Udemy-Unity制作类暗黑破坏神游戏记录-P28

2024-09-06
97看过
这套教程比较基础,在Udemy上评分很高,我觉得用作新人学习Unity非常合适,学习前提,最好是掌握一些基本C#编程。
P29章前主要是简单介绍了如何使用Unity自带的AI寻路烘焙,使用AI来制作角色的移动,相机的跟随,制作玩家的动画混合,并对动画进行更新。
玩家的移动主要通过射线检测碰撞,如果点击处没有寻路网格,玩家则不会前往,防止玩家走出世界之外。

还制作了攻击的基本逻辑和被攻击的敌人目标,点击敌人,角色会自动前往到敌人身边。
一些代码和教程有出入,自己做了一些修改,大致基本上一致。
以下是代码部分:
Mover

  1. using RPG.Combat;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.AI;
  6. using UnityEngine.UI;
  7. //角色的移动
  8. namespace RPG.Movement
  9. {
  10.     public class Mover : MonoBehaviour
  11.     {
  12.         private NavMeshAgent navMeshAgent;
  13.         private Fighter fighter;
  14.         Animator animator;
  15.         private void Start()
  16.         {
  17.             animator = GetComponent<Animator>();
  18.             navMeshAgent = GetComponent<NavMeshAgent>();
  19.             fighter = GetComponent<Fighter>();
  20.         }
  21.         private void Update()
  22.         {
  23.             UpdateAnimator();
  24.         }
  25.         /// <summary>
  26.         /// 开始移动行为
  27.         /// </summary>
  28.         /// <param name="destination">移动的位置</param>
  29.         public void StartMoveAction(Vector3 destination)
  30.         {
  31.             fighter.Cancel();
  32.             MoveTo(destination);
  33.         }
  34.         /// <summary>
  35.         /// 寻路移动到射线检测点
  36.         /// </summary>
  37.         /// <param name="hit"></param>
  38.         public void MoveTo(Vector3 destination)
  39.         {
  40.             navMeshAgent.destination = destination;//获取寻路目的地 = 射线碰撞的点
  41.             navMeshAgent.isStopped = false;
  42.         }
  43.         /// <summary>
  44.         /// 停止寻路
  45.         /// </summary>
  46.         public void Stop()
  47.         {
  48.             navMeshAgent.isStopped = true;
  49.         }
  50.         /// <summary>
  51.         /// 动画更新
  52.         /// </summary>
  53.         private void UpdateAnimator()
  54.         {
  55.             Vector3 velocity = navMeshAgent.velocity;//创建寻路速度
  56.             Vector3 localVelocity = transform.InverseTransformDirection(velocity);// 将世界向前变换到本地空间:
  57.             float speed = localVelocity.z;
  58.             
  59.             animator.SetFloat("forwardSpeed", speed);
  60.         }
  61.     }
  62. }
复制代码
PlayerController


  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using RPG.Movement;
  5. using RPG.Combat;
  6. //角色的控制
  7. namespace RPG.Control
  8. {
  9.    
  10.     public class PlayerController : MonoBehaviour
  11.     {
  12.         private Mover mover;
  13.         private void Start()
  14.         {
  15.             mover = GetComponent<Mover>();
  16.         }
  17.         private void Update()
  18.         {
  19.             if (InteractWithCombat()) return;
  20.             if (InteractWithMovement()) return;
  21.             
  22.         }
  23.         
  24.         // 战斗交互
  25.         private bool InteractWithCombat()
  26.         {
  27.             RaycastHit[] hits = Physics.RaycastAll(GetMouseRay());
  28.             foreach (RaycastHit hit in hits)
  29.             {
  30.                 CombatTarget target = hit.transform.GetComponent<CombatTarget>();//被射线击中的物体获取战斗目标组件
  31.                 if(target == null) continue;//为空则继续
  32.                 if(Input.GetMouseButtonDown(0))//按下左键
  33.                 {
  34.                     GetComponent<Fighter>().Attack(target);//攻击目标
  35.                 }
  36.                 return true;//射线找到目标
  37.             }
  38.             return false;//射线没有找到目标
  39.         }
  40.         // 移动和交互
  41.         private bool InteractWithMovement()
  42.         {
  43.             RaycastHit hit;//存储射线碰撞的信息
  44.             bool hasHit = Physics.Raycast(GetMouseRay(), out hit); //通过射线检测是否有接触到碰撞物体
  45.             if (hasHit)//如果有检测到
  46.             {
  47.                 if (Input.GetMouseButton(0))//如果按下鼠标左键
  48.                 {
  49.                     mover.StartMoveAction(hit.point);
  50.                     
  51.                 }
  52.                 return true;
  53.             }
  54.             return false;
  55.         }
  56.         
  57.         //创建射线
  58.         private static Ray GetMouseRay()
  59.         {
  60.             return Camera.main.ScreenPointToRay(Input.mousePosition);
  61.         }
  62.     }
  63. }
复制代码
Fighter


  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using RPG.Movement;
  5. namespace RPG.Combat
  6. {
  7.     //攻击
  8.     public class Fighter : MonoBehaviour
  9.     {
  10.         [SerializeField] float weaponRange = 2f;//武器范围
  11.         Transform target;
  12.         private Mover mover;
  13.         private bool isInRange;
  14.         private void Start()
  15.         {
  16.             mover = GetComponent<Mover>();
  17.         }
  18.         private void Update()
  19.         {
  20.             if (target == null) return;
  21.             if (target != null && !GetIsInRange())//目标不为空并且在距离范围内
  22.             {
  23.                 mover.MoveTo(target.position);
  24.             }
  25.             else
  26.             {
  27.                 mover.Stop();
  28.             }
  29.         }
  30.         private bool GetIsInRange()
  31.         {
  32.             return  Vector3.Distance(transform.position, target.position) < weaponRange;//创建玩家距离和敌人距离是否小于2
  33.         }
  34.         public void Attack(CombatTarget combatTarget)
  35.         {
  36.             target = combatTarget.transform;
  37.         }
  38.         public void Cancel()
  39.         {
  40.             target = null;
  41.         }
  42.     }
  43. }
复制代码
FollowCamera


  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class FollowCamera : MonoBehaviour
  5. {
  6.     [SerializeField]
  7.     private Transform target;
  8.     public Vector3 offset;
  9.     private void LateUpdate()
  10.     {
  11.         transform.position = target.position + offset;
  12.     }
  13. }
复制代码
CombatTarget

暂时为空,仅仅用于检测敌人脚本,将其挂在攻击目标上

回复

举报

 
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表