using UnityEngine;
namespace Unity.Cinemachine.Samples
{
///
/// This class inherits CinemachineCameraManagerBase, which is a convenient base class for
/// making complex cameras by transitioning between a number of worker cameras, depending
/// on some arbitrary game state.
///
/// In this case, we monitor the player's facing direction and motion, and select a camera
/// with the appropriate settings. CinemachineCameraManagerBase takes care of handling the blends.
///
[ExecuteAlways]
public class PlatformerCamera2D : CinemachineCameraManagerBase
{
public enum PlayerState
{
Right,
Left,
FallingRight,
FallingLeft
}
[Space]
public float FallingSpeedThreshold = 0.1f;
// The cameras in these fields must be GameObject children of the manager camera.
[Header("State Cameras")]
[ChildCameraProperty] public CinemachineVirtualCameraBase RightCamera;
[ChildCameraProperty] public CinemachineVirtualCameraBase LeftCamera;
[ChildCameraProperty] public CinemachineVirtualCameraBase FallingRightCamera;
[ChildCameraProperty] public CinemachineVirtualCameraBase FallingLeftCamera;
Rigidbody2D m_Player;
SimplePlayerAnimator m_PlayerAnimator;
protected override void OnEnable()
{
base.OnEnable();
var target = DefaultTarget.Enabled ? DefaultTarget.Target.TrackingTarget : null;
if (target != null)
{
target.TryGetComponent(out m_Player);
m_PlayerAnimator = target.GetComponentInChildren();
}
if (m_Player == null)
Debug.LogError("PlatformerCamera2D: Default target must be set to Player with a Rigidbody2D");
}
PlayerState GetPlayerState()
{
bool isLeft = false;
bool isFalling = false;
if (m_Player != null)
{
if (m_PlayerAnimator != null)
isLeft = Mathf.Abs(m_PlayerAnimator.transform.rotation.eulerAngles.y) > 90;
isFalling = m_Player.velocity.y < -FallingSpeedThreshold;
}
if (isFalling)
return isLeft ? PlayerState.FallingLeft : PlayerState.FallingRight;
return isLeft ? PlayerState.Left : PlayerState.Right;
}
///
/// Choose the appropriate child camera depending on player state.
///
protected override CinemachineVirtualCameraBase ChooseCurrentCamera(Vector3 worldUp, float deltaTime)
{
return GetPlayerState() switch
{
PlayerState.Left => LeftCamera,
PlayerState.FallingRight => FallingRightCamera,
PlayerState.FallingLeft => FallingLeftCamera,
_ => RightCamera,
};
}
}
}