I had considered putting the respawn logic into the Fade
script but that seemed to be way too dirty to me…
I was thinking it might be part of the PlayerController
but then it would have to be a static
method in order not to get into trouble with the lingering Destroy()
operation which OnDestroy()
only intercepts but won’t avoid. (Unless I got that bit completely wrong).
So instead I made myself a Respawner
script to be placed on the spawning zone, and defined an OnPlayerDied
action in the PlayerController
.
So in the PlayerController
:
private void OnDestroy()
{
OnPlayerDied?.Invoke();
}
The Respawner
pretty much takes care of everything:
using UnityEngine;
using Cinemachine;
using System;
public class PlayerSpawner : MonoBehaviour
{
public static Action OnPlayerRespawn;
[SerializeField] private GameObject _playerPrefab;
[SerializeField] private float _respawnTime = 1f;
private Fade _fade;
private CinemachineVirtualCamera _virtualCamera;
private Transform _cameraPosition;
private void Awake()
{
_virtualCamera = FindFirstObjectByType<CinemachineVirtualCamera>();
_fade = FindFirstObjectByType<Fade>();
}
private void OnEnable()
{
PlayerController.OnPlayerDied += PlayerDiedFadeToBlack;
PlayerController.OnPlayerDied += PlayerDiedRespawn;
OnPlayerRespawn += RespawnPlayer;
}
private void OnDisable()
{
PlayerController.OnPlayerDied -= PlayerDiedFadeToBlack;
PlayerController.OnPlayerDied -= PlayerDiedRespawn;
OnPlayerRespawn -= RespawnPlayer;
}
private void PlayerDiedFadeToBlack()
{
_fade.FadeIn();
}
private void PlayerDiedRespawn()
{
Utils.RunAfterDelay(this, _respawnTime, OnPlayerRespawn);
}
private void RespawnPlayer()
{
GameObject newPlayerInstance = Instantiate(_playerPrefab, transform.position, Quaternion.identity);
PlayerController.Instance = newPlayerInstance.GetComponent<PlayerController>();
_virtualCamera.Follow = newPlayerInstance.transform;
}
}
And in Fade
I would subscribe to the Respawn
event:
private void OnEnable()
{
PlayerSpawner.OnPlayerRespawn += FadeOut;
}
private void OnDisable()
{
PlayerSpawner.OnPlayerRespawn -= FadeOut;
}
And now that there is an event available for the respawning, one could add all kinds of fancy things to it, like a juicy SFX, for example…