Search code examples
c#unity-game-enginecinemachine

Is there a ways for cinemachine to retarget player after it is destroyed and instantiated as a clone?


I am working on a 2D platformer and I am using cinemachine to follow my player.
When a player drops off a platform under -20 y, the player is destroyed and instantiated as a clone to the spawn point as expected, but the camera is not following, as the original player is destroyed: it says missing on the "Follow" Slot.
Is there any way to solve it? I prefer using Destroy and Instantiate as respawning instead of teleporting the original player to the respawn point.

This is the respawn script (GameMaster)

public class GameMaster : MonoBehaviour
{

    public static GameMaster gm;



    void Start()
    {
        if (gm == null)
        {
            gm = GameObject.FindGameObjectWithTag("GM").GetComponent<GameMaster>();
        }
    }
    public Transform playerPrefab, spawnPoint;
    public int spawnDelay = 2;

    public void RespawnPlayer() {
        //yield return new WaitForSeconds(spawnDelay);

        Instantiate(playerPrefab, spawnPoint.position, spawnPoint.rotation);
        Debug.Log("ADD SPAWN PARITCAL");
    }

    public static void Killplayer(Player player) {
        Destroy(player.gameObject);
        gm.RespawnPlayer();
    }
}

here is the player script if it is needed

public class Player : MonoBehaviour
{
    [System.Serializable]
    public class PlayerStats
    {
        public int Health = 100;

    }
    public PlayerStats playerStats = new PlayerStats();
    public int FallBoundary = -20;
    void FixedUpdate()
    {
        if (transform.position.y <= FallBoundary)
        {
            DamagePlayer(1000);
        }
    }

    public void DamagePlayer(int damage) {
        playerStats.Health -= damage;
        if (playerStats.Health<=0)
        {
            Debug.Log("Kill Player");
            GameMaster.Killplayer(this);
        }
    }
}

Solution

  • You can cache the cinemachine inside your start method and then assign to follow the player at respawn.

    Your code will become

    using Cinemachine;
    
    public class GameMaster : MonoBehaviour
    {
        public static GameMaster gm;
        public CinemachineVirtualCamera myCinemachine;
    
    
        void Start()
        {
            if (gm == null)
            {
                gm = GameObject.FindGameObjectWithTag("GM").GetComponent<GameMaster>();
            }
    
            myCinemachine = GetComponent<CinemachineVirtualCamera>();
        }
        public Transform playerPrefab, spawnPoint;
        public int spawnDelay = 2;
    
        public void RespawnPlayer() {
            //yield return new WaitForSeconds(spawnDelay);
    
            var newPlayer = Instantiate(playerPrefab, spawnPoint.position, spawnPoint.rotation);
            Debug.Log("ADD SPAWN PARITCAL");
    
            myCinemachine.m_Follow = newPlayer;
        }
    
        public static void Killplayer(Player player) {
            Destroy(player.gameObject);
            gm.RespawnPlayer();
        }
    }