How to change cameras in Unity based on camera coordinates? - unity3d

I'd like to create a movie in Unity, so I would need several cameras and camerapaths.
On the top of this off course I'd like to change between them. For example if Camerapath1 reaches a significant point with Camera1 then I'd like to change to Camerapath2 with Camera2, etc.
I also have Camera Path Animator asset installed. It's working perfectly when I'm using it with only one camera for several camerapaths but I'm unable to change between maincameras.
I'm a newcomer to Unity. I also know that I should do something like this:
...
camera1.camera.active = false;
camera2.camera.active = true;
...
...but where should I populate these lines? On the top of this, how may I catch the event when a camera on a specific camerapath reaches a particular point?

The way to go would be an animation controller that has all camera as children and controls the active state of all cameras. This provides perfect control over the behaviour.
Create an empty game object, add all cameras as children, add an Animator to the main object with one animation. This animation takes all the camera and set their active state. One extra bonus of this approach is the possibility to call methods as well using the AnimationEvent process. You can still define within the animation for some triggered actions like explosions or movements of objects.
As I said, this give you perfect control since you can define easily actions at specific time.
The downside of it is the rigidity of the process. It may not be as flexible as code, but since you are making a movie, you probably do not need flexibility.
If so, you would have your cameras with a collider and rigidbody (isKinematic true), then you would have some trigger box with a simple script:
public void CameraTrigger:MonoBehaviour{
public GameObject nextCamera;
void OnTriggerEnter(Collider col){
if(col.gameObject.CompareTag("Camera")){
col.gameObject.SetActive(false);
nextCamera.SetActive(true);
}
}
}
Then you drag the camera meant to start next as nextCamera.

Related

How to adjust character height when playing seated in closed VR with MRTK?

I am creating a VR application with mrtk 2.1 and want to have the User on the same height when playing seated or standing.
When Playing seated the camera is too low.
I could adjust the height of the MixedRealityPlayspace which contains the MainCamera, but that resets after using the teleport function.
Additionally learned from this GitHub Post, that there is an Offset between the MainCamera and MixedRealityPlayspace which is not accessible via mrtk so calculating the right height would be difficult.
This just does not seem like the right approach.
How can I make sure that the User is always on the right head height in game even when playing seated?
I've gone ahead and filed the following feature request:
https://github.com/microsoft/MixedRealityToolkit-Unity/issues/6786
An untested workaround may be the following:
Create logic that instantiates a new GameObject at runtime.
Set the new GameObject's parent to be the MixedRealityPlayspace.
Set the new GameObject to be the parent of your main camera
Apply your desired offset as a transform to this new GameObject.
Talking with different MRTK Contributors, its felt that you may need to do this transform configuration at runtime. Trying to do this in the editor/in the scene hierarchy may encounter problems because folks were unsure whether or not the main camera's parent gets set as the MixedRealityPlayspace regardless of whether or not the main camera is a grandchild of the MixedRealityPlayspace.
OK i found a solution that works for me.
I use the following code to move the mixedRealityPlayspace up or down to achieve the wanted player height.(if you want to use this make sure to tag your mixedRealityPlayspace GameObject "Player")
var mixedRealityPlayspace = GameObject.FindGameObjectsWithTag("Player")[0].transform;
var camHeight = mainCamera.transform.position.y;
var adjustement =wantedPlayerHeight-camHeight ;
mixedRealityPlayspace.position= new Vector3(mixedRealityPlayspace.position.x,mixedRealityPlayspace.position.y+adjustement, mixedRealityPlayspace.position.z);
I call this on ones on the start of my Scene and in the OnTeleportCompleted Event described in this Dokumentation for the MRTK Teleport system

Unity | How to play animations that are stored in a variable (without having them in the animator)

I'm creating a 2D fighting game, where the player can choose from a number of fighters. the fighters have different attacks with different animations.
the data (damage, hitbox, cast time, animation, etc.) for every attack is stored in a Scriptable Object that is then triggered by the player script. this worked out fine so far, but I can't find out how to play an animation from code without needing it to be in the animator.
I've tried several solutions that I found here but they seem to end up having to fall back to putting the animation in the animator.
but I can't find out how to play an animation from code without needing it to be in the animator.
You will need the Animator-Component to run an animation.
But you can assign the animation you want to play at runtime. For this you need the RuntimeAnimationController to hold the AnimatorController-object and assign it to your Animator (in code).
You do not necessarily need the Animator component as stated in this answer.
There is also the Animation component. It is marked as legacy but is still quite powerful especially when you do not need to configure an entire state machine but want to rather simply playback single AnimationClip. Might be the reason why this still makes it into newer Unity versions:
public AnimationClip clip;
private void Awake()
{
var animation = GetComponent<Animation>();
animation.clip = clip;
animation.Play();
}
Also see Animation.Play

Disabling head-tracking on a SteamVR camera in Unity?

I am trying to develop a HUD for my VR players using two cameras. One is a stationary camera that points at my HUD objects with a depth=1, the other is the main camera with depth=0 which tracks the HMD and has the HUD overlaid onto it.
However Unity, SteamVR or OpenVR is forcing my camera to track the player's HMD. After my exhaustive search I was unable to find any way to stop this behavior. Then I tried to parent all of my HUD objects to my HUD camera and hoped for the best.
This results in undesirable jerky motion in all HUD objects:
Project Hierarchy:
[WorldHUD]
|__ Container (HUD)
|__ Camera (eye)
|__ TextMesh (Status) <- Is child of camera
[CameraRig]
|__ Camera (Head)
|__ Camera (eye)
[SteamVR]
I believe I really need control over my camera's transform so I may prevent it from moving or stopping it from tracking the player's HMD.
I have tried updating the cameras position in Update() and LateUpdate() but that does not have any affect. I also spent many hours modifying/debugging SteamVR and OVR scripts which had no positive results and the cameras never stopped tracking.
I have tried using this suggested script on my cameras parent:
NegateTracking.cs:
using UnityEngine;
using UnityEngine.VR;
public class NegateTracking : MonoBehaviour
{
void LateUpdate()
{
transform.position = -InputTracking.GetLocalPosition(VRNode.CenterEye);
transform.rotation = Quaternion.Inverse(InputTracking.GetLocalRotation(VRNode.CenterEye));
}
}
This caused the camera to point in one direction but was still translating a bit. However I noticed that things seemed even more choppy this way and feel I'm either using it wrong or it just isn't sufficient.
I'm now back to looking for ways to disable headtracking on certain cameras so I am able to position them in my scene.
Does anyone know how SteamVR/OpenVR takes control of these camera's transforms? Is there any way to disable or overridden this behavior?
Thank you.
So, just spent the whole night developing a functional workaround and put together a project that uses a little post processing magic to essentially "spoof" a stationary camera. My idea was to generate two renderTextures from a custom stereo camera setup consisting of two separate cameras that are not being tracked (which allows control of position, rotation, convergence plane. fov and so on). I then pass those camera's (left and right) renderTextures to the left and right eyes of one of the "tracked" cameras within the OnRenderImage() function. It worked better than I expected, So I decided to put everything up on GitHub and write a short tutorial for anyone else needing to do this.
Stationary Stereo Camera (Download From GitHub)
Or you can change the target display and the target type (to main display) in your Camera component. (can also be done in a script)

Player dies when hitting the floor

I am trying to make a game in unity, and I am new to unity and coding, and I have started making a game, I have made some progress on it but I am having trouble finding some of my answers on youtube and the unity forum, and sometimes when I do, I still can't get things to work. So this is what I'm trying to do.
I have a map and the player is on top of the tower, I want the player to fall and when hitting the ground, dies with it displaying game over, What could I do to make this happen and what script?
So i have this now,
// Ground.cs: Kills players that touch this.collider.
using UnityEngine;
// Attach this to the grass collider
public class Ground : MonoBehaviour {
// Called when another collider hits the grass.
// This is part of Unity!
void OnCollisionEnter(Collision c) {
// Does the other collider have the tag "Player"?
if (c.gameObject.tag == "Player") {
// Yes it does. Destroy the entire gameObject.
Destroy(c.gameObject);
}
}
}
Now, I need to it transition to a game over overlay, which asks me to restart, yes or no.
The resources are out there in regards to learning Unity3D efficiently.
Look at the Unity3D tutorials: https://unity3d.com/learn/tutorials
These tutorials are usually kept up to date in terms of not using deprecated code. Additionally, several of the tutorials will teach you how to set up events like those that you need.
In regards to your immediate question though, look into forming the logic for your game.
You're going to need allow your player gameobject to fall via either gravitational force enacted on a rigidbody or hard-coded physics being applied to the gameobject. Next you will need to determine if the player gameobject has collided with the "floor". If so you will need to trigger an event to destroy the player gameobject, then display a GUI Text that says Game Over.
Look around more at tutorials and get better acquianted with Unity. Over time, you'll learn how to make things happen. If you have more questions, feel free to ask.
Answer to you update:
If your code is functioning correctly and your destroying your gameobject correctly, then awesome! You're learning fast!
The next step could be:
Create a Canvas, create a gui panel, create a gui text
That gui text object can have your Game Over Text
Now, create a button that you will utilize as the restart button
You can have the button call a function which utilizes SceneManager.LoadScene to reload the scene. Look here for an example: http://answers.unity3d.com/questions/1109497/unity-53-how-to-load-current-level.html
Next, Disable the panel as you will not need it until your player dies.
When your player collides with the ground you will destroy the player gameobject and set the panel you created to active. (you can trigger these actions via a listener in code or via the button component in the inspector).

Unity3d 3d skybox not quite right

I'm messing around in unity3d in order to learn it.
Had a crack at making my own 3d skybox like in source engine for example. I'm using the standard 1st person controller.
I made another camera with same FOV for my skybox, and slaved it to the camera in the 1st person controller using the script below which I put on my skybox camera.
(Maincam field has the 1st person controller camera component in it)
using UnityEngine;
using System.Collections;
public class CameraSlave : MonoBehaviour {
public Component Maincam;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
transform.rotation = Maincam.transform.rotation;
}
}
You can see result here. Its a bit funny. (The big tetrahedron shape in the background is in my skybox everything else is normal)
As far as I understand it as long as the camera fov is the same it doesnt matter what size my skybox things are.
I think the problem, is there is some lag maybe? Like the Update in the code above is being called one frame too late? I tried calling that update from the 1st person controllers mouse look script but as well as getting loads of errors the result was the same.
I can't visualize your example, btw:
I think the problem, is there is some lag maybe? Like the Update in
the code above is being called one frame too late? I tried calling
that update from the 1st person controllers mouse look script but as
well as getting loads of errors the result was the same.
You can't rely on the order in which Update method will be called by the engine (unless you force a particular order, but this isn't generally a good choice). For camera update operations it's better to use LateUpdate. It's guaranteed that it will be called after all Update methods.