Cinemachine -Target Follow an Initialize Prefab

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; }
}

2 Likes

@nlv22 Don’t do that. Leave CinemachineVirtualCamera.cs alone. Instead, have another script that does:

var vcam = GetComponent<CinemachineVirtualCamera>();
vcam.LookAt = bla;
vcam.Follow = bla;
20 Likes

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.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;

public class FollowPlayer : MonoBehaviour
{


    public GameObject tPlayer;
    public Transform tFollowTarget;
    private CinemachineVirtualCamera vcam;

    void Start()
    {
        var vcam = GetComponent<CinemachineVirtualCamera>();
    }

    void Update()
    {
        if (tPlayer == null)
        {
            tPlayer = GameObject.FindWithTag("Player");
        }
        tFollowTarget = tPlayer.transform;
        vcam.LookAt = tFollowTarget;
        vcam.Follow = tFollowTarget;
    }
}
6 Likes

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().

2 Likes

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)

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.

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.

3726406--308644--Capture2.JPG

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:

    void Update()
    {
        if (tPlayer == null)
        {
            tPlayer = GameObject.FindWithTag("Player");
            if (tPlayer != null)
            {
                tFollowTarget = tPlayer.transform;
                vcam.LookAt = tFollowTarget;
                vcam.Follow = tFollowTarget;
            }
        }
    }

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.

1 Like

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)

3728062--308824--Capture.JPG

.

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.

1 Like

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:

**var vcam = GetComponent<CinemachineVirtualCamera>();**

instead of just:

**vcam = GetComponent<CinemachineVirtualCamera>();**

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:

using UnityEngine;
using Cinemachine;

public class FollowPlayer : MonoBehaviour
{
    public GameObject tPlayer;
    public Transform tFollowTarget;
    private CinemachineVirtualCamera vcam;

    // Use this for initialization
    void Start()
    {
        vcam = GetComponent<CinemachineVirtualCamera>();
    }

    // Update is called once per frame
    void Update()
    {
        if (tPlayer == null)
        {
            tPlayer = GameObject.FindWithTag("Player");
            if (tPlayer != null)
            {
                tFollowTarget = tPlayer.transform;
                vcam.LookAt = tFollowTarget;
                vcam.Follow = tFollowTarget;
            }
        }
    }
}

Much thanks to you Greg!

4 Likes

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!

5 Likes

@duanegra works like a charm!

I cannot use var

CinemachineVirtualCamera vcam = GetComponent<CinemachineVirtualCamera>();

2 Likes

my
public CinemachineVirtualCamera vcam;
line Gets An error CS0246 pls help

@ShonySion Do you have using Cinemachine; at the top?

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.

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??

It should just work.
Can you show the code?

1 Like