using UnityEngine;
namespace Unity.Cinemachine.Samples
{
///
/// When there is an active ThirdPersonFollow camera with noise cancellation,
/// the position of this object is the aim target for the ThirdPersonAim camera.
///
public class AimTargetManager : MonoBehaviour
{
[Tooltip("This canvas will be enabled when there is a 3rdPersoAim camera active")]
public Canvas ReticleCanvas;
[Tooltip("If non-null, this target will pe positioned on the screen over the actual aim target")]
public RectTransform AimTargetIndicator;
bool m_HaveAimTarget;
// We add a CameraUpdatedEvent listener so that we are guaranteed to update after the
// Brain has positioned the camera
void OnEnable() => CinemachineCore.CameraUpdatedEvent.AddListener(SetAimTarget);
void OnDisable() => CinemachineCore.CameraUpdatedEvent.RemoveListener(SetAimTarget);
// This is called after the Brain has positioned the camera. If the camera has a
// ThirdPersonAim component with noise cancellation, then we set the aim target
// position to be precisely what the camera is indicating onscreen.
// Otherwise, we disable the reticle and the aim target indicator.
void SetAimTarget(CinemachineBrain brain)
{
m_HaveAimTarget = false;
if (brain == null || brain.OutputCamera == null)
CinemachineCore.CameraUpdatedEvent.RemoveListener(SetAimTarget);
else
{
CinemachineCamera liveCam;
if (brain.ActiveVirtualCamera is CinemachineCameraManagerBase managerCam)
liveCam = managerCam.LiveChild as CinemachineCamera;
else
liveCam = brain.ActiveVirtualCamera as CinemachineCamera;
if (liveCam != null)
{
if (liveCam.TryGetComponent(out var aim) && aim.enabled)
{
// Set the worldspace aim target position so that we can know what gets hit
m_HaveAimTarget = aim.NoiseCancellation;
transform.position = aim.AimTarget;
// Set the screen-space hit target indicator position
if (AimTargetIndicator != null)
AimTargetIndicator.position = brain.OutputCamera.WorldToScreenPoint(transform.position);
}
}
}
if (ReticleCanvas != null)
ReticleCanvas.enabled = m_HaveAimTarget;
}
///
/// Called by the player's shooting object to get the aim direction override, in case
/// there is an active ThirdPersonFollow camera with noise cancellation.
///
/// Where the firing will come from.
/// The intended firing direction.
/// The direction in which to fire
public Vector3 GetAimDirection(Vector3 firingOrigin, Vector3 firingDirection)
{
if (m_HaveAimTarget)
{
var dir = transform.position - firingOrigin;
var len = dir.magnitude;
if (len > 0.0001f)
return dir / len;
}
return firingDirection;
}
}
}