Pretty much what the title says.
I'm creating a VR game in Unity and I want the player to be able to change their movement and camera settings via an in-game menu. What's giving me trouble at the moment is figuring out how to retrieve each (or just one) component (Action-Based Continuous Move, Action-Based Snap Turn, etc.) so that I can set them to true/false.
My idea was to set up a Canvas/Panel/Button on click event that passed a string into a function, and based on that string value, used if-statements to determine which components to enable/disable.
The script itself grabs the game object using: GameObject locomotion = GameObject.Find("Locomotion System");.
I tried using GetComponent<ActionBasedContinuousMoveProvider>.enabled = false; however it didn't work like I'd hoped.
Related
I've been googling this for 10 hours and I'm running out of ideas. I found several video-tutorials and written-tutorials but none of them really works or they're overkill.
I have VR Unity (2020.3.16f) project designed to be run on Quest 2. I'm not using OpenXR. I already created hand, created one simple grabbing animation, added animation to Animator, created transitions, and set "IsGrabbed" parameter. Now I'm looking a simple way to change "IsGrabbed" to true/false whenever I grab/release anything. I'm expecting something like this:
public class grabber : MonoBehaviour
{
// Start is called before the first frame update
Animator animator;
???
void Start()
{
???
}
// Update is called once per frame
void Update()
{
if (???)
{
animator.SetBool("IsGrabbing", true);
}
elseif (???)
{
animator.SetBool("IsGrabbing", false);
}
}
}
Please help. We're talking about VR here so I'm sure grabbing animation is the very basics of very basics of very basics. It can't be any difficult.
Best regards
First of all, I highly recommend watching this video by Justin P Barnett to get a much better overview of how this all works.
If you don't want to go that route for some reason, there are other options available to you. One such option is the "Player Input" component, which can act as a bridge between your input devices and your code. Most XR packages these days use the new Input System package, and it makes life easier, so I will assume you have that installed.
First, you will need to create an Input Actions asset, which can be done in the project pane: right-click -> Create -> Input Actions. There are many tutorials which explain this asset in detail, but here is a simple setup to get you started. Double click on the new asset to open the editing window, and create a new Action Map. In the "Actions" list, create a new action with action type Value, Control Type Axis, and in the dropdown arrow on your new action set the path to the input source. As an example source path, I will use XR Controller -> XR Controller -> XR Controller (Left Hand) -> Optional Controls -> grip. Make sure to click Save Asset before closing the window.
Create a script similar to this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class ControllerInputReceiver : MonoBehaviour {
public void FloatToScale(InputAction.CallbackContext context) {
float val = 0.1f + 0.1f * context.ReadValue<float>();
transform.localScale = new Vector3(val, val, val);
}
}
Create a cube somewhere visible in your scene, and add the Input Action Manager component to it, and drag your created Input Actions asset to its list of Action Assets. Then add the ControllerInputReceiver script. Also on this cube, create a Player Input component and drag your Input Actions asset to its Actions element. Choose your map as the default map and change behavior to Invoke Unity Events. Under the events drop down, you should see an element for the Action you created earlier. Drop your Controller Input Receiver component into this Action and select the FloatToScale function.
In theory it should work at this point. Build the game to your device and see if pulling the grip causes the cube to resize. If it does, then you can replace your Update function with:
void SetGrabbing(InputAction.CallbackContext context) {
animator.SetBool("IsGrabbing", context.ReadValue<float>() > cutoff);
}
If you are still having issues at this point, I really recommend checking out these youtube channels. I only started VR a couple of months ago and learned everything I know so far from these people. JustinPBarnett, VRwithAndrew, ValemVR, LevelUp2020. (Links removed because it kept screwing up my post)
Note, the new input system has button options instead of value/axis options for VR devices. These may be closer to what you want, but I had no luck getting them to work today.
Also note, depending on how you organize your code, you may or may not need the "Input Action Manager" component somewhere in your scene with your input actions asset in its list. It enables your actions for you, without you needing to do this programmatically.
Another solution would be:
Using the OVR plugin and Hands prefab (for left and right), to check whether the rotation of each of the fingers on a specific axis (ex. Z-Axis) falls under a specific range-meaning fingers are grasping/flexed.
By referencing for example the Transform of b_l_index1 , which is the corresponding part of the Index Finger within the model, you can check its local roation every frame and trigger the event of grasping when all fingers are rotated to a specific angle. Subsequently, triggering the animation you need.
I have been working with Unity 2020.3 LTS, the Windows XR Plugin, and the amazing MRTK 2.7.0 to port an existing application to HoloLens 2.
In this application I have a scene with several GameObjects in it and I need to detect whether a hand touches a GameObject (either with the indexfingertip near interaction or the pinch gesture far interaction). The important part here is that this detection needs to happen in a central script in the scene (i.e. maybe have the hand as an object in the code) and not from the view of the touched Gameobject itself.
I have successfully implemented the latter using this example with the two code examples below on that page, but the touched GameObject itself firing events via a listener does not work well with my use case. I need to detect the touch from the hand's perspective, so to speak.
I have searched the web and the Microsoft MRTK documentation several times for this and unfortunately I could not find anything remotely helpful. For head-gaze the documentation has a super simple code example that works beautifully: Head-gaze in Unity. I need the exact same thing for detecting when a hand touches a GameObject.
Eventually I will also need the same thing for eye-tracking when looking at a GameObject, but I have not looked into this yet and right now the hand interaction is giving me headaches. I hope someone can help me with this. Thanks in advance :).
but the touched GameObject itself firing events via a listener does not work well with my use case.
Why does the event not work? Could you provide more detail about it?
In addition to NearInteractionTouchable, have you tried the Interactable component? It's usually used to attach to the touched Game Object and will fire the event receiver when catching input actions. In the event receiver (in the Component UI), you can add any function attached to any object as the listener, such as a central script in the scene. It should be an effortless way can meet your request. For more information please see: Event
After some additional fiddling around I was able to get it to work the way I want/need to with the Touch Code Example. The solution was to create an empty GameObject variable in the code of the central script that is continuously checked whether it is null or not. The touch on the GameObject itself then binds itself to that checked GameObject variable as long as it is touched and sets it back to null once it is not touched anymore. This allows the central script to work with the touched GameObject as long as it is touched.
void Start()
{
centralScript = GameObject.Find("Scripts").GetComponent<CentralScript>();
NearInteractionTouchableVolume touchable = gameObject.AddComponent<NearInteractionTouchableVolume>();
touchable.EventsToReceive = TouchableEventType.Pointer;
pointerHandler = gameObject.AddComponent<PointerHandler>();
pointerHandler.OnPointerDown.AddListener((e) =>
{
centralScript.handTouchGameObject = gameObject;
});
pointerHandler.OnPointerUp.AddListener((e) =>
{
centralScript.handTouchGameObject = null;
});
}
I am a bit of a novice with the Unity Engine and Mixed Reality App development so please bear with me.
I have been working with the Microsoft Mixed Reality Toolkit for Unity to try and animate a game object and move it to the side. A simple action, very similar to an example scene provided by Microsoft with the toolkit called "InteractableObject" (Information links provided below)
Interactable Object - Mixed Reality (Microsoft Docs)
Mixed Reality Toolkit-Unity Interactable Objects and Receivers (Github)
This example scene in Unity has multiple objects to be used as "buttons". With the Mixed Reality Toolkit, even objects that you want the user to interact with to perform some sort of action when selected is even considered a button. At least according to the documentation I have actually been able to find on the subject. This is a series of screenshots depicting the inspector panels for my GameObject and the container for my object:
GameObject Inspector Panel
GameObject Container Inspector Panel (Part 1
GameObject Container Inspector Panel (Part 2
I am trying to make a single game object move to the side when I place the standard cursor on it. This same action is done with a balloon object in the example scene I mentioned. I have created the animator and the state machine the same as they did in there example as well as setup my game object in an almost identical format. Only real difference is that created a balloon object themselves and I am using a different set of custom models from my company.
When I attempt to play back the app in the Unity Editor, the state does not change when I place the cursor on the object. I can force the state to change using the editor and the required animation engages, but it will not change the state on its own. I configured my state machine the same as the Microsoft example and setup my state variable the same as well. It should move from an "Observation" state to a "Targeted" or "ObservationTargeted" state when the cursor moves onto the object. A screenshot of the GameObject state machine and the inspector panel of the specific transition in question are provided below:
GameObject Animator State Machine Setup
Observation to ObservationTargeted Transition Inspector Panel
I went through and verified that all components added by the Mixed Reality Toolkit are the same and they are. This includes the DefaultCursor, InputManager, MixedRealityCameraParent and Directional Light. I also checked that all the scripts were coded the same as well and they are. I am running out of places to look. I attached the Visual Studio debugger to the project in Unity and have verified that it just isn't changing the state on its own. But I cannot figure out why. I believe the problem has something to do with the setup of the transition, but I haven't been able to find the issue. All of the other mentioned components are provided by Microsoft and are not changed by myself nor are they changed in the sample scene.
If anyone else has had a similar problem or may know where I can look to find the problem please let me know. I haven't even built the project into an UWP application yet.
I know it's been a few months, but do you still looking for the solution?
With the newest version of Mixed Reality Toolkit you could make any GameObject to act as a button. Simply read this documentation. I have some cubes as buttons in my Unity project and the only extra Component I added to it to make it work was Interactable, which comes from Mixed Reality Toolkit.
If you want to trigger some animation when you place the cursor on the object (or look at it if you're going to use it with Hololens) then you can add them in Interactable object by adding a new Event (for example: OnFocus() event)
Hope this helps is any way
I'm working with the Google VR Unity SDK and I'm trying to create a VR application where users can switch between multiple ambients(places). I want them to switch to a different ambient just by pushing down the magnetic sensor of the cardboard, pointing anywhere. My problem is that every link (like this one) I've found, works with objects selection. I've tried adding an Event Trigger to my Main Camera and adding a Mesh collider to my building but none of them worked.
So, ¿is it possible to listen for the magnetic sensor pushdown in the full scene without having to select an object?
Turns out it's simpler than I thought.
if(Input.GetButtonDown("Fire1")){
//some code
}
Thing is googleVR removed magnetic button support since version 0.9.0 and I was using 1.0.3. So if you want to implement a trigger for cardboard's magnetic button you need to use v0.8.5.
You could put up a Canvas that's attached to the camera in World Space, so that it always stays in the line of sight. Add a Button to the canvas at the location where the gaze input cursor is, and you should always hit that when triggering.
How can i make an image to randomly appear while in-game in Unity3D ? It will serve as my popup advertisements for my game. I want to have ads without using AdMobs or any other plugins.
Depending on how you plan to display your images. You could write a script to randomly Enable a GUI Image, then have the GUI Image become disables after a specified time is over or by a button click (like a "X" symbol or close button).
My recommendation would be some mix of the following:
Create an UI Image GameObject. Use this as the main Advertisement GameObject.
Create a script to set this gameobject active/inactive randomly throughout the game. Place this script on an object in the hierarchy that will exist throughout the game.
Create a script that will be your advertisement handler. Attach this to your UI GameObject. In this you can create some sort of structure to hold different ads or however you plan to populate the ads. Then you can customize the way the ads will be displayed. Will it be random? Will it happen sequentially? Are there different types of ads?
Create logic to disable the gameobject based on a timer or by way of a close button.
If you get around to coding and have trouble, then please feel free to ask about the coding. Also, check out the Unity Forums for questions specific to Unity.