重构前,我的控制器是这样子
Assets/MeowACT/Scripts/ThirdPerson/ThirdPerson.cs
// ----------------------------------------------
// 作者: 廉价喵
// 创建于: 25/03/2022 23:35
// 最后一次修改于: 28/03/2022 20:03
// 版权所有: CheapMiaoStudio
// 描述:
// ----------------------------------------------
using Cinemachine;
using UnityEngine;
namespace MeowACT
{
/// <summary>
/// 第三人称主角
/// </summary>
public class ThirdPerson : MonoBehaviour
{
// Perfab 自带组件
public CharacterController CharacterCtr;
public Animator Anim;
public MeowACTInputController Input;
public GameObject CMCameraFollowTarget;
public GameObject PlayerFollowCamera;
public Camera MainCamera;
public GameObject BattleGUI;
// 控制组件
public ThirdPersonAttributeManager AttributeManager;
public ThirdPersonEventManager EventManager;
private ThirdPersonActionController actionController;
private ThirdPersonLocomotionController locomotionController;
private ThirdPersonAnimationController animationController;
private ThirdPersonBattleController battleController;
private ThirdPersonUIController uiController;
private void Awake()
{
// 初始化 Perfab 自带组件
CharacterCtr = GetComponent<CharacterController>();
Anim = GetComponent<Animator>();
Input = gameObject.AddComponent<MeowACTInputController>();
CMCameraFollowTarget = transform.Find("PlayerCameraRoot").gameObject;
PlayerFollowCamera = GameObject.Find("PlayerFollowCamera");
PlayerFollowCamera.GetComponent<CinemachineVirtualCamera>().Follow = CMCameraFollowTarget.transform;
MainCamera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>();
BattleGUI = transform.Find("BattleGUI").gameObject;
BattleGUI.GetComponent<Canvas>().worldCamera = MainCamera;
BattleGUI.GetComponent<Canvas>().planeDistance = 1;
// 初始化控制组件
AttributeManager = new ThirdPersonAttributeManager(this);
EventManager = new ThirdPersonEventManager(this);
actionController = new ThirdPersonActionController(this);
locomotionController = new ThirdPersonLocomotionController(this);
animationController = new ThirdPersonAnimationController(this);
battleController = new ThirdPersonBattleController(this);
uiController = new ThirdPersonUIController(this);
// 初始化动画状态机参数
animationController.AssignAnimationIDs();
// 初始化属性
AttributeManager.Init();
}
protected void Update()
{
// 行为
actionController.TryAction();
// 运动
locomotionController.ApplyGravity();
locomotionController.GroundedCheck();
locomotionController.Move();
locomotionController.RotateToMoveDir();
// 动画
animationController.SetAnimatorValue();
}
protected void LateUpdate()
{
// 运动
locomotionController.CameraRotate();
}
private void OnControllerColliderHit(ControllerColliderHit hit)
{
// 运动
if (AttributeManager.canPush) PhysicsUtility.PushRigidBodies(hit, AttributeManager.pushLayers, AttributeManager.strength);
}
/// <summary>
/// 由动画触发的动画事件,还需要在 mgr 中触发事件:尝试造成伤害
/// </summary>
public void OnTryDoDamageAnimEvent()
{
EventManager.Fire("TryDoDamageEvent", null);
Debug.Log("OnTryDoDamageAnimEvent");
}
/// <summary>
/// 由动画触发的动画事件,还需要在行为控制器中触发事件:结束近战攻击
/// </summary>
public void OnEndMeleeAttackAnimEvent()
{
actionController.FireEndMeleeAttackEvent();
Debug.Log("OnEndMeleeAttackAnimEvent");
}
}
}
Assets/MeowACT/Scripts/ThirdPerson/ThirdPersonActionController.cs
// ----------------------------------------------
// 作者: 廉价喵
// 创建于: 26/03/2022 2:15
// 最后一次修改于: 28/03/2022 15:28
// 版权所有: CheapMiaoStudio
// 描述:
// ----------------------------------------------
using UnityEngine;
namespace MeowACT
{
/// <summary>
/// 第三人称行为控制器
/// </summary>
public class ThirdPersonActionController
{
/// <summary>
/// 第三人称行为控制器的主人
/// </summary>
public ThirdPerson Owner;
/// <summary>
/// 冲刺的冷却时间
/// </summary>
private float sprintTimeout = 0.5f;
/// <summary>
/// 攻击的冷却时间
/// </summary>
private float attackTimeout = 1f;
/// <summary>
/// 第三人称行为控制器的构造函数
/// </summary>
/// <param name="owner">第三人称行为控制器的主人</param>
public ThirdPersonActionController(ThirdPerson owner)
{
Owner = owner;
}
public void TryAction()
{
if(TrySprint())
return;
TryMeleeAttack();
}
private bool TrySprint()
{
if (Owner.Input.Sprint && !Owner.AttributeManager.IsSprinting && !Owner.AttributeManager.IsFreezingMove)
{
FireBeginSprintEvent();
var cotimer = TimerSystemSingleton.SingleInstance.CreateCoTimer(0,
delegate(object[] args) {
FireAfterBeginSprintEvent(); });
cotimer.Start();
var timer = TimerSystemSingleton.SingleInstance.CreateTimer(sprintTimeout, false,
delegate(object[] args) {
FireEndSprintEvent(); });
timer.Start();
return true;
}
return false;
}
private bool TryMeleeAttack()
{
if (Owner.Input.Attack && !Owner.AttributeManager.IsMeleeAttacking)
{
FireBeginMeleeAttackEvent();
return true;
}
return false;
}
private void FireBeginSprintEvent()
{
Owner.AttributeManager.IsSprinting = true;
Owner.AttributeManager.IsSprintBegin = true;
// 开始冲刺进入霸体
Owner.AttributeManager.IsSuperArmor = true;
// 开始冲刺消耗体力
Owner.AttributeManager.NRG -= Owner.AttributeManager.SprintCost;
Owner.EventManager.Fire("BeginSprintEvent", null);
}
private void FireAfterBeginSprintEvent()
{
Owner.AttributeManager.IsSprintBegin = false;
Owner.EventManager.Fire("AfterBeginSprintEvent", null);
}
private void