在上一节我们创建了一个动作调度器的脚本,动作调度器的目的主要是为了减少脚本之间的依赖,避免在移动的脚本中编写过多的逻辑,所以使用接口让动作调度器通关一个Cancel的方法来处理移动和战斗的逻辑
创建接口 IAction,同时Mover和Fighter脚本中进行修改,在动作调度器处理逻辑
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- namespace RPG.Core
- {
- public interface IAction
- {
- void Cancel();
- }
- }
复制代码
ActionScheduler
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- namespace RPG.Core
- {
- public class ActionScheduler : MonoBehaviour
- {
- IAction currentAction;
- public void StartAction(IAction action)
- {
- if (currentAction == action) return;//如果新操作与当前操作相同,则不执行任何操作
- if (currentAction != null)//如果有新的操作,请打印取消消息
- {
- currentAction.Cancel();
- }
-
- currentAction = action;//将新操作设置为当前操作
- }
- }
- }
复制代码
Mover
- using RPG.Core;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.AI;
- using UnityEngine.UI;
-
- //角色的移动
- namespace RPG.Movement
- {
-
- public class Mover : MonoBehaviour,IAction
- {
-
- private NavMeshAgent navMeshAgent;
-
- Animator animator;
-
- private void Start()
- {
- animator = GetComponent<Animator>();
- navMeshAgent = GetComponent<NavMeshAgent>();
-
- }
-
- private void Update()
- {
-
- UpdateAnimator();
- }
-
- /// <summary>
- /// 开始移动行为
- /// </summary>
- /// <param name="destination">移动的位置</param>
- public void StartMoveAction(Vector3 destination)
- {
- GetComponent<ActionScheduler>().StartAction(this);
-
- MoveTo(destination);
- }
-
- /// <summary>
- /// 寻路移动到射线检测点
- /// </summary>
- /// <param name="hit"></param>
- public void MoveTo(Vector3 destination)
- {
- navMeshAgent.destination = destination;//获取寻路目的地 = 射线碰撞的点
- navMeshAgent.isStopped = false;
- }
-
- /// <summary>
- /// 停止寻路
- /// </summary>
- public void Cancel()
- {
- navMeshAgent.isStopped = true;
- }
-
-
-
- /// <summary>
- /// 动画更新
- /// </summary>
- private void UpdateAnimator()
- {
- Vector3 velocity = navMeshAgent.velocity;//创建寻路速度
- Vector3 localVelocity = transform.InverseTransformDirection(velocity);// 将世界向前变换到本地空间:
- float speed = localVelocity.z;
-
- animator.SetFloat("forwardSpeed", speed);
- }
- }
- }
复制代码
Fighter
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using RPG.Movement;
- using RPG.Core;
-
-
- namespace RPG.Combat
- {
- //攻击
- public class Fighter : MonoBehaviour,IAction
- {
- [SerializeField] float weaponRange = 2f;//武器范围
-
- Transform target;
-
- private Mover mover;
- private bool isInRange;
-
- private void Start()
- {
- mover = GetComponent<Mover>();
- }
-
- private void Update()
- {
- if (target == null) return;
-
-
- if (target != null && !GetIsInRange())//目标不为空并且在距离范围内
- {
- mover.MoveTo(target.position);
- }
- else
- {
- mover.Cancel();
- }
- }
-
- private bool GetIsInRange()
- {
- return Vector3.Distance(transform.position, target.position) < weaponRange;//创建玩家距离和敌人距离是否小于2
- }
-
- public void Attack(CombatTarget combatTarget)
- {
- GetComponent<ActionScheduler>().StartAction(this);
- target = combatTarget.transform;
-
- }
-
- public void Cancel()
- {
- target = null;
- }
- }
- }
复制代码
|