Livestream playback on Hololens2 - unity3d

I have encountered the following problem
My task is as follows, I need to play streaming video (raw h264 video over UDP protocol) on a 3d object. At the moment I'm using FFmpegInteropX to set a MediaSource to a Windows object.Media.Playback.MediaPlayer.
Media Player works in frame server mode, then I subscribe to the videoFrameAvailable event and transmit the resulting frame to Unity
The problem is that the performance on Hololens2 (UWP) is quite low, I can't get enough smoothness and low latency if I use texture sizes greater than 720x720. At the same time, if I run the application on a PC, I can play everything up to 4096x4096 smoothly and without delay.
Perhaps someone has some ideas on how to improve performance on Hololens2?
private SoftwareBitmap frameServerDest = new SoftwareBitmap(BitmapPixelFormat.Rgba8, 1024,1024,BitmapAlphaMode.Premultiplied );
private UnityEngine.Texture2D tex = new UnityEngine.Texture2D(frameServerDest.PixelWidth, frameServerDest.PixelHeight, UnityEngine.TextureFormat.RGBA32, false);
private async void InitializeMediaPlayer(){
FFmpegInteropLogging.SetDefaultLogProvider();
FFmpegInteropConfig configuration = new FFmpegInteropConfig()
{
MaxVideoThreads = 8,
SkipErrors = uint.MaxValue,
DefaultBufferTime = TimeSpan.Zero,
FastSeek = true,
VideoDecoderMode = VideoDecoderMode.ForceFFmpegSoftwareDecoder,
};
configuration.FFmpegOptions.Add("tune", "zerolatency");
configuration.FFmpegOptions.Add("flags", "low_delay");
configuration.FFmpegOptions.Add("fflags", "discardcorrupt+shortest+sortdts+ignidx+nobuffer");
decoder = await FFmpegInteropMSS.CreateFromUriAsync("udp://127.0.0.1:9005",configuration)
var mediaStreamSource = decoder.GetMediaStreamSource();
mediaStreamSource.BufferTime = TimeSpan.FromSeconds(0);
Debug.WriteLine($"{decoder.CurrentVideoStream.CodecName} {decoder.CurrentVideoStream.DecoderEngine} {decoder.CurrentVideoStream.HardwareDecoderStatus} {decoder.CurrentVideoStream.PixelWidth} x {decoder.CurrentVideoStream.PixelHeight}");
var FrameServer = new Windows.Media.Playback.MediaPlayer() { IsVideoFrameServerEnabled = true };
FrameServer.Source = MediaSource.CreateFromMediaStreamSource(mediaStreamSource);
FrameServer.RealTimePlayback = true;
FrameServer.VideoFrameAvailable += MediaPlayer_VideoFrameAvailable;
FrameServer.Play();
}
//FrameAvailable:
private void MediaPlayer_VideoFrameAvailable(Windows.Media.Playback.MediaPlayer sender, object args)
{
CanvasDevice canvasDevice = CanvasDevice.GetSharedDevice();
using (CanvasBitmap canvasBitmap = CanvasBitmap.CreateFromSoftwareBitmap(canvasDevice, frameServerDest))
{
sender.CopyFrameToVideoSurface(canvasBitmap);
byte[] bytes = canvasBitmap.GetPixelBytes();
if (AppCallbacks.Instance.IsInitialized())
{
AppCallbacks.Instance.InvokeOnAppThread(() =>
{
tex.LoadRawTextureData(bytes);
tex.Apply();
Display.GetComponent<UnityEngine.UI.RawImage>().texture = tex;
}, false);
}
GC.Collect();
}
}
My FFmpeg output setting
ffmpeg -r 60 -f gdigrab -i desktop -f h264 -framerate 60 -vcodec libx264 -preset ultrafast -tune zerolatency -threads 8 -thread_type slice udp://127.0.0.1:9005
UPDATE:
Hello, I did some work.
What I've done:
I have established a direct connection via usb-s - etnernet
I begin to look towards using directx surface
I found the following way to get d3d11 device using by Unity
For this I had to use the library SharpDX, and similar thread https://forum.unity.com/threads/d3d11-texture2d-blitting-framerate.562552
But there are problems that I can't solve yet:
1 FFmpeg works only in the VideoDecoderMode = VideoDecoderMode.Automatic or VideoDecoderMode.ForceFFmpegSoftwareDecoder mode;
2 In the event handler (videoframe_available), there is still a very large load on the Garbage Collector, and apparently this causes performance problems. Moreover, the performance suffers only on Hololens.
In other VideoDecoderMode`s, the stream parameters are determined, but the videoframe_available event never fires. Latency is approx to zero, but perfomance still not very good
Perhaps there are ideas how to solve the problem with GarbageColletor?
private SoftwareBitmap frameServerDist = new SoftwareBitmap(BitmapPixelFormat.Rgba8, 780, 780,
BitmapAlphaMode.Premultiplied);
private FFmpegInteropMSS decoder;
private UnityEngine.GameObject Display;
private UnityEngine.Texture2D targetTexture;
private UnityEngine.GameObject MainCamera;
private SharpDX.Direct3D11.Device dstDevice;
private SharpDX.Direct3D11.DeviceContext dstContenxt;
private SharpDX.Direct3D11.Texture2D m_DstTexture;
private SharpDX.Direct3D11.Device srcDevice;
private SharpDX.Direct3D11.DeviceContext srcContext;
private static DataRectangle _rect;
private SharpDX.Direct3D11.Texture2DDescription Texture2DDescription = new SharpDX.Direct3D11.Texture2DDescription()
{
ArraySize = 1,
BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource,
Usage = SharpDX.Direct3D11.ResourceUsage.Immutable, //GPU Only
CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None,
Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
MipLevels = 1,
OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None,
SampleDescription = new SharpDX.DXGI.SampleDescription()
{
Count = 1,
Quality = 0
}
};
//This event occurs when UnityEngine Initialized
private void AppCallbacks_Initialized()
{
srcDevice = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Hardware);
srcContext = srcDevice.ImmediateContext;
UnityEngine.WSA.Application.InvokeOnAppThread(() =>
{
Display = UnityEngine.GameObject.Find("Display");
targetTexture = null;
//Create texture for get Device and Device context
UnityEngine.Texture2D deviceTexture = new UnityEngine.Texture2D(frameServerDist.PixelWidth, frameServerDist.PixelHeight, UnityEngine.TextureFormat.RGBA32, false);
IntPtr txPtr = deviceTexture.GetNativeTexturePtr();
SharpDX.Direct3D11.Texture2D dstTextureX = new SharpDX.Direct3D11.Texture2D(txPtr);
dstDevice = dstTextureX.Device;
dstContenxt = dstDevice.ImmediateContext;
//Create sharedResource
SharpDX.Direct3D11.Texture2DDescription sharedTextureDesc = dstTextureX.Description;
sharedTextureDesc.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.Shared;
m_DstTexture = new SharpDX.Direct3D11.Texture2D(dstDevice, sharedTextureDesc);
SharpDX.Direct3D11.ShaderResourceViewDescription rvdesc = new SharpDX.Direct3D11.ShaderResourceViewDescription
{
Format = sharedTextureDesc.Format,
Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2D
};
rvdesc.Texture2D.MostDetailedMip = 0; rvdesc.Texture2D.MipLevels = 1;
SharpDX.Direct3D11.ShaderResourceView rvptr = new SharpDX.Direct3D11.ShaderResourceView(
dstDevice,
m_DstTexture, rvdesc);
targetTexture = UnityEngine.Texture2D.CreateExternalTexture(sharedTextureDesc.Width, sharedTextureDesc.Height, UnityEngine.TextureFormat.BGRA32, false, false, rvptr.NativePointer);
MainCamera = UnityEngine.GameObject.Find("Main Camera");
Display.GetComponent<UnityEngine.UI.RawImage>().texture = targetTexture;
InitializeMediaPlayer();
}, false);
private void MediaPlayer_VideoFrameAvailable(Windows.Media.Playback.MediaPlayer sender, object args)
{
canvasBitmap = CanvasBitmap.CreateFromSoftwareBitmap(canvasDevice, frameServerDist);
sender.CopyFrameToVideoSurface(canvasBitmap);
var sharedResourceDst = m_DstTexture.QueryInterface<SharpDX.DXGI.Resource>();
var sharedTexDst = srcDevice.OpenSharedResource<SharpDX.Direct3D11.Texture2D>(sharedResourceDst.SharedHandle);
using (var _stream = DataStream.Create(canvasBitmap.GetPixelBytes(), true, false))
{
_rect.DataPointer = _stream.DataPointer;
_rect.Pitch = Texture2DDescription.Width * 4;
var srcTexture = new SharpDX.Direct3D11.Texture2D(srcDevice, Texture2DDescription, _rect);
srcContext.CopyResource(srcTexture, sharedTexDst);
srcContext.Flush();
sharedResourceDst.Dispose();
sharedTexDst.Dispose();
srcTexture.Dispose();
}
}

The problem was copying from CPU to GPU, the SharpDX library allowed copying frames directly to Idirect3dsurface. I'm attaching the code, maybe it will be useful.
Direct3D11 helpers is available in the microsoft documentation
https://learn.microsoft.com/en-us/windows/uwp/audio-video-camera/screen-capture-video#helper-wrapper-classes
private UnityEngine.GameObject MainCamera;
private UnityEngine.Texture2D targetTexture;
private IDirect3DSurface surface;
private SharpDX.Direct3D11.Device dstDevice;
private void AppCallbacks_Initialized()
{
SharpDX.Direct3D11.Device srcDevice = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Hardware);
UnityEngine.WSA.Application.InvokeOnAppThread(() =>
{
Display = UnityEngine.GameObject.Find("Display");
targetTexture = null;
//Create texture for get Device and Device context from Unity
UnityEngine.Texture2D deviceTexture = new UnityEngine.Texture2D(2048, 2048, UnityEngine.TextureFormat.RGBA32, false);
IntPtr txPtr = deviceTexture.GetNativeTexturePtr();
SharpDX.Direct3D11.Texture2D dstTexture = new SharpDX.Direct3D11.Texture2D(txPtr);
dstDevice = dstTexture.Device;
//Create sharedResource
SharpDX.Direct3D11.Texture2DDescription sharedTextureDesc = dstTexture.Description;
sharedTextureDesc.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.Shared;
SharpDX.Direct3D11.Texture2D m_DstTexture = new SharpDX.Direct3D11.Texture2D(dstDevice, sharedTextureDesc);
SharpDX.Direct3D11.ShaderResourceViewDescription rvdesc = new SharpDX.Direct3D11.ShaderResourceViewDescription
{
Format = sharedTextureDesc.Format,
Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2D
};
rvdesc.Texture2D.MostDetailedMip = 0;
rvdesc.Texture2D.MipLevels = 1;
SharpDX.Direct3D11.ShaderResourceView rvptr = new SharpDX.Direct3D11.ShaderResourceView(
dstDevice,
m_DstTexture, rvdesc);
targetTexture = UnityEngine.Texture2D.CreateExternalTexture(sharedTextureDesc.Width, sharedTextureDesc.Height, UnityEngine.TextureFormat.BGRA32, false, false, rvptr.NativePointer);
MainCamera = UnityEngine.GameObject.Find("Main Camera");
Display.GetComponent<UnityEngine.UI.RawImage>().texture = targetTexture;
var sharedResourceDst = m_DstTexture.QueryInterface<SharpDX.DXGI.Resource>();
var sharedTexDst = srcDevice.OpenSharedResource<SharpDX.Direct3D11.Texture2D>(sharedResourceDst.SharedHandle);
surface = Direct3D11Helper.CreateDirect3DSurfaceFromSharpDXTexture(sharedTexDst);
sharedResourceDst.Dispose();
sharedTexDst.Dispose();
dstTexture.Dispose();
m_DstTexture.Dispose();
}, false);
InitializeMediaPlayer();
}
private void MediaPlayer_VideoFrameAvailable(Windows.Media.Playback.MediaPlayer sender, object args)
{
Debug.WriteLine("frameAvail");
sender.CopyFrameToVideoSurface(surface);
}

Related

My Unity (ZXing/XR) QRCode reader isn't presenting the decoded info. What am I doing wrong?

This is the code I am using for QR Scan. It uses XR for Camera input and ZXing to decode the QR Code. I have been at this for 3 days and still have no clue what I am doing wrong. I do not know whether it is that code isn't able to decode the QR, or it can but isn't able to print it out on Output text. Any help would be greatly appreciated. Thank you! :)
These are the libraries I am using :
using System.Collections;
using UnityEngine;
using UnityEngine.XR.ARSubsystems;
using UnityEngine.XR.ARFoundation;
using ZXing;
using TMPro;
This is the code :
IBarcodeReader _reader;
ARCameraManager _arCam;
AudioSource _audioSrc;
ARRaycastManager _arRay;
private Texture2D _arTexture;
private TextMeshPro _outputText;
private void Awake()
{
_arCam = FindObjectOfType<ARCameraManager>();
_audioSrc = FindObjectOfType<AudioSource>();
_arRay = FindObjectOfType<ARRaycastManager>();
_reader = new BarcodeReader();
_arCam.frameReceived += OnCameraFrameReceived; //When camera receives frame.
}
//Fires off when Frame is received.
void OnCameraFrameReceived(ARCameraFrameEventArgs eventArgs)
{
if ((Time.frameCount % 15) == 0)
{
XRCpuImage _image;
if(_arCam.TryAcquireLatestCpuImage(out _image))
{
StartCoroutine(ProcessQRCode(_image));
_image.Dispose();
}
}
}
//Processes the QR Code in the _image.
IEnumerator ProcessQRCode(XRCpuImage _image)
{
var request = _image.ConvertAsync(new XRCpuImage.ConversionParams { inputRect = new RectInt(0, 0, _image.width, _image.height),
outputDimensions = new Vector2Int(_image.width / 2, _image.height / 2),
outputFormat = TextureFormat.RGB24
});
while (!request.status.IsDone())
yield return null;
if (request.status != XRCpuImage.AsyncConversionStatus.Ready)
{
Debug.LogErrorFormat("Request failed with status {0}", request.status);
request.Dispose();
yield break;
}
var rawData = request.GetData<byte>();
if(_arTexture == null)
{
_arTexture = new Texture2D(
request.conversionParams.outputDimensions.x,
request.conversionParams.outputDimensions.y,
request.conversionParams.outputFormat,
false
);
}
_arTexture.LoadRawTextureData(rawData);
_arTexture.Apply();
byte[] barcodeBitmap = _arTexture.GetRawTextureData();
LuminanceSource source = new RGBLuminanceSource(barcodeBitmap, _arTexture.width, _arTexture.height);
var result = _reader.Decode(source);
if(result != null)
{
var QRContents = result.Text;
_outputText.text = QRContents;
_audioSrc.Play();
}
}

Scaleup and Scale Down of imported DWG file in the Eyeshot Model

I imported the DWG file into the eyeshot model. For reading file I used ReadAutodesk class. I want to apply Scaleup and Scaledown on the imported DWG file. I don’t understand how to do that. Can you please help me.
This is code I used.
private void RibbonRadioButton_Click(object sender, RoutedEventArgs e) {
OpenFileDialog openFileDialog1 = new OpenFileDialog() {
Filter = "DWG File|*.dwg|pdf file|*.pdf",
Multiselect = false,
AddExtension = true,
CheckFileExists = true,
CheckPathExists = true
};
string fileName = null;
if (fileName != null || openFileDialog1.ShowDialog().Value) {
System.Windows.Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate { }));
var rfa = new ReadAutodesk(fileName != null ? fileName : openFileDialog1.FileName);
ScaleTransform aa = new ScaleTransform(2,2.5,1,1);
rfa.DoWork();
rfa.AddToScene(model1);
Entity[] toAdd = model1.Entities.Explode();
model1.RenderTransform = aa;
model1.ZoomFit();
model1.Entities.AddRange(toAdd, NOT_MODIFIED_COLOR);
model1.SetView(viewType.Top);
// Fits the model in the viewport
model1.Invalidate();
}
}

Open OSM pbf results in Protobuf exception

Using OSMSharp I am having trouble to open a stream for a file (which I can provide on demand)
The error occurs in PBFReader (line 104)
using (var tmp = new LimitedStream(_stream, length))
{
header = _runtimeTypeModel.Deserialize(tmp, null, _blockHeaderType) as BlobHeader;
}
and states: "ProtoBuf.ProtoException: 'Invalid field in source data: 0'" which might mean different things as I have read in this SO question.
The file opens and is visualized with QGis so is not corrupt in my opinion.
Can it be that the contracts do not match? Is OsmSharp/core updated to the latest .proto files for OSM from here (although not sure if this is the real original source for the definition files).
And what might make more sense, can it be that the file I attached is generated for v2 of OSM PBF specification?
In the code at the line of the exception I see the following comment which makes me wonder:
// TODO: remove some of the v1 specific code.
// TODO: this means also to use the built-in capped streams.
// code borrowed from: http://stackoverflow.com/questions/4663298/protobuf-net-deserialize-open-street-maps
// I'm just being lazy and re-using something "close enough" here
// note that v2 has a big-endian option, but Fixed32 assumes little-endian - we
// actually need the other way around (network byte order):
// length = IntLittleEndianToBigEndian((uint)length);
BlobHeader header;
// again, v2 has capped-streams built in, but I'm deliberately
// limiting myself to v1 features
So this makes me wonder if OSM Sharp is (still) up-to-date.
My sandbox code looks like this:
using OsmSharp.Streams;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using OsmSharp.Tags;
namespace OsmSharp
{
class Program
{
private const string Path = #"C:\Users\Bernoulli IT\Documents\Applications\Argaleo\Test\";
private const string FileNameAntarctica = "antarctica-latest.osm";
private const string FileNameOSPbf = "OSPbf";
private const Boolean useRegisterSource = false;
private static KeyValuePair<string, string> KeyValuePair = new KeyValuePair<string, string>("joep", "monita");
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
//string fileName = $#"{Path}\{FileNameAntarctica}.pbf";
string fileName = $#"{Path}\{FileNameOSPbf}.pbf";
string newFileName = $"{fileName.Replace(".pbf", string.Empty)}-{Guid.NewGuid().ToString().Substring(0, 4)}.pbf";
Console.WriteLine("*** Complete");
string fileNameOutput = CompleteFlow(fileName, newFileName);
Console.WriteLine("");
Console.WriteLine("*** Display");
DisplayFlow(fileNameOutput);
Console.ReadLine();
}
private static string CompleteFlow(string fileName, string newFileName)
{
// 1. Open file and convert to bytes
byte[] fileBytes = FileToBytes(fileName);
// 2. Bytes to OSM stream source (pbf)
PBFOsmStreamSource osmStreamSource;
osmStreamSource = BytesToOsmStreamSource(fileBytes);
osmStreamSource.MoveNext();
if (osmStreamSource.Current() == null)
{
osmStreamSource = FileToOsmStreamSource(fileName);
osmStreamSource.MoveNext();
if (osmStreamSource.Current() == null)
{
throw new Exception("No current in stream.");
}
}
// 3. Add custom tag
AddTag(osmStreamSource);
// 4. OSM stream source to bytes
//byte[] osmStreamSourceBytes = OsmStreamSourceToBytes(osmStreamSource);
// 5. Bytes to file
//string fileNameOutput = BytesToFile(osmStreamSourceBytes, newFileName);
OsmStreamSourceToFile(osmStreamSource, newFileName);
Console.WriteLine(newFileName);
return newFileName;
}
private static void DisplayFlow(string fileName)
{
// 1. Open file and convert to bytes
byte[] fileBytes = FileToBytes(fileName);
// 2. Bytes to OSM stream source (pbf)
BytesToOsmStreamSource(fileBytes);
}
private static byte[] FileToBytes(string fileName)
{
Console.WriteLine(fileName);
return File.ReadAllBytes(fileName);
}
private static PBFOsmStreamSource BytesToOsmStreamSource(byte[] bytes)
{
MemoryStream memoryStream = new MemoryStream(bytes);
memoryStream.Position = 0;
PBFOsmStreamSource osmStreamSource = new PBFOsmStreamSource(memoryStream);
foreach (OsmGeo element in osmStreamSource.Where(osmGeo => osmGeo.Tags.Any(tag => tag.Key.StartsWith(KeyValuePair.Key))))
{
foreach (Tag elementTag in element.Tags.Where(tag => tag.Key.StartsWith(KeyValuePair.Key)))
{
Console.WriteLine("!!!!!!!!!!!!!! Tag found while reading !!!!!!!!!!!!!!!!!!".ToUpper());
}
}
return osmStreamSource;
}
private static PBFOsmStreamSource FileToOsmStreamSource(string fileName)
{
using (FileStream fileStream = new FileInfo(fileName).OpenRead())
{
PBFOsmStreamSource osmStreamSource = new PBFOsmStreamSource(fileStream);
return osmStreamSource;
}
}
private static void AddTag(PBFOsmStreamSource osmStreamSource)
{
osmStreamSource.Reset();
OsmGeo osmGeo = null;
while (osmGeo == null)
{
osmStreamSource.MoveNext();
osmGeo = osmStreamSource.Current();
if(osmGeo?.Tags == null)
{
osmGeo = null;
}
}
osmGeo.Tags.Add("joep", "monita");
Console.WriteLine($"{osmGeo.Tags.FirstOrDefault(tag => tag.Key.StartsWith(KeyValuePair.Key)).Key} - {osmGeo.Tags.FirstOrDefault(tag => tag.Key.StartsWith(KeyValuePair.Key)).Value}");
}
private static byte[] OsmStreamSourceToBytes(PBFOsmStreamSource osmStreamSource)
{
MemoryStream memoryStream = new MemoryStream();
PBFOsmStreamTarget target = new PBFOsmStreamTarget(memoryStream, true);
osmStreamSource.Reset();
target.Initialize();
UpdateTarget(osmStreamSource, target);
target.Flush();
target.Close();
return memoryStream.ToArray();
}
private static string BytesToFile(byte[] bytes, string fileName)
{
using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
fs.Write(bytes, 0, bytes.Length);
}
return fileName;
}
private static void OsmStreamSourceToFile(PBFOsmStreamSource osmStreamSource, string fileName)
{
using (FileStream fileStream = new FileInfo(fileName).OpenWrite())
{
PBFOsmStreamTarget target = new PBFOsmStreamTarget(fileStream, true);
osmStreamSource.Reset();
target.Initialize();
UpdateTarget(osmStreamSource, target);
target.Flush();
target.Close();
}
}
private static void UpdateTarget(OsmStreamSource osmStreamSource, OsmStreamTarget osmStreamTarget)
{
if (useRegisterSource)
{
osmStreamTarget.RegisterSource(osmStreamSource, osmGeo => true);
osmStreamTarget.Pull();
}
else
{
bool isFirst = true;
foreach (OsmGeo osmGeo in osmStreamSource)
{
Tag? tag = osmGeo.Tags?.FirstOrDefault(t => t.Key == KeyValuePair.Key);
switch (osmGeo.Type)
{
case OsmGeoType.Node:
if (isFirst)
{
for (int indexer = 0; indexer < 1; indexer++)
{
(osmGeo as Node).Tags.Add(new Tag(KeyValuePair.Key + Guid.NewGuid(), KeyValuePair.Value));
}
isFirst = false;
}
osmStreamTarget.AddNode(osmGeo as Node);
break;
case OsmGeoType.Way:
osmStreamTarget.AddWay(osmGeo as Way);
break;
case OsmGeoType.Relation:
osmStreamTarget.AddRelation(osmGeo as Relation);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}
}
}
Already I posted this question on the GITHube page of OSMSharp as is linked here. Any help would be very appreciated.

unity crashes when script runs

in my simple usp server finder script when i select client it makes unity crash and i can't find why;
import System.Net.Sockets;
private var udp_server:UdpClient;
private var udp_client:UdpClient;
private var udp_port:int = 18000;
private var udp_broadcast_ip:IPAddress = IPAddress.Parse ("224.0.0.224");
private var udp_received_message:String;
private var udp_endpoint:IPEndPoint;
private var selected:boolean = false;
private var clientStarted:boolean = false;
function StartServer(){
udp_server = new UdpClient(udp_port, AddressFamily.InterNetwork);
udp_server.JoinMulticastGroup(udp_broadcast_ip);
udp_endpoint = new IPEndPoint(udp_broadcast_ip, udp_port);
InvokeRepeating("StartBroadcastUDP", 0.0,0.3);
}
function StartClient(){
udp_client = new UdpClient();
udp_endpoint = new IPEndPoint(IPAddress.Any, udp_port);
udp_client.Client.Bind(udp_endpoint);
udp_client.JoinMulticastGroup(udp_broadcast_ip);
/*
while(true){
yield;
var udp_received_message_byte:byte[] = udp_client.Receive(udp_endpoint);
udp_received_message = Encoding.Unicode.GetString(udp_received_message_byte);
print("Received Message: " + udp_received_message);
}*/
clientStarted = true;
}
function StartBroadcastUDP(){
var udp_broadcast_message = Encoding.Unicode.GetBytes("GAME SERVER");
if(udp_broadcast_message != ""){
udp_server.Send(udp_broadcast_message, udp_broadcast_message.Length);
}
}
function OnGUI(){
if(!selected){
if(GUI.Button(Rect(0, 0, 100, 100), "Server")){
StartServer();
selected = true;
}else if(GUI.Button(Rect(100, 0, 100, 100), "Client")){
StartClient();
selected = true;
}
}
}
function Update(){
/*
if(clientStarted){
var udp_received_message_byte:byte[] = udp_client.Receive(udp_endpoint);
udp_received_message = Encoding.Unicode.GetString(udp_received_message_byte);
print("Received Message: " + udp_received_message);
}*/
}
in both of the commented parts i tried doing this, in the first i used while to keep it in the same function but it crashed so i mmoved it into the update function but it still crashes. help?
The while(true)in StartClient() will indeed make the editor / app to be frozen, because StartClient() is not called as a Coroutine, so yield does not return to the Unity engine, and your program is stuck forever in the while.
There is another thing thus. It looks like udp-client.Receive is a synchronous call, meaning it's blocking the code waiting for a packet. The game will indeed freeze unless you have like 60 packets per seconds.

how to execute the .cs file generated using codeDom

Here is my source code.....
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;
using System.IO;
using Microsoft.CSharp;
using Microsoft.VisualBasic;
namespace CodeDOM
{
class Program
{
private string m_strFileName;
private string m_Suffix = ".cs";
public Program(string FileName)
{
m_strFileName = FileName;
}
public void CreateCodeDom()
{
Stream codeFile = File.Open("c:\\" + m_strFileName + m_Suffix, FileMode.Create);
StreamWriter sw = new StreamWriter(codeFile);
CSharpCodeProvider cscp = new CSharpCodeProvider();
ICodeGenerator codeGenerator = cscp.CreateGenerator(sw);
CodeGeneratorOptions cgo = new CodeGeneratorOptions();
CodeSnippetCompileUnit cscu = new CodeSnippetCompileUnit("imports System");
codeGenerator.GenerateCodeFromCompileUnit(cscu, sw, cgo);
CodeNamespace cnsCodeDom = new CodeNamespace("SampleNamespace");
CodeTypeDeclaration clsDecl = new CodeTypeDeclaration();
clsDecl.Name = "Sample";
clsDecl.IsClass = true;
clsDecl.TypeAttributes = TypeAttributes.Public;
cnsCodeDom.Types.Add(clsDecl);
CodeConstructor clsConstructor = new CodeConstructor();
clsConstructor.Attributes = MemberAttributes.Public;
clsDecl.Members.Add(clsConstructor);
CodeMemberField clsMember = new CodeMemberField();
clsMember.Name = "myname";
clsMember.Attributes = MemberAttributes.Private;
clsMember.Type = new CodeTypeReference("System.String");
clsDecl.Members.Add(clsMember);
CodeMemberProperty property = new CodeMemberProperty();
property.Name = "MyName";
property.Type = new CodeTypeReference("System.String");
property.Attributes = MemberAttributes.Public;
property.HasGet = true;
property.GetStatements.Add(new CodeSnippetExpression("return this.myname"));
property.HasSet = true;
property.SetStatements.Add(new CodeSnippetExpression("this.myname=value"));
//property.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "this.myname")));
//property.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "this.myname"), new CodePropertySetValueReferenceExpression()));
clsDecl.Members.Add(property);
CodeMemberMethod mtd = new CodeMemberMethod();
mtd.Name = "Print";
mtd.ReturnType = null;
mtd.Attributes = MemberAttributes.Public;
mtd.Statements.Add(new CodeSnippetStatement("Console.WriteLine(myname)"));
clsDecl.Members.Add(mtd);
codeGenerator.GenerateCodeFromNamespace(cnsCodeDom, sw, cgo);
sw.Close();
codeFile.Close();
}
static void Main(string[] args)
{
Program m_obj = new Program("Sample");
m_obj.CreateCodeDom();
Console.ReadLine();
}
}
}
from this i got sample.cs file.now i want to execute that sample.cs file.wil u plz suggest me how to do it?
If it is an application, in a single source file, you can simply do:
csc sample.cs && sample.exe