Teleport Point: Switch to new scene - unity3d

I have used the following site to set up the teleportation in my game: https://unity3d.college/2017/05/16/steamvr-locomotion-teleportation-movement/.
As seen from the image, i have inputted 'Location3' as the new scene i would like to teleport to in the build settings. However, when i run the .exe file, i am not able to teleport to a 'Location3' even though I am able to teleport to the other teleport points to a new location in the current scene.
The console logs the "TeleportPoint: Hook up your level loading logic to switch to new scene: Location3".

What you are trying to achieve seems to be a scene change (?)
This can be done using
Application.LoadLevel("Location3");
When you change to this scene you might want to manipulate the position of whatever it is that you want to teleport. This could be achieved by using a static class that does something depending on what scene you are changing too.

I do not recommend to use Application.LoadLevel(), because that function is obsolete and won't be supported in future Unity releases.
You can use:
SceneManager.LoadSceneAsync("NameOfScene");
In order not to keep your Teleportation script from being destroyed you can add the following script to your Teleportation Component.
[Serializable]
public class KeepOnSceneChange : MonoBehaviour {
public void Awake() {
DontDestroyOnLoad(this.gameObject);
}
}
Using this Component your object won't be destroyed when a new scene is loaded and therefor can be used to teleport.

Related

Loading a scene in Unity twice causes some game objects to lose some components

When I hit play the game scene behaves as normal, even if I come from a different scene.
But when I am on the game scene and go to other scene and back again to the game scene some components from some game objects.
I am using SceneManager.LoadScene("SceneName"); to move around scenes, and every component was added in the editor and saved in the scene.
And as an example here is the Game Manager inspector at first load of game scene:
And second load of game scene:
Windows Controls is a script much like the others missing.
Am I doing something wrong?
Thanks in advance.
Without knowing what's going on inside the GameManager and the FoodManager scripts, I think you use the DontDestroyOnLoad similar what is showed on the bottom of the page, and your code destroys the scripts.
Simply put, I was short-sighted, I used a singleton pattern to access the managers and the way I did, at least, doesn't work in this context.
Any manager that I needed access I created a static instance, but since I checked for its existence elsewhere, the second time the component was destroyed.
public GameManager Instance {get; private set;}
void Awake()
{
if(Instance is not Null && Instance != this)
{
Destroy(Instance);
return;
}
Instance = this;
}
I realize that every time the scene loads the components are new objects, but I am still to understand why there is still copies of the old components.
I fixed it by using the [SerializeField] on any manager reference that I could and and manually adding them on the inspector, for some game objects that were instantiated at run time I pass the manager in a method.
GameManager gameManager;
public void Manager(GameManager _gameManager)
{
gameManager = _gameMananger;
}
GameObject gameObject = Instantiate(prefab);
gameObject.GetComponent<Script>().Manager(this);

Unity Navmesh bake multiple maps in the same scene

I have an scene with multiple maps, and when the game starts I randomly activate one of the maps and keep the others inactive.
My problem is that I can only have one the maps baked, because when I change to bake other map it's overwrited by the previous bake.
I search for other post to try baking at runtime but is seems it's not possible.
Is there a way to have multiple bakes or to bake only the active map at runtime?
To solve the problem, you can call the bake navigation code after the level changes.
Bake Navigation Inside Unity Editor
This code works similar to what is in the Unity Editor. Just make sure your Navigation Static object is enabled before using it.
The NavMeshBuilder class will allow this. In the code bellow.
using UnityEditor.AI;
...
public void Generate()
{
GenerateLevel(); // for e.g
NavMeshBuilder.BuildNavMesh();
}
Bake Navigation in Runtime
To bake in runtime, you need to download the necessary NavMeshComponents.
The component's will give you a NavMeshSurface component. It does not require static navmesh and works locally. Add component to all of your game ground's then put them in a list as the code bellow. After each run of the game, it is enough to BuildNavMesh all or part of them.
public List<NavMeshSurface> surfaces;
public void Start()
{
GenerateLevel(); // for e.g
surfaces.ForEach(s => s.BuildNavMesh());
}
Also this tutorial from Brackeys will help you so much.

How to animate grabbing in Unity VR?

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.

Why the gameObject created in subclass of MaskableGraphic not be destroyed when unity stopped running?

I have a class inherit MaskableGraphic. In the function Awake(), I create a gameObject. The strange thing is when stop Unity, the GameObject is not be destroyed.
public class Test : MaskableGraphic
{
protected void Awake()
{
var go = new GameObject();
}
}
It seems that, when inheriting from UI.Graphic (and ofc from any subclass of UI.Graphic), the [ExecuteInEditMode] attribute is active by default on the class.
It can be noticed by the fact that, using your script, the go game object is created as soon Unity serializes the compiled script, and moreover, if this GO is deleted at runtime, it's serialized back by Unity when exiting play mode and going back to edit mode: typical behaviour of scripts executed in the editor and not just in play mode.

How to Send message to another scene

I have two scenes in my game(Main Menu and Game).
There are two buttons in Main Menu each sending different values to Game.
So how can i set this value in other scenes script.
If I understand correctly you are trying to pass settings between the main menu scene and the game scene.
What you can do is create a GameSettings script that contains all your settings, and stick it on a game object of your main menu scene.
Store your settings in this script.
Loading the game scene would normally destroys all existing game objects, but Unity provides the Object.DontDestroyOnLoad() function that will prevent an object from being destroyed at loading.
Use this on your GameSettings script and it will exist in both the main menu and game scene and you will be able to retrieve your stored settings from the game scene.
Check the documentation for more info: http://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html
Here is an example:
public class GameSettings : MonoBehaviour
{
public int NumberOfPlayer;
/* Add other game settings here ... */
void Awake()
{
DontDestroyOnLoad(transform.gameObject)
}
}
Hope it helps :)
Any variable declared static in a script will be preserved across scene changes. If you have a script in both scenes, and set the value of a static variable in one of the scenes, the script instance in the other scene will access the same value.