Die

This page is part of the 3D Game Kit sample.

When the player gets hit too many times, they die and Respawn at the last checkpoint they passed:

Mecanim

Dying works basically the same as Flinching except that it's triggered by the Damageable.OnDeath event:

The PlayerController.OnReceiveMessage method explained on the Flinch page includes a case for death messages:

// PlayerController.cs:
public void OnReceiveMessage(MessageType type, object sender, object data)
{
    switch (type)
    {
        case MessageType.DAMAGED:
            {
                Damageable.DamageMessage damageData = (Damageable.DamageMessage)data;
                Damaged(damageData);
            }
            break;
        case MessageType.DEAD:
            {
                Damageable.DamageMessage damageData = (Damageable.DamageMessage)data;
                Die(damageData);
            }
            break;
    }
}

readonly int m_HashDeath = Animator.StringToHash("Death");

public void Die(Damageable.DamageMessage damageMessage)
{
    m_Animator.SetTrigger(m_HashDeath);
    m_ForwardSpeed = 0f;
    m_VerticalSpeed = 0f;
    m_Respawning = true;
    m_Damageable.isInvulnerable = true;
}
  1. The transition from Any State to EllenDeath occurs after the "Death" trigger parameter is set.
  2. When that animation finishes it transitions into the BeginRespawn state.
  3. That state has a EllenRespawnEffect script attached to it.
  4. That script's OnStateEnter method calls PlayerController.Respawn.
  5. Respawn calls StartCoroutine(RespawnRoutine()).
  6. RespawnRoutine does several things:
readonly int m_HashRespawn = Animator.StringToHash("Respawn");

protected IEnumerator RespawnRoutine()
{
    // Wait for the animator to be transitioning from the EllenDeath state.
    while (m_CurrentStateInfo.shortNameHash != m_HashEllenDeath || !m_IsAnimatorTransitioning)
    {
        yield return null;
    }

    // Wait for the screen to fade out.
    yield return StartCoroutine(ScreenFader.FadeSceneOut());
    while (ScreenFader.IsFading)
    {
        yield return null;
    }

    // Enable spawning.
    EllenSpawn spawn = GetComponentInChildren<EllenSpawn>();
    spawn.enabled = true;

    // If there is a checkpoint, move Ellen to it.
    if (m_CurrentCheckpoint != null)
    {
        transform.position = m_CurrentCheckpoint.transform.position;
        transform.rotation = m_CurrentCheckpoint.transform.rotation;
    }
    else
    {
        Debug.LogError("There is no Checkpoint set, there should always be a checkpoint set. Did you add acheckpoint at the spawn?");
    }

    // Set the Respawn parameter of the animator.
    m_Animator.SetTrigger(m_HashRespawn);

    // Start the respawn graphic effects.
    spawn.StartEffect();

    // Wait for the screen to fade in.
    // Currently it is not important to yield here but should some changes occur that require waiting until arespawn has finished this will be required.
    yield return StartCoroutine(ScreenFader.FadeSceneIn());

    m_Damageable.ResetDamage();
}
  1. The "Respawn" trigger causes the Animator Controller to transition to the Respawn state which plays the actual animation on the character (while the screen is fading back in).

Animancer

The DieState script handles most of the same behaviour as the Mecanim character:

using Animancer;
using Animancer.FSM;
using UnityEngine;
using UnityEngine.Events;

public class DieState : CharacterState
{
    [SerializeField] private ClipTransition _Animation;
    [SerializeField] private UnityEvent _OnEnterState;
    [SerializeField] private UnityEvent _OnExitState;

    protected virtual void Awake()
    {
        _Animation.Events.OnEnd = Character.Respawn.ForceEnterState;
    }

    public void OnDeath()
    {
        Character.StateMachine.ForceSetState(this);
    }

    protected virtual void OnEnable()
    {
        Character.Animancer.Play(_Animation);
        Character.Parameters.ForwardSpeed = 0;
        _OnEnterState.Invoke();
    }

    protected virtual void OnDisable()
    {
        _OnExitState.Invoke();
    }

    public override bool FullMovementControl => false;

    public override bool CanExitState => false;
}

Unfortunately, the Script Referencing issue prevents it from using the ScreenFader script because its methods are static so Unity Events can't call them. UltEvents could call them, but we don't want this sample to require another plugin.

It has a public OnDeath method for the Damageable to call just like the Flinch state as well as _OnEnterState and _OnExitState events which make the player invulnerable just like the Respawn state.

Those events could have been set up as Animancer Events at the start and end of the _Animation Transition, but it's possible that something could interrupt this state (such as forcibly restarting the level) and we wouldn't want to leave the player invulnerable if that happens.