面向对象:使用事件系统控制人物
控制流程:
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";
}
}