157 lines
3.2 KiB
C#
157 lines
3.2 KiB
C#
using UnityEngine;
|
|
|
|
namespace Beyond
|
|
{
|
|
/// <summary>
|
|
/// Overrides camera state while locked-on to specific targets.
|
|
/// </summary>
|
|
[RequireComponent(typeof(bLockOn))]
|
|
public sealed class LockOnCameraStateOverride : MonoBehaviour
|
|
{
|
|
private bLockOn _lockOn;
|
|
private bThirdPersonInput _input;
|
|
|
|
private bool _isOverriding;
|
|
private string _overrideState;
|
|
private Transform _overrideTarget;
|
|
|
|
private struct CameraStateSnapshot
|
|
{
|
|
public bool changeCameraState;
|
|
public string customCameraState;
|
|
public bool smoothCameraState;
|
|
}
|
|
|
|
private CameraStateSnapshot _previousState;
|
|
|
|
private void Awake()
|
|
{
|
|
_lockOn = GetComponent<bLockOn>();
|
|
_input = GetComponent<bThirdPersonInput>();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (_lockOn != null)
|
|
{
|
|
_lockOn.onLockOnTarget.AddListener(OnLockOn);
|
|
_lockOn.onUnLockOnTarget.AddListener(OnUnlockOn);
|
|
}
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (_lockOn != null)
|
|
{
|
|
_lockOn.onLockOnTarget.RemoveListener(OnLockOn);
|
|
_lockOn.onUnLockOnTarget.RemoveListener(OnUnlockOn);
|
|
}
|
|
|
|
StopOverrideIfNeeded();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!_isOverriding)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_overrideTarget == null)
|
|
{
|
|
StopOverrideIfNeeded();
|
|
return;
|
|
}
|
|
|
|
var targetOverride = _overrideTarget.GetComponent<LockOnCameraStateOverrideTarget>();
|
|
if (targetOverride == null)
|
|
{
|
|
StopOverrideIfNeeded();
|
|
return;
|
|
}
|
|
|
|
if (!IsWithinDistance(_overrideTarget, targetOverride.maxDistance))
|
|
{
|
|
StopOverrideIfNeeded();
|
|
}
|
|
}
|
|
|
|
private void OnLockOn(Transform target)
|
|
{
|
|
if (target == null || _input == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var targetOverride = target.GetComponent<LockOnCameraStateOverrideTarget>();
|
|
if (targetOverride == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!IsWithinDistance(target, targetOverride.maxDistance))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_previousState = new CameraStateSnapshot
|
|
{
|
|
changeCameraState = _input.changeCameraState,
|
|
customCameraState = _input.customCameraState,
|
|
smoothCameraState = _input.smoothCameraState
|
|
};
|
|
|
|
_overrideState = targetOverride.cameraStateName;
|
|
_overrideTarget = target;
|
|
|
|
_input.ChangeCameraStateWithLerp(_overrideState);
|
|
_isOverriding = true;
|
|
}
|
|
|
|
private void OnUnlockOn(Transform target)
|
|
{
|
|
StopOverrideIfNeeded();
|
|
}
|
|
|
|
private void StopOverrideIfNeeded()
|
|
{
|
|
if (!_isOverriding || _input == null)
|
|
{
|
|
_isOverriding = false;
|
|
_overrideTarget = null;
|
|
return;
|
|
}
|
|
|
|
// Only restore if we're still on the override state.
|
|
if (_input.changeCameraState && _input.customCameraState == _overrideState)
|
|
{
|
|
if (_previousState.changeCameraState)
|
|
{
|
|
_input.changeCameraState = true;
|
|
_input.customCameraState = _previousState.customCameraState;
|
|
_input.smoothCameraState = _previousState.smoothCameraState;
|
|
}
|
|
else
|
|
{
|
|
_input.ResetCameraState();
|
|
}
|
|
}
|
|
|
|
_isOverriding = false;
|
|
_overrideTarget = null;
|
|
_overrideState = null;
|
|
}
|
|
|
|
private bool IsWithinDistance(Transform target, float maxDistance)
|
|
{
|
|
if (maxDistance <= 0f)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
var delta = target.position - transform.position;
|
|
return delta.sqrMagnitude <= maxDistance * maxDistance;
|
|
}
|
|
}
|
|
}
|