[Unity] ACT 战斗系统学习 4:重构前的第三人称控制器

本文介绍了作者在Unity中开发ACT战斗系统时,如何将原本集中的第三人称控制器进行重构,以提高代码可维护性和策划可配置性。通过采用ScriptableObject的思想,计划将逻辑拆分到多个独立的组件中,包括ThirdPersonActionController、ThirdPersonAnimationController等,以实现更清晰的职责划分。
摘要由CSDN通过智能技术生成

重构前,我的控制器是这样子

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 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值