Camera Lock On override

This commit is contained in:
SzymonMis
2026-02-19 21:34:50 +01:00
parent e88179d52c
commit 4c0affacc9
5 changed files with 188 additions and 1 deletions

View File

@@ -0,0 +1,16 @@
using UnityEngine;
namespace Beyond
{
/// <summary>
/// Marks a target that should override the lock-on camera state when close.
/// </summary>
public sealed class LockOnCameraStateOverrideTarget : MonoBehaviour
{
[Tooltip("Camera state to use while locked on this target.")]
public string cameraStateName = "LockOnBig";
[Tooltip("Max distance to apply the override. Set per enemy as needed.")]
public float maxDistance = 6f;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d26a247418ec4c849b93fb72ca6279e0

View File

@@ -0,0 +1,156 @@
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;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 86ca4effe1f4a4b4dbd243af2bc93a29

View File

@@ -12,9 +12,20 @@ namespace Beyond
{
if (controller.currentTarget.transform == null) return;
var summoner = controller.gameObject.GetComponent<DemonBoss.Summoner.SummonerAI>();
if (summoner != null && !summoner.ShouldEngageMelee())
{
controller.Stop();
return;
}
if (controller.targetDistance <= controller.attackDistance && !controller.isBlocking)
{
controller.Stop();
if (summoner != null)
{
summoner.NotifyMeleeAttack();
}
controller.Attack();
}
else if (!controller.animatorStateInfos.HasAnyTag("Attack", "LockMovement", "CustomAction"))