using System; using DG.Tweening; using SickscoreGames.HUDNavigationSystem; using UniRx; using UnityEngine; using UnityEngine.UI; using SLSFramework.General; using Ease = DG.Tweening.Ease; namespace Cielonos.MainGame.Characters { public partial class LockTargetSubmodule : SubmoduleBase { private Player player => owner.player; private PlayerViewSubcontroller viewSc => owner; private PlayerInputSubcontroller inputSc => player.inputSc; private HUDNavigationSystem navigationSystem => HUDNavigationSystem.Instance; private HUDNavigationCanvas navigationCanvas => HUDNavigationCanvas.Instance; /// /// 通常ACT类武器锁定目标时自动旋转摄像机,即使用LockTargetCamera /// TPS类远程武器不自动旋转,仅在目标上显示锁定标记,不切换摄像机 /// public bool isAutoRotate; /// /// 是否正在锁定目标 /// public bool isLocking; /// /// 是否正在使用锁定目标摄像机 /// public bool isUsingLockTargetCamera => isLocking && isAutoRotate; public bool isDuringSwitch; public CharacterBase lockTarget; public Transform targetPoint; private Tweener iconTween; public LockTargetSubmodule(PlayerViewSubcontroller owner) : base(owner) { isLocking = false; isAutoRotate = false; isDuringSwitch = false; lockTarget = null; targetPoint = null; } public void Update() { if (isUsingLockTargetCamera && !isDuringSwitch) { viewSc.cameraRoot.LookAt(targetPoint); float distance = (targetPoint.position - viewSc.cameraRoot.transform.position).Flatten().magnitude; if (isUsingLockTargetCamera && distance < 1f) { UnlockTarget(); } } } } public partial class LockTargetSubmodule { public void SwitchLockState() { if (isLocking) { UnlockTarget(); } else { LockTarget(true); } } public void LockTarget(bool isAutoRotate) { if(isDuringSwitch) return; CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(50f); if (target != null) { this.isLocking = true; this.isAutoRotate = isAutoRotate; this.lockTarget = target; this.isDuringSwitch = true; if (isAutoRotate) { targetPoint = target.bodyPartsSc.cameraLockingPoint ?? target.bodyPartsSc.staticCenterPoint; viewSc.currentCamera = viewSc.lockingTargetCamera; viewSc.lockingTargetCamera.LookAt = targetPoint; viewSc.stateDrivenCamera.GetComponent().SetBool("isLockTarget", true); viewSc.cameraRoot.DOLookAt(targetPoint.position, 0.5f) .SetEase(Ease.InOutSine) .OnComplete(() => { isDuringSwitch = false; }) .Play(); } else { Observable.Timer(TimeSpan.FromSeconds(0.5f)).First().Subscribe(_ => { isDuringSwitch = false; }); } lockTarget.navigationElement.showIndicator = true; Image icon = lockTarget.navigationElement.Indicator.OnscreenIcon; iconTween?.Kill(true); iconTween = icon.GetComponent().DOScale(1f, 0.5f).From(0f).SetEase(Ease.OutQuart).Play(); } } public void UnlockTarget() { if(isDuringSwitch) return; if (isAutoRotate) { viewSc.cameraRotationSm.SyncRotationWithCamera(); viewSc.stateDrivenCamera.GetComponent().SetBool("isLockTarget", false); viewSc.stateDrivenCamera.InternalUpdateCameraState(Vector3.up, Time.deltaTime); viewSc.currentCamera = viewSc.freeLookCamera; } this.isLocking = false; this.isAutoRotate = false; Image icon = lockTarget.navigationElement.Indicator.OnscreenIcon; iconTween?.Kill(true); iconTween = icon.GetComponent().DOScale(0f, 0.5f).SetEase(Ease.OutQuart).OnComplete(() => { lockTarget.navigationElement.showIndicator = false; this.lockTarget = null; this.targetPoint = null; this.isDuringSwitch = false; }).Play(); } } }