Search Unity

  1. All Pro and Enterprise subscribers: find helpful & inspiring creative, tech, and business know-how in the new Unity Success Hub. Sign in to stay up to date.
    Dismiss Notice
  2. Dismiss Notice

Cinemachine -Target Follow an Initialize Prefab

Discussion in 'Cinemachine' started by nlv22, Sep 23, 2018.

  1. nlv22

    nlv22

    Joined:
    Dec 20, 2016
    Posts:
    31
    Since my player gets initialized in runtime, I am trying to add cinemachine's target and follow through code. What I tried below is not working:

    Inside the Cinemachine Virtual Camera Script I change

    override public Transform LookAt
    {
    get { return ResolveLookAt(m_LookAt); }
    set { m_LookAt = value; }
    }

    override public Transform Follow
    {

    get { return ResolveFollow(m_Follow); }
    set { m_Follow = value; }
    }

    To this:

    override public Transform LookAt
    {
    get { return ResolveLookAt(m_LookAt); }
    set { m_LookAt = GameObject.Find("Player").transform; }
    }

    override public Transform Follow
    {

    get { return ResolveFollow(m_Follow); }
    set { m_Follow = GameObject.Find("Player").transform; }
    }


     
    murp35 likes this.
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    5,014
    @novavillanueva22 Don't do that. Leave CinemachineVirtualCamera.cs alone. Instead, have another script that does:
    Code (CSharp):
    1. var vcam = GetComponent<CinemachineVirtualCamera>();
    2. vcam.LookAt = bla;
    3. vcam.Follow = bla;
     
  3. nlv22

    nlv22

    Joined:
    Dec 20, 2016
    Posts:
    31
    Thanks! I made another script (see below). It finds the initialize player as a target in the new FollowPlayer Script but doesn't do anything to Cinemachine. Seems I am missing something.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Cinemachine;
    5.  
    6. public class FollowPlayer : MonoBehaviour
    7. {
    8.  
    9.  
    10.     public GameObject tPlayer;
    11.     public Transform tFollowTarget;
    12.     private CinemachineVirtualCamera vcam;
    13.  
    14.     void Start()
    15.     {
    16.         var vcam = GetComponent<CinemachineVirtualCamera>();
    17.     }
    18.  
    19.     void Update()
    20.     {
    21.         if (tPlayer == null)
    22.         {
    23.             tPlayer = GameObject.FindWithTag("Player");
    24.         }
    25.         tFollowTarget = tPlayer.transform;
    26.         vcam.LookAt = tFollowTarget;
    27.         vcam.Follow = tFollowTarget;
    28.     }
    29. }
    30.  
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    5,014
    To which game object did you attach this script?
    Also: all the code should be in Start(), no need to do it every frame in Update().
     
  5. nlv22

    nlv22

    Joined:
    Dec 20, 2016
    Posts:
    31
    I've attached the script to the CM vcam1 camera GameObject Cinemachine makes when you add a camera. I do not have any other cameras in the scene. If I manually add the player prefab at runtime, Cinemachine (follow target) does work.

    It highlights 'vcam.LookAt = tFollowTarget;' as an error (which I'm guessing the previous line may be the problem) that reads:

    NullReferenceException: Object reference not set to an instance of an object
    FollowPlayer.Update () (at Assets/FollowPlayer.cs:26)
     

    Attached Files:

  6. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    5,014
    Probably tPlayer is null. Unity won't find it if it's not in the scene.
    Also, the virtual camera should not have a Camera component. Best to remove it.
     
  7. nlv22

    nlv22

    Joined:
    Dec 20, 2016
    Posts:
    31
    tPlayer is found after the game starts as show on this new screenshot attached. I am sorry, I didn't have this showing before. The Player does not start in the scene- it gets initialized after. This is a multi player setup. Is this some overriding Cinemachine problem?

    Oh, this camera component was created by Cinemachine's when I added a 'Create 2d Camera'. My virtual camera doesn't seem to work without it.
     

    Attached Files:

  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    5,014
    In that case, leave your code in Update(), but you must handle the case where tPlayer is null because it hasn't been spawned yet:
    Code (CSharp):
    1.     void Update()
    2.     {
    3.         if (tPlayer == null)
    4.         {
    5.             tPlayer = GameObject.FindWithTag("Player");
    6.             if (tPlayer != null)
    7.             {
    8.                 tFollowTarget = tPlayer.transform;
    9.                 vcam.LookAt = tFollowTarget;
    10.                 vcam.Follow = tFollowTarget;
    11.             }
    12.         }
    13.     }
    Cinemachine will never create a Camera component for you. It should not be there.
    Can you show me your inspector for the Main Camera? The one with the Brain.
     
    Vainusy likes this.
  9. nlv22

    nlv22

    Joined:
    Dec 20, 2016
    Posts:
    31
    Thanks for all the help so far. I really appreciated. I updated the code as illustrated above which made things better by the console not throwing 100s of lines.

    The connection to Cinemachine seems to still be missing. You were right that the camera with the brain doesn't have another camera. Only the vCM vcam1 GameObject has another camera. I've attached a screenshot for each.

    The same error appears: NullReferenceException: Object reference not set to an instance of an object
    FollowPlayer.Update () (at Assets/FollowPlayer.cs:33)



    Capture.JPG Capture2.JPG

    .
     
  10. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    5,014
    The problem is that the structure is wrong. Somehow it got mixed up. You should have this:

    GameObject1: Tag: MainCamera
    - Camera
    - Audio Listener
    - CinemachineBrain

    GameObject2: CM vcam1
    - VirtualCamera
    - FollowPlayer

    The job of the brain is to monitor all the active vcams in the scene, and position itself (and the Camera) according to the one with the highest priority, and do blends when a different vcam is activated.

    If you start with an empty scene and do Cinemachine/CreateVirtualCamera, you will see that you get this structure.
     
    murp35 likes this.
  11. nlv22

    nlv22

    Joined:
    Dec 20, 2016
    Posts:
    31
    Works now!

    When I made a new fresh scene as you advised, I realized that the warnings were turn off in the other project that read 'vcam was assigned but not used' so that the error of 'Object reference not set to an instance of an object' was not the only thing. Sorry about that, that would have been useful knowledge for troubleshooting.

    In the code I accidentally wrote:

    [B]var vcam = GetComponent<CinemachineVirtualCamera>(); [/B]


    instead of just:

    [B]vcam = GetComponent<CinemachineVirtualCamera>();[/B] 


    From the new clean project I did see that my setup is a bit strange with an additional camera. Although its working, I'll correct that just in case of future problems. So the final code is now:

    Code (CSharp):
    1. using UnityEngine;
    2. using Cinemachine;
    3.  
    4. public class FollowPlayer : MonoBehaviour
    5. {
    6.     public GameObject tPlayer;
    7.     public Transform tFollowTarget;
    8.     private CinemachineVirtualCamera vcam;
    9.  
    10.     // Use this for initialization
    11.     void Start()
    12.     {
    13.         vcam = GetComponent<CinemachineVirtualCamera>();
    14.     }
    15.  
    16.     // Update is called once per frame
    17.     void Update()
    18.     {
    19.         if (tPlayer == null)
    20.         {
    21.             tPlayer = GameObject.FindWithTag("Player");
    22.             if (tPlayer != null)
    23.             {
    24.                 tFollowTarget = tPlayer.transform;
    25.                 vcam.LookAt = tFollowTarget;
    26.                 vcam.Follow = tFollowTarget;
    27.             }
    28.         }
    29.     }
    30. }
    Much thanks to you Greg!
     
    ToyBrain101 and CaliSangren like this.
  12. duanegra

    duanegra

    Joined:
    Aug 28, 2018
    Posts:
    10
    There is another way to handle this problem. Combine the object that you want to follow (such as Player), and the virtual camera in one prefab. This can be done by making them children of an empty game object. Be sure set the Follow, and Look at targets before making the prefab. Also be sure the set the positions of the components to zero. Now you can Instantiate them all at once, and the v-cam will follow the object.

    I hope this helps. All the best!
     
    andrescuevas and AhmedFireKing like this.
  13. blastedw

    blastedw

    Joined:
    Apr 29, 2019
    Posts:
    13
  14. ZZRTheBeasT

    ZZRTheBeasT

    Joined:
    Jan 16, 2020
    Posts:
    1
    I cannot use var
     
  15. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    5,014
    CinemachineVirtualCamera vcam = GetComponent<CinemachineVirtualCamera>();
     
    a01024592 likes this.
  16. ShonySion

    ShonySion

    Joined:
    Jul 9, 2020
    Posts:
    1
    my
    public CinemachineVirtualCamera vcam;
    line Gets An error CS0246 pls help
     
  17. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    5,014
    @ShonySion Do you have
    using Cinemachine;
    at the top?
     
  18. MathewHI

    MathewHI

    Joined:
    Mar 29, 2016
    Posts:
    243
    Good idea but you will have to also write code to instantiate a new version of cinemachine. I tried your idea it works except for the fact that when I instantiate my player it destroys previous players and adds an new one, this separates the prefab the cinemachine and player into two in the heirarchy.
     
  19. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,254
    So no matter what I try I cannot assign follow or lookat from code. It works fine if I drag them into inspector, is there something special I need to do to assign from code??
     
  20. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    5,014
    It should just work.
    Can you show the code?
     
    radiantboy likes this.
  21. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,254
    Sorry it was my own logic error, works now. Making cutscenes in cinemachine :)
     
unityunity