I'm working on a Mixed Reality app in Unity.
I'm trying to update my own hand mesh according to:
https://learn.microsoft.com/en-us/windows/mixed-reality/mrtk-unity/features/input/hand-tracking?view=mrtkunity-2021-05#hand-mesh-prefab
public void OnHandMeshUpdated(InputEventData<HandMeshInfo> eventData)
{
print("Hand mesh update!");
if (eventData.Handedness == myHandedness)
{
myMesh.vertices = eventData.InputData.vertices;
myMesh.normals = eventData.InputData.normals;
myMesh.triangles = eventData.InputData.triangles;
if (eventData.InputData.uvs != null && eventData.InputData.uvs.Length > 0)
{
myMesh.uv = eventData.InputData.uvs;
}
}
}
However, the method OnHandMeshUpdated(InputEventData eventData) never triggers. I use Holographic Remoting. I made sure I set the Hand Mesh Visualization Modes to "Everything" in MRTK -> Articulated Hand Tracking.
MRTK Image
What am I missing? How can I animate my own hand mesh?
Unity: 2020.3.26f1
MRTK: 2.7.3
check if you registered for global input events.
Maybe this link will provide some information.
https://learn.microsoft.com/en-us/windows/mixed-reality/mrtk-unity/mrtk2/features/input/input-events?view=mrtkunity-2022-05
I tried Global input registration example in this link and it worked.
Related
I have build a driver simulator using Unity and I use as steering wheel the Logitech G29 controller.
So in my project to break and throttle I configured this:
Vertical1 is used to Throttle function and Vertical2 is used to Break function. This configuration are working now.
Now I need to configure also another controller (HC1 3DRap). This is an Hand Controller. So I checked it on windows device and I can see this:
Rotation Axis X and Rotation Axis Y have a value in sleep mode (without press the two levels).
Now I need to integrate also this new Controller in my project. So I try to make this:
In this mode if I try to check value of Y axis value with the follow code ( in this moment I cannot press the levers) :
Debug.Log("Input debug frenata: " + Input.GetAxis("Vertical2"));
I can display this:
If I try to press a levers, I can display this values
In this mode with thie new controller join on the system I m not able to run the car, because I think that there is every time the break pressed.
Could you suggest me, how can I fixed this bug ?
I run into a similar problem some time ago. I found out, that the axis I was actually using was not the one I expected.
Let's say you have a joystick and have a separate "POV-Stick" on it. When you use the POV-Stick you might be moving the whole joystick and therefore change the main axis of the joystick. If you are just watching the main axis input, it looks like that is the input of your POV-Stick, but actually isn't. So make sure the input you read is the correct one.
Then you have another problem: Not every joystick, steer etc. is mapping it's inputs to the same axis. So if you buy 2 more devices, they might be on a different axis as well. If you try to handle that on your own, you go crazy.
There is a unity forum about that topic (and other related problems).
And I found that there are some unity plugins, that could probably solve your problem:
https://github.com/speps/XInputDotNet
https://github.com/JISyed/Unity-XboxCtrlrInput
I hope you can solve your problem with these inputs (please let us know, if you do).
It seems that since you're seeing values even when the input device is not being used, that you'll need to "zero" the device and use dead zones like you might for a joystick or controller.
In the Player or Input script, in OnEnable/Awake/Start (whichever works best for you), set the "zero" value for the device in a field. You can run the assignment of the Vertical2 zero value in a method, and then allow the player to recalibrate during play with a button that invokes that function.:
private float _vertical2Zero = 0.0f;
void Start()
{
this.CalibrateVertical2Zero();
// ... more code ...
}
private void CalibrateVertical2Zero()
{
this._vertical2Zero = Input.GetAxis("Vertical2")
{
Then, when you're checking the value later, test it against the "zero" value, and apply some deadzones if desired:
private float _vertical2Deadzone = 0.05f;
void HandleInput()
{
float newVertical2Value = Input.GetAxis("Vertical2");
bool vertical2Low = newVertical2Value <= ( this._vertical2Zero - _vertical2Deadzone );
bool vertical2High = newVertical2Value >= ( this._vertical2Zero + _vertical2Deadzone );
if( vertical2Low || vertical2High )
{
// Input detected on Vertical2, accounting for the zero and deadzone
}
}
This can help with your problem.
How to manage input in Unity
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
// Spacebar was pressed
}
if (Input.GetMouseButtonDown(0))
{
// Left mouse was pressed
}
}
The new Input System
using UnityEngine;
using UnityEngine.InputSystem;
public class ReportMousePosition : MonoBehaviour
{
void Update()
{
Vector2 mousePosition = Mouse.current.position.ReadValue();
if(Keyboard.current.anyKey.wasPressedThisFrame)
{
Debug.Log("A key was pressed");
}
if (Gamepad.current.aButton.wasPressedThisFrame)
{
Debug.Log("A button was pressed");
}
}
}
Hope it helped
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteAlways]
public class SkyBox : MonoBehaviour
{
public Material[] skyboxes;
public Camera skyboxCamera;
public float skyboxMoveSpeed = 2f;
private int index = 0;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
SwitchSkybox();
}
if (RenderSettings.skybox == skyboxes[1])
{
RenderSettings.skybox.SetFloat("_Rotation", Time.time * skyboxMoveSpeed);
}
}
public void SwitchSkybox()
{
index++;
if (index == skyboxes.Length)
{
index = 0;
}
RenderSettings.skybox = skyboxes[index];
if (RenderSettings.skybox == skyboxes[1])
{
skyboxCamera.enabled = true;
Camera.current.enabled = false;
Time.timeScale = 1.0f;
}
else
{
skyboxCamera.enabled = false;
Camera.current.enabled = true;
Time.timeScale = 0.0f;
}
}
}
The script switch between skyboxes the default and my skybox and also switch between the currently active camera and the sky box camera.
But when I'm hitting the escape key it's throwing null exception in the editor on the line number 46 :
Camera.current.enabled = false;
The current of the Camera is null
I want to make that when I press the escape key it will switch to my skybox and to the skybox camera and also will pause the game (Later I will make a main menu when the game is paused).
This is the Camera.current, from the manual.
The camera we are currently rendering with.
Also worth noting the comment from Ruzihm.
The Unity engine typically assigns an already-instantiated instance of
Camera to Camera.current
So, from your scripts, I see 2 issues. The one directly related to this questions happens just in editor mode and I will start from that one.
Editor Issue: Camera.current is null
When working in the editor, Camera.current won't be just your own application's camera, but it could be any camera. It could even refer to the editor's scene view camera.
In this last case, if your scene view is not in focus (IE when you've focus on Game Window) Camera.current will be null.
Logical Issue: you couldn't switch back
When you try to switch back from skyboxCamera, your Camera.current will be the same skyboxCamera, and not your default camera. So you won't be able to retrieve the previous camera.
SOLUTION
Do not use Camera.current, but store all of your cameras in your script (this solution is also better for perfomance, since both Camera.current and Camera.Main are not performant scripts).
In your case you will need to add this piece of code to your script and use the EnableSkyBoxCamera method.
public Camera defaultCamera;
public Camera skyBoxCamera;
private Camera _currentCamera;
public void EnableSkyBoxCamera(bool enableSkyBox)
{
defaultCamera.enabled = !enableSkyBox;
skyBoxCamera.enabled = !enableSkyBox;
if (enableSkyBox) _currentCamera = skyBoxCamera;
else _currentCamera = defaultCamera;
}
If camera is null you can't set the enabled to false without getting a nullpointerexception. Instantiate the camera first or remove that line of code.
*** Edit ill take another crack at this
try
Camera.main.enabled = false;
instead of
Camera.current.enabled = false;
As per Unity docs in reference to Camera.current: 'Most of the time you will want to use Camera.main instead. Use this function only when implementing one of the following events: MonoBehaviour.OnRenderImage, MonoBehaviour.OnPreRender, MonoBehaviour.OnPostRender'
I am trying to find a configuration, or determine what additions I need to make to MRTK v2.1 to enable testing of HL1 in the 'Editor' work as it did with the prior workflow. Simplified, it is the ability to use Gaze and the mouse as we did prior to MRTK v2.
I have not found a way to map the left mouse button, in the profile, to behave as it does with the hand visible. With the hand visible pressing the left mouse enables manipulation. We simply need this with gaze as well. Note: Changing 'Hand Simulation' to Gestures does not produce the proper behavior it only makes the Gaze cursor persistent with no interaction.
I have asked this question in many places and it is often misunderstood so here is some background. We are continuing to deliver applications to clients that require stringent QA. They must be tested, as they have been while using the new MRTK. It is not reasonable to have our QA team use the articulated hands on a HL1 project as it introduces human error which is counterproductive to bug testing.
The needs are:
1. Have the cursor persistent in the Editor. (In the latest release, it disappears after using the hands via space bar.) This should be a toggle in our opinion. Yes, we know that you can press '1' to emulate select, but as mentioned in the above this is not acceptable for proper QA.
2. Have the left mouse button, without use of the hands, trigger 'Select' and 'Pinch'. I have written a service extension to handle the 'Select', but adding the pinch, as it is tied to the Hand articulation, has proven a challenge.
Proposed solutions so far: Change the 'Hand Simulation' mode to Gestures. Unfortunately, Gestures eliminates the ability to use the hands for HL2 testing and does not provide 'Select' or 'Pinch' behavior to the left mouse button. So it is either not working correctly or not the proper solution.
We do not see a reason why HL1 and HL2 cannot be tested in the editor at the same time. We are just missing the use of the left mouse button when the hands are not in use.
This is the Service extension I created for the left mouse button to send a 'Select' event. This will trigger an OnClick() event on an 'Intractable'. What it is missing the 'Pinch' ability to move or manipulate a 'Manipulation Handler' with the left mouse button as well.
[MixedRealityDataProvider(
typeof(IMixedRealityInputSystem),
(SupportedPlatforms)(-1), // All platforms supported by Unity
"Unity Mouse Device Manager")]
public class TharynMouseService : BaseInputDeviceManager, ITharynMouseService
{
private TharynMouseServiceProfile tharynMouseServiceProfile;
public TharynMouseService(
IMixedRealityServiceRegistrar registrar,
IMixedRealityInputSystem inputSystem,
string name,
uint priority,
BaseMixedRealityProfile profile) : base(registrar, inputSystem, name, priority, profile)
{
tharynMouseServiceProfile = (TharynMouseServiceProfile)profile;
}
private IMixedRealityInputSource inputSource;
private IMixedRealityInputSystem inputSystem;
public override void Initialize()
{
// Do service initialization here.
inputSystem = Service as IMixedRealityInputSystem;
Debug.Log("inputSystem: " + inputSystem);
inputSource = inputSystem.RequestNewGenericInputSource("Tharyn Mouse Service");
Debug.Log("inputSource: " + inputSource);
inputSystem.RaiseSourceDetected(inputSource);
}
public override void Update()
{
// Do service updates here.
if (UnityEngine.Input.GetKeyDown(KeyCode.Mouse0))
{
inputSystem.RaiseOnInputUp(inputSource, Handedness.None, tharynMouseServiceProfile.TapAction);
Debug.Log("Down");
Debug.Log("inputSystem: " + inputSystem);
Debug.Log("inputSource: " + inputSource);
Debug.Log("TapAction: " + tharynMouseServiceProfile.TapAction);
}
}
}
Needs:
Trigger the same event that the '1' key does upon releasing the space bar to return the gaze cursor.
Extend the above service to include the 'Pinch' event/action so that object can be manipulated with Gaze and Mouse as it is with Hands.
Cheers and thanks in advance!
Tharyn
you can achieve ability to simulate hand pinch, hand release events using just the mouse + cursor by creating a component that invoked OnInputDown and OnInputUp events to the MRTK Input System. You then need to attach this component to a game object in the scene.
The key code to simulate OnInputDown and OnInputUp events is the following:
public void Update()
{
if (Input.GetMouseButtonDown(0))
{
InputSystem?.RaiseOnInputDown(
InputSource,
Handedness.Right,
selectAction
);
}
if (Input.GetMouseButtonUp(0))
{
InputSystem?.RaiseOnInputUp(
InputSource,
Handedness.Right,
selectAction
);
}
}
Here is the full code for a component will raise input down and up events that will allow you to simulate pinch and drag + move using just the mouse:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Microsoft.MixedReality.Toolkit.Input;
using Microsoft.MixedReality.Toolkit;
using Microsoft.MixedReality.Toolkit.Utilities;
public class SimulateSelectOnClick : MonoBehaviour
{
private IMixedRealityInputSystem inputSystem = null;
protected IMixedRealityInputSystem InputSystem
{
get
{
if (inputSystem == null)
{
MixedRealityServiceRegistry.TryGetService<IMixedRealityInputSystem>(out inputSystem);
}
return inputSystem;
}
}
private IMixedRealityInputSource inputSource;
private MixedRealityInputAction selectAction;
private IMixedRealityInputSource InputSource
{
get
{
if (inputSource != null)
{
return inputSource;
}
inputSource = new BaseGenericInputSource("SimulateSelect",
new IMixedRealityPointer[] { InputSystem.GazeProvider.GazePointer }, InputSourceType.Hand) ;
return inputSource;
}
}
public void Start()
{
var inputActions = MixedRealityToolkit.Instance.ActiveProfile.InputSystemProfile.InputActionsProfile.InputActions;
selectAction = new MixedRealityInputAction();
for (int i = 0; i < inputActions.Length; i++)
{
if (inputActions[i].Description.Equals("select", StringComparison.CurrentCultureIgnoreCase))
{
selectAction = inputActions[i];
}
}
}
public void Update()
{
if (Input.GetMouseButtonDown(0))
{
InputSystem?.RaiseOnInputDown(
InputSource,
Handedness.Right,
selectAction
);
}
if (Input.GetMouseButtonUp(0))
{
InputSystem?.RaiseOnInputUp(
InputSource,
Handedness.Right,
selectAction
);
}
}
}
I'm making a VR application for iOS/Android.
I just bought Easy Movie Texture, using latest Unity version.
I can play one of the video. But I don't know how to play multiple videos.
For example, how do I make a cardboard tap trigger to change a movie?
I’m using the Sphere Example.
I created a gameobject, inside it’s update() function has a if(Carboard.SDK.Triggered) that I want to change the target parameter in sphere (Media Player Control Script). (Change the video)
How do I access this object? Where Exactly that object is created?
In short, mediaPlayerCtrl.Load(movieName) changes the movie. The movie must be in StreamingAssets for this to work properly (SD card is possible on Android, but requires more effort).
As you have issues with locating your MediaPlayerCtrl instance, here's an easy solution. Add this script to an example from Easy Movie Texture and use the ChangeMovie method.
using UnityEngine;
public class EMTChangeFile : MonoBehaviour
{
// drag an instance of Media Player Ctrl or leave empty for autodetection
public MediaPlayerCtrl mediaPlayerCtrl;
void Awake ()
{
if (mediaPlayerCtrl == null)
{
mediaPlayerCtrl = FindObjectOfType<MediaPlayerCtrl>();
if (mediaPlayerCtrl == null)
throw new UnityException("No Media Player Ctrl object in scene");
}
}
public void ChangeMovie(string movieName, bool autoplay = true)
{
mediaPlayerCtrl.Stop();
mediaPlayerCtrl.Load(movieName);
if(autoplay)
mediaPlayerCtrl.Play();
else
mediaPlayerCtrl.Stop();
}
}
I just started Unity last week, but I have a few years of programming experience. I want a light to come on when the game ends. Here is my code, the light doesn't light up.
using UnityEngine;
using System.Collections;
public class Collide : MonoBehaviour {
// Use this for initialization
void OnTriggerEnter(Collider other) {
light.intensity = 1;
}
}
You can toggle any bool by setting it to the opposite of its current value:
myBool = !myBool;
So you can toggle a light source by toggling its enabled state:
myLight.enabled = !myLight.enabled;
Now you want to do that if you press a certain button:
Light myLight = lightPoint.GetComponent("Light");
if (Input.GetButtonDown("Fire1")) {
myLight.enabled = !myLight.enabled;
}
If you copy/paste the code as is, it won't work. The code given is in C#, so you'd need to create a C# script (with all the attendant file/class name matching) and put the if expression inside the Update function.