UDP sockect about string in UWP - string

I find a strange problem when I write code in UWP.
I use UDP sockect to send a coordinates to hololens.
The coordinate is like "1.0_1.0_1.0", it was send as string and will be cut according to "_",then the coordinate will be used to control the moving of a sphere.
First of all, it run all right in the unity editor.
But in the hololens, for example, I only receive "1.0_1.0_1.0", but cannot change it to vector3:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HoloToolkit.Unity;
#if !UNITY_EDITOR
using System;
using Windows.Foundation;
#endif
public class pre : MonoBehaviour
{
public TextMesh tm = null;
public TextMesh tmmm = null;
public GameObject sphere;
string test;
public void ResponseToUDPPacket(string incomingIP, string incomingPort, string data)
{
string[] centre = data.Split('_');
float[] num= new float[3];
if (tm != null)
tm.text = data;
num[0] = float.Parse(centre[0]);
num[1] = float.Parse(centre[1]);
num[2] = float.Parse(centre[2]);
Debug.Log(num[1]);
if (tmmm != null)
tmmm.text = num[1].ToString();
sphere.transform.position = new Vector3(num[0], num[1], num[2]);
//var headPosition = Camera.main.transform.position;
//headPosition.z = headPosition.z+10;
//sphere1.transform.position = headPosition;
}
}
I use two testmesh to show the result, "data"is the string I have received, the first "tm" doesn't have problem.for example, it will show"1.0_1.0_1.0".
But the "tmm" which is get according to num[1] is never work.
I have thought it is the problem of UWP.
BUT!!!!!!!!!!!!!!!!!!!!!!!
I send the UDP string by a c++ program, but when I use a software(UDPsender or something like it) to send string manually, the problem in hololens disappeared!
But I don't think there is a problem in my C++ program, because at least it run well in unity editor.
Is there anyone has idea about the problem?

Maybe your emulator and your device have different cultures and one understands 1.0 while the other expects 1,0 in the float.Parse.
You can pass your culture (or InvariantCulture) to float.Parse if that is the case.
Does the Debug.Log(num[1]) print the correct number in all cases? If not, this could confirm the above theory.

Related

How to use the SCNNode look Method in Xamarin iOS?

Im Programming a Xamarin iOS AR app.
Im trying to display an arrow in my ARSCNView that points to a specific node.
The method I use to add the arrow:
private void AddDirectionArrow()
{
var arrow = SCNScene.FromFile("arrow.dae");
if (arrow is null)
{
throw new FileNotFoundException("Pfeil 3D Modell nicht gefunden");
}
this.ArrowNode = arrow.RootNode;
this.ArrowNode.Position = new SCNVector3(0, 3, -8f);
this.sceneView.PointOfView?.AddChildNode(this.ArrowNode);
this.ArrowNode.Rotation = new SCNVector4(0, 0, 1, 0);
}
This works fine.The arrow stays in front of the users device.
My class has 2 nodes as property:
private SCNNode ArrowNode;
private SCNNode NodeToPointTo;
The NodeToPointTo is set as followed:
this.NodeToPointTo = this.sceneView.GetNode(<SomeARAnchor>);
Works fine as well.
In the ARDelegate.cs method WillRenderScene I call this method to update the arrow:
public override void OnUpdateScene(double timeInSeconds)
{
base.OnUpdateScene(timeInSeconds);
if (this.NodeToPointTo is null)
{
return;
}
this.ArrowNode.Look(this.NodeToPointTo.WorldPosition, this.sceneView.PointOfView.WorldUp, this.ArrowNode.WorldFront);
}
This is what I cant figure out.
Im calling the Look method that should point my arrow node to the node I want it to point to.
How do I call this method correctly so my arrow points to the node?
Here is the Apple Dokumentation since I couldn't find any for Xamarin.
And the desired outcome
Don't hesitate to ask if anything is unclear.
-Simon
According to this case which is about one SCNNode look at another SCNNode, you can try to use the SCNLookAtConstraint which is a constraint that orients a node to always point toward a specified other node.
You can try the following code:
private SCNNode ArrowNode;
private SCNNode NodeToPointTo;
....
SCNLookAtConstraint sCNLookAtConstraint = SCNLookAtConstraint.Create(NodeToPointTo);
ArrowNode.Constraints = new SCNLookAtConstraint[] { sCNLookAtConstraint };

Environment.userName is Unknown in Hololens2

I have an hololens2 application that I built in Unity. The Environment.Username works in the Unity editor correctly, but when I deployed to the HL2, the Environment.UserName is Unknown. Under the player settings I've applied Enterprise Application, WebCam,Microphone, HumanInterfaceDevice, UserAccountInformation, Bluetooth, SystemManagement, UserDataTasks and Contacts.
It builds just fine and deploys to HL2 without problems, but the UserName is Unknown. When I go to the HL2 start menu, it displays my name correctly.
Please Help,
Martin F.
Please try the following code, it should display the account name signed into the HoloLens2:
using System;
using System.Collections.Generic;
using System.Text;
using TMPro;
using UnityEngine;
#if WINDOWS_UWP
using Windows.System;
#endif
public class UserName : MonoBehaviour
{
[SerializeField]
private TMP_Text userNameText = null;
// Start is called before the first frame update
async void Start()
{
#if WINDOWS_UWP
IReadOnlyList<User> users = await User.FindAllAsync();
StringBuilder sb = new StringBuilder();
foreach (User u in users)
{
string name = (string)await u.GetPropertyAsync(KnownUserProperties.AccountName);
if (string.IsNullOrWhiteSpace(name))
{
name = "unknown account name";
}
sb.AppendLine(name);
}
userNameText.text = sb.ToString();
#endif
}
}

How to add 2 sounds and play them via script?

I am made a door script and it works fine but now i want to add different sounds when the door opens and when it closes. I added an Audio Source at the door and added the doorOpen sound. How can i add a doorClose sound too and make it play via the script?
Audio Source
if (open) {
GetComponent<AudioSource>().Play ();
} else {
GetComponent<AudioSource>().Play ();
}
Check Audio & Sound Tutorial. Here is sample code:
using UnityEngine;
using System.Collections;
namespace Completed
{
public class SoundManager : MonoBehaviour
{
public AudioSource efxSource; //Drag a reference to the audio source which will play the sound effects.
public AudioSource musicSource; //Drag a reference to the audio source which will play the music.
public static SoundManager instance = null; //Allows other scripts to call functions from SoundManager.
public float lowPitchRange = .95f; //The lowest a sound effect will be randomly pitched.
public float highPitchRange = 1.05f; //The highest a sound effect will be randomly pitched.
void Awake ()
{
//Check if there is already an instance of SoundManager
if (instance == null)
//if not, set it to this.
instance = this;
//If instance already exists:
else if (instance != this)
//Destroy this, this enforces our singleton pattern so there can only be one instance of SoundManager.
Destroy (gameObject);
//Set SoundManager to DontDestroyOnLoad so that it won't be destroyed when reloading our scene.
DontDestroyOnLoad (gameObject);
}
//Used to play single sound clips.
public void PlaySingle(AudioClip clip)
{
//Set the clip of our efxSource audio source to the clip passed in as a parameter.
efxSource.clip = clip;
//Play the clip.
efxSource.Play ();
}
//RandomizeSfx chooses randomly between various audio clips and slightly changes their pitch.
public void RandomizeSfx (params AudioClip[] clips)
{
//Generate a random number between 0 and the length of our array of clips passed in.
int randomIndex = Random.Range(0, clips.Length);
Keep reference to both the Audio files.
Then,
if (open) {
GetComponent<AudioSource> ().clip = _OpenClip;
GetComponent<AudioSource> ().Play ();
} else {
GetComponent<AudioSource> ().clip = _CloseClip;
GetComponent<AudioSource> ().Play ();
}

Reusable generic LightSwitch screen with WCF RIA Services

I'm new to WCF RIA Services, and have been working with LightSwitch for 4 or so months now.
I created a generic screen to be used for editing lookup tables all over my LightSwitch application, mostly to learn how to create a generic screen that can be used with different entity sets on a dynamic basis.
The screen is pretty simple:
Opened with arguments similar to this:
Application.ShowLookupTypesList("StatusTypes", "StatusTypeId"); which correspond to the entity set for the lookup table in the database.
Here's my WCF RIA service code:
using System.Data.Objects.DataClasses;
using System.Diagnostics;
using System.Reflection;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Server;
namespace WCF_RIA_Project
{
public class LookupType
{
[Key]
public int TypeId { get; set; }
public string Name { get; set; }
}
public static class EntityInfo
{
public static Type Type;
public static PropertyInfo Key;
public static PropertyInfo Set;
}
public class WCF_RIA_Service : LinqToEntitiesDomainService<WCSEntities>
{
public IQueryable<LookupType> GetLookupTypesByEntitySet(string EntitySetName, string KeyName)
{
EntityInfo.Set = ObjectContext.GetType().GetProperty(EntitySetName);
EntityInfo.Type = EntityInfo.Set.PropertyType.GetGenericArguments().First();
EntityInfo.Key = EntityInfo.Type.GetProperty(KeyName);
return GetTypes();
}
[Query(IsDefault = true)]
public IQueryable<LookupType> GetTypes()
{
var set = (IEnumerable<EntityObject>)EntityInfo.Set.GetValue(ObjectContext, null);
var types = from e in set
select new LookupType
{
TypeId = (int)EntityInfo.Key.GetValue(e, null),
Name = (string)EntityInfo.Type.GetProperty("Name").GetValue(e, null)
};
return types.AsQueryable();
}
public void InsertLookupType(LookupType lookupType)
{
dynamic e = Activator.CreateInstance(EntityInfo.Type);
EntityInfo.Key.SetValue(e, lookupType.TypeId, null);
e.Name = lookupType.Name;
dynamic set = EntityInfo.Set.GetValue(ObjectContext, null);
set.AddObject(e);
}
public void UpdateLookupType(LookupType currentLookupType)
{
var set = (IEnumerable<EntityObject>)EntityInfo.Set.GetValue(ObjectContext, null);
dynamic modified = set.FirstOrDefault(t => (int)EntityInfo.Key.GetValue(t, null) == currentLookupType.TypeId);
modified.Name = currentLookupType.Name;
}
public void DeleteLookupType(LookupType lookupType)
{
var set = (IEnumerable<EntityObject>)EntityInfo.Set.GetValue(ObjectContext, null);
var e = set.FirstOrDefault(t => (int)EntityInfo.Key.GetValue(t, null) == lookupType.TypeId);
Debug.Assert(e.EntityState != EntityState.Detached, "Entity was in a detached state.");
ObjectContext.ObjectStateManager.ChangeObjectState(e, EntityState.Deleted);
}
}
}
When I add an item to the list from the running screen, save it, then edit it and resave, I receive data conflict "Another user has deleted this record."
I can workaround this by reloading the query after save, but it's awkward.
If I remove, save, then readd and save an item with the same name I get unable to save data, "The context is already tracking a different entity with the same resource Uri."
Both of these problems only affect my generic screen using WCF RIA Services. When I build a ListDetail screen for a specific database entity there are no problems. It seems I'm missing some logic, any ideas?
I've learned that this the wrong approach to using LightSwitch.
There are several behind-the-scenes things this generic screen won't fully emulate and may not be do-able without quite a bit of work. The errors I've received are just one example. LightSwitch's built-in conflict resolution will also fail.
LS's RAD design means just creating a bunch of similar screens is the way to go, with some shared methods. If the actual layout needs changed across many identical screens at once, you can always find & replace the .lsml files if you're careful and make backups first. Note that modifying these files directly isn't supported.
I got that error recently. In my case I create a unique ID in my WCF RIA service, but in my screen behind code I must explicitly set a unique ID when I create the object that will later be passed to the WCF RIA Service insert method (this value will then be overwritten with the unique counter ID in the table of the underlying database).
See the sample code for this project:
http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/157/A-Visual-Studio-LightSwitch-Picture-File-Manager.aspx

MonoTouch, NSLog, and TestFlightSdk

I am trying to integrate the TestFlightSdk into an app I've made using MonoTouch.
I am trying to implement logging in my app in such a way that it is picked up by the TestFlightSdk. It supposedly picks up NSLogged text automatically, but I can't seem to find the right combination of code to add to my own app, written in C#/MonoTouch, that does the same.
What I've tried:
Console.WriteLine("...");
Debug.WriteLine("..."); (but I think this just calls Console.WriteLine)
Implementing support for NSlog, but this crashed my app so apparently I did something wrong (I'll ask a new question if this is the way to go forward.)
Is there anything built into MonoTouch that will write log messages through NSLog, so that I can use it with TestFlightSdk? Or do I have to roll my own wrapper for NSLog?
In order to implement NSLog myself, I added this:
public static class Logger
{
[DllImport("/System/Library/Frameworks/Foundation.framework/Foundation")]
private extern static void NSLog(string format, string arg1);
public static void Log(string message)
{
NSLog("%s", message);
}
}
(I got pieces of the code above from this other SO question: How to I bind to the iOS Foundations function NSLog.)
But this crashes my app with a SIGSEGV fault.
using System;
using System.Runtime.InteropServices;
using Foundation;
public class Logger
{
[DllImport(ObjCRuntime.Constants.FoundationLibrary)]
private extern static void NSLog(IntPtr message);
public static void Log(string msg, params object[] args)
{
using (var nss = new NSString (string.Format (msg, args))) {
NSLog(nss.Handle);
}
}
}
Anuj pointed the way, and this is what I ended up with:
[DllImport(MonoTouch.Constants.FoundationLibrary)]
private extern static void NSLog(IntPtr format, IntPtr arg1);
and calling it:
using (var format = new NSString("%#"))
using (var arg1 = new NSString(message))
NSLog(format.Handle, arg1.Handle);
When I tried just the single parameter, if I had percentage characters in the string, it was interpreted as an attempt to format the string, but since there was no arguments, it crashed.
Console.WriteLine() works as expected (it redirects to NSLog) on current xamarin.ios versions. Even on release builds (used by hockeyapp, etc). No need to use DllImport anymore.

Resources