I am using location services in a Unity 3D game. I am using this (slightly modified) script that I found in the Unity Documentation just for testing purposes. Here is the script:
using UnityEngine;
using System.Collections;
public class TestLocationService : MonoBehaviour
{
IEnumerator Start()
{
// First, check if user has location service enabled
if (!Input.location.isEnabledByUser)
print("no");
yield break;
// Start service before querying location
Input.location.Start();
// Wait until service initializes
int maxWait = 20;
while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0)
{
yield return new WaitForSeconds(1);
maxWait--;
}
// Service didn't initialize in 20 seconds
if (maxWait < 1)
{
print("Timed out");
yield break;
}
// Connection has failed
if (Input.location.status == LocationServiceStatus.Failed)
{
print("Unable to determine device location");
yield break;
}
else
{
// Access granted and location value could be retrieved
print("Location: " + Input.location.lastData.latitude + " " + Input.location.lastData.longitude + " " + Input.location.lastData.altitude + " " + Input.location.lastData.horizontalAccuracy + " " + Input.location.lastData.timestamp);
}
// Stop service if there is no need to query location updates continuously
Input.location.Stop();
}
}
When I run the script, it is supposed to print my location. However, it thinks that location services are not enabled (I am using Windows 10) and just prints "no" before stopping. In my location settings, I have location enabled.
Why isn't Unity allowed to use my location?
Location access in Unity is for Handheld Devices Only(i.e. Mobiles and Tablets). You cannot use it on a Computer.
Unity Docs: https://docs.unity3d.com/ScriptReference/Input-location.html
You have to give Unity the permission to use the location services also.
If you scroll down on the screenshot that you posted, you will have to toggle the switch for Unity also.
If that doesn't work you might want to try installing some sort of geo sensor and see if it makes any difference.
Based on http://answers.unity3d.com/questions/1219218/windows-10-using-location-with-unity-through-pc-no.html the api Input.location.isEnabledByUser is supposed to work only for (handheld devices only)
Related
I'm trying to use a cloud TTS within my Unity game.
With the newer versions (I am using 2019.1), they have deprecated WWW in favour of UnityWebRequest(s) within the API.
I have tried the Unity Documentation, but that didn't work for me.
I have also tried other threads and they use WWW which is deprecated for my Unity version.
void Start()
{
StartCoroutine(PlayTTS());
}
IEnumerator PlayTTS()
{
using (UnityWebRequestMultimedia wr = new UnityWebRequestMultimedia.GetAudioClip(
"https://example.com/tts?text=Sample%20Text&voice=Male",
AudioType.OGGVORBIS)
)
{
yield return wr.Send();
if (wr.isNetworkError)
{
Debug.LogWarning(wr.error);
}
else
{
//AudioClip ttsClip = DownloadHandlerAudioClip.GetContent(wr);
}
}
}
The URL in a browser (I used Firefox) successfully loaded the audio clip allowing me to play it.
What I want it to do is play the TTS when something happens in the game, it has been done within the "void Start" for testing purposes.
Where am I going wrong?
Thanks in advance
Josh
UnityWebRequestMultimedia.GetAudioClip automatically adds a default DownloadHandlerAudioClip which has a property streamAudio.
Set this to true and add a check for UnityWebRequest.downloadedBytes in order to delay the playback before starting.
Something like
public AudioSource source;
IEnumerator PlayTTS()
{
using (var wr = new UnityWebRequestMultimedia.GetAudioClip(
"https://example.com/tts?text=Sample%20Text&voice=Male",
AudioType.OGGVORBIS)
)
{
((DownloadHandlerAudioClip)wr.downloadHandler).streamAudio = true;
wr.Send();
while(!wr.isNetworkError && wr.downloadedBytes <= someThreshold)
{
yield return null;
}
if (wr.isNetworkError)
{
Debug.LogWarning(wr.error);
}
else
{
// Here I'm not sure if you would use
source.PlayOneShot(DownloadHandlerAudioClip.GetContent(wr));
// or rather
source.PlayOneShot((DownloadHandlerAudioClip)wr.downloadHandler).audioClip);
}
}
}
Typed on smartphone so no warranty but I hope you get the idea
I have 2 issues when using PhotoCapture on the Hololens 2, which are probably connected. They did not occur on the Hololens 1.
The only obtainable resolution is 3904x2196
Getting the CameraToWorldMatrix always fails
As can be seen in the docs, this resolution has no framerate associated with it.
My presumption is that the CameraToWorldMatrix is only obtainable for camera profiles with a lower resolution.
How can i change the resolution and get the matrix within Unity?
Minimal Reproducible Example
I am using Unity 2019.2.19f1 and Visual Studio 2019 Community (16.4.5)
Create a new Unity Project following the steps here, except using IL2CPP as the scripting backend instead of .NET
In Player Settings: Capabilities enable InternetClient, InternetClientServer, PrivateNetworkClientServer, Webcam, Microphone and SpatialPerception, in Player Settings: Supported Device Families select Holographic
Create a new empty gameobject and add the following script:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Windows.WebCam;
public class PhotoCaptureController : MonoBehaviour
{
PhotoCapture photoCaptureObject = null;
bool isRunning = false;
void Start()
{
StartCoroutine(StartCameraCapture());
}
private IEnumerator StartCameraCapture()
{
if (!Application.HasUserAuthorization(UserAuthorization.WebCam))
{
yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
}
if (Application.HasUserAuthorization(UserAuthorization.WebCam))
{
Debug.Log("Creating PhotoCapture");
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
}
else
{
Debug.Log("Webcam Permission not granted");
}
}
private void Update()
{
if (isRunning)
{
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
}
void OnPhotoCaptureCreated(PhotoCapture captureObject)
{
photoCaptureObject = captureObject;
IEnumerable<Resolution> availableResolutions = PhotoCapture.SupportedResolutions;
foreach (var res in availableResolutions)
{
Debug.Log("PhotoCapture Resolution: " + res.width + "x" + res.height);
}
Resolution cameraResolution = availableResolutions.OrderByDescending((res) => res.width * res.height).First();
CameraParameters c = new CameraParameters();
c.hologramOpacity = 0.0f;
c.cameraResolutionWidth = cameraResolution.width;
c.cameraResolutionHeight = cameraResolution.height;
c.pixelFormat = CapturePixelFormat.BGRA32;
captureObject.StartPhotoModeAsync(c, OnPhotoModeStarted);
}
private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
{
if (result.success)
{
isRunning = true;
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
}
void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame frame)
{
if (result.success)
{
if (frame.TryGetCameraToWorldMatrix(out Matrix4x4 cameraToWorldMatrix))
{
Debug.Log("Successfully obtained CameraToWorldMatrix: " + cameraToWorldMatrix.ToString());
}
else
{
Debug.Log("Failed to obtain CameraToWorldMatrix");
}
}
frame.Dispose();
}
}
Change Build Settings:
Build, open VS solution, set build target to ARM64, Debug and deploy to Device
This CameraCapture plugin may work for you. It's a native plugin for Unity. The readme.txt contains information on building it. Basically, you need to build the native plugin variants before trying to open up the Unity sample. If you haven’t built C++/WinRT components, you may need to go through the setup steps here. The SpatialCameraTracker.cs file shows how to receive the camera matrices.
There is minimal support on this but all the code is in the repo
I was about to release a new game on Steam. It is a Unity game in which I use Steamworks.NET to get achievements from Steam.
I use the following code:
if (SteamManager.Initialized) {
string name = SteamFriends.GetPersonaName ();
Debug.Log (name+" - "+SteamUser.GetSteamID() );
m_GameID = new CGameID (SteamUtils.GetAppID ());
Debug.Log ("number of achievements: " + SteamUserStats.GetNumAchievements ());
Debug.Log ("gameID: " + m_GameID);
} else {
Debug.Log ("Steam not initialized");
}
m_GameID is set correctly (I use a steam_appid.txt file).
I use it for all my steam games, but for some reason SteamUserStats.GetNumAchievements () always returns 0.
I published the achievements on Steam, but still don't know why this is happening.
How I can correct that?
I discover the problem.
I just need to call SteamUserStats.RequestCurrentStats() in the update method. It's working now.
I am using vuforia library in my unity project where I need to change the DigitalEyewearBehaviour properties on a users button click action. So far the orientation of the screen changes and when checked through the debug log the eyewear type and the mode both are seem to be set perfectly. But the device only changes the screen orientation to landscape and blacks out the camera.
public void ChangeToHeadGearMode(){
//static setting changes
Screen.orientation = ScreenOrientation.Landscape;
//Getting Player Settings
string ViewerType = PlayerPrefs.GetString("Viewer Type","Generic Cardboard (Vuforia)");
string SterioFrameWork = PlayerPrefs.GetString ("Sterio Framework", "0");
mDebug.Log ("Getting VT " + ViewerType);
mDebug.Log ("Getting SF " + SterioFrameWork);
//setting set
mDebug.Log (mHeadGearParameters.GetEyewearType().ToString());
mHeadGearParameters.SetEyewearType(Vuforia.DigitalEyewearAbstractBehaviour.EyewearType.VideoSeeThrough);
mDebug.Log (mHeadGearParameters.GetEyewearType().ToString());
if(SterioFrameWork=="0")
{
mHeadGearParameters.SetStereoCameraConfiguration(Vuforia.DigitalEyewearAbstractBehaviour.StereoFramework.Vuforia);
mDebug.Log ("ST=0");
}
else if(SterioFrameWork=="1")
{
mHeadGearParameters.SetStereoCameraConfiguration(Vuforia.DigitalEyewearAbstractBehaviour.StereoFramework.Cardboard);
mDebug.Log ("ST=1");
}
else if(SterioFrameWork=="2")
{
mHeadGearParameters.SetStereoCameraConfiguration(Vuforia.DigitalEyewearAbstractBehaviour.StereoFramework.GearVR);
mDebug.Log ("ST=2");
}
mHeadGearParameters.SetViewerActive (true,true);
}
The vuforia developer portal says a method as SetViewerActive When I apply that method only the camera blacks out. If I does not use that the camera does not black out but the view does not change to cardboard view. I have tried all the possible options in SetViewerActive method but does not work. I went through the vuforia developer portal a number of times but did not find the error.
What am I doing wrong or where am I missing an important point?
I found the answer to my own question and I am posting it to anyone who might come across the same problem. As of now there are no tutorials or real examples of how this actually works. So I had to go with trial and error and finally I found the solution.
The thing you need to do is just deinit the camera instance and then do the setting changes and then SetViewerActive(true,true) so that the camera will be reinitialised.
The final solution is as follows.
//static setting changes
Screen.orientation = ScreenOrientation.Landscape;
if (CameraDevice.Instance.Stop () && CameraDevice.Instance.Deinit ())
{
//Getting Player Settings
string ViewerType = PlayerPrefs.GetString("Viewer Type","Generic Cardboard (Vuforia)");
string SterioFrameWork = PlayerPrefs.GetString ("Sterio Framework", "0");
mDebug.Log ("Getting VT " + ViewerType);
mDebug.Log ("Getting SF " + SterioFrameWork);
//setting set
mDebug.Log (mHeadGearParameters.GetEyewearType().ToString());
mHeadGearParameters.SetEyewearType(DigitalEyewearAbstractBehaviour.EyewearType.VideoSeeThrough);
mDebug.Log (mHeadGearParameters.GetEyewearType().ToString());
if(SterioFrameWork=="0")
{
mHeadGearParameters.SetStereoCameraConfiguration(DigitalEyewearAbstractBehaviour.StereoFramework.Vuforia);
mDebug.Log ("ST=0");
}
else if(SterioFrameWork=="1")
{
mHeadGearParameters.SetStereoCameraConfiguration(DigitalEyewearAbstractBehaviour.StereoFramework.Cardboard);
mDebug.Log ("ST=1");
}
else if(SterioFrameWork=="2")
{
mHeadGearParameters.SetStereoCameraConfiguration(DigitalEyewearAbstractBehaviour.StereoFramework.GearVR);
mDebug.Log ("ST=2");
}
mHeadGearParameters.SetViewerActive (true,true);
}
Remember to active again the normal view: use DigitalEyewearARController.Instance.SetViewerActive(false, true); to deactivate it and reset the camera.
I need to find a way to have the kinect only recognize objects in a certain Range. The problem is that in our setup there will be viewers around the scene who may disturb the tracking. Therefore I need to set the kinect to a range of a few meters so it won't be disturbed by objects beyond that range. We are using the SimpleOpenNI library for processing.
Is there any possibility to achieve something like that in any way?
Thank you very much in advance.
Matteo
You can get the user's centre of mass(CoM) which retrieves a x,y,z position for a user without skeleton detection:
Based on the z position you should be able to use a basic if statement for your range/threshold.
import SimpleOpenNI.*;
SimpleOpenNI context;//OpenNI context
PVector pos = new PVector();//this will store the position of the user
ArrayList<Integer> users = new ArrayList<Integer>();//this will keep track of the most recent user added
float minZ = 1000;
float maxZ = 1700;
void setup(){
size(640,480);
context = new SimpleOpenNI(this);//initialize
context.enableScene();//enable features we want to use
context.enableUser(SimpleOpenNI.SKEL_PROFILE_NONE);//enable user events, but no skeleton tracking, needed for the CoM functionality
}
void draw(){
context.update();//update openni
image(context.sceneImage(),0,0);
if(users.size() > 0){//if we have at least a user
for(int user : users){//loop through each one and process
context.getCoM(user,pos);//store that user's position
println("user " + user + " is at: " + pos);//print it in the console
if(pos.z > minZ && pos.z < maxZ){//if the user is within a certain range
//do something cool
}
}
}
}
//OpenNI basic user events
void onNewUser(int userId){
println("detected" + userId);
users.add(userId);
}
void onLostUser(int userId){
println("lost: " + userId);
users.remove(userId);
}
You can find more explanation and hopefully useful tips in these workshop notes I posted.