面向对象之使用事件系统控制人物

面向对象:使用事件系统控制人物

对象图

控制流程:

PlayerInput类用作输入,发生事件,作为控制端。

PlayerInputController类提供监听者。

PlayerMotor提供角色的功能。

PlayerStatus提供角色的一切信息。

PlayerAnimationPrams提供所有动画状态机的参数。

1.在PlayerInputController中注册监听者到PlayerInput控制器中的事件。

2.获取到输入后监听者响应事件,调用函数OnInputMove()。函数内部使用PlayerMotor提供的角色功能,以及使用PlayerStatus所提供的参数来播放动画。

好处:可扩展性高,耦合度低。

可更改处:可以将移动的方法,攻击的方法等再单独做类,组合在PlayerMotor中。

PlayerInput:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

namespace ARPGDemo.Player{
    /// <summary>
    /// 用于获取玩家的输入,并基于事件进行操控
    /// </summary>
    public class PlayerInput : MonoBehaviour
    {
        #region Delegate
        //委托
        public delegate void MoveInputEventHandler(InputMove dir);
        public delegate void MoveInputEndEventHandler();
        #endregion

        #region Event
        //事件
        public static event MoveInputEventHandler On_AxisInput;
        public static event MoveInputEndEventHandler On_AxisInputEnd;
        #endregion

        #region Member
        private InputMove inputAxis;

        private enum MessageName { On_AxisInput,On_AxisInputEnd };
        #endregion

        #region Monobehaviour
        private void Start()
        {
            inputAxis = new InputMove { InputVector3 = Vector3.zero };
        }

        private void Update()
        {
            UpdateEvents();
        }

        private void CreatEvent(MessageName messageName)
        {
            switch(messageName)
            {
                case MessageName.On_AxisInput:
                    On_AxisInput(inputAxis);
                    break;
                case MessageName.On_AxisInputEnd:
                    On_AxisInputEnd();
                    break;
            }
        }

        private void UpdateEvents()
        {
            //获取输入
            GetInput();
            if (inputAxis.InputVector3.x != 0 || inputAxis.InputVector3.z != 0)
            {
                CreatEvent(MessageName.On_AxisInput);
            }
            else
            {
                CreatEvent(MessageName.On_AxisInputEnd);
            }
        }


        #endregion

        #region Method
        private void GetInput()
        {
            float hor = Input.GetAxis("Horizontal");
            float ver = Input.GetAxis("Vertical");
            inputAxis.InputVector3 = new Vector3(hor, 0, ver);
        }
        #endregion

    }
}

PlayerInputController:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace ARPGDemo.Player
{
    /// <summary>
    /// 控制角色
    /// </summary>
    public class PlayerInputController : MonoBehaviour
    {
        private PlayerMotor plMotor;
        private Animator animator;
        private PlayerStatus status;

        private void Start()
        {
            plMotor = GetComponent<PlayerMotor>();
            status = GetComponent<PlayerStatus>();
            animator = GetComponent<Animator>();
        }

        //绑定事件
        private void OnEnable()
        {
            PlayerInput.On_AxisInput += OnInputMove;
            PlayerInput.On_AxisInputEnd += OnInputMoveEnd;
        }

        private void OnDisable()
        {
            PlayerInput.On_AxisInput -= OnInputMove;
        }

        //每次事件发生都会被调用
        private void OnInputMove(InputMove move)
        {
            plMotor.Movement(move.InputVector3);
            animator.SetBool(status.parms.move,true);
        }

        private void OnInputMoveEnd()
        {
            animator.SetBool(status.parms.move,false);
        }
        
    }
}

PlayerMotor:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace ARPGDemo.Player
{
    /// <summary>
    /// 玩家的驱动器,提供所有的功能
    /// </summary>
    public class PlayerMotor : MonoBehaviour
    {
        [SerializeField,Tooltip("移动速度")]
        private float moveSpeed = 5f;
        [SerializeField,Tooltip("转动速度")]
        private float rotateSpeed = 10f;

        private CharacterController chController;
        
        private void Start()
        {
            chController = GetComponent<CharacterController>();
        }

        private void LookAtTarget(Vector3 directon)
        {
            Quaternion dir = Quaternion.LookRotation(directon);
            transform.rotation = Quaternion.Lerp(transform.rotation, dir, rotateSpeed * Time.deltaTime * rotateSpeed);
        }

        public void Movement(Vector3 directon)
        {
            LookAtTarget(directon);
     
            Vector3 forward = directon.normalized;
            //transform.Translate(forward * Time.deltaTime * moveSpeed, Space.World);
            //让角色不会浮空
            forward.y = -1;
            chController.Move(forward * Time.deltaTime * moveSpeed);
        }
    }
}

PlayerStatus:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace ARPGDemo.Player
{
    /// <summary>
    /// 用于获取玩家当前的信息
    /// </summary>
    public class PlayerStatus : MonoBehaviour
    {
        public PlayerAnimationParms parms;

        private void Start()
        {
            parms = new PlayerAnimationParms();
        }
    }
}

PlayerAnimationPrams:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace ARPGDemo.Player
{
    /// <summary>
    /// 提供所有的动画参数
    /// </summary>
    [System.Serializable]
    public class PlayerAnimationParms
    {
        public string move = "IsMove";
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值