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

2024-09-23
142看过
武器脚本数据存储,修改战斗脚本,新建武器拾取脚本


Weapon:

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace RPG.Combat
  5. {
  6.     [CreateAssetMenu(fileName = "Weapon", menuName = "Weapons/Make New Waepon", order = 0)]
  7.     public class Weapon : ScriptableObject
  8.     {
  9.         [SerializeField] float weaponDamage = 5f;//武器伤害
  10.         [SerializeField] float weaponRange = 2f;// 武器攻击范围
  11.         [SerializeField] AnimatorOverrideController animatorOverride = null;//装备武器动画
  12.         [SerializeField] GameObject equippedPrefab = null;//武器预制体
  13.         public void Spawn(Transform handTransform, Animator animator)
  14.         {
  15.             if (equippedPrefab != null)//如果不为空,就实例化,防止为空时出现错误
  16.             {
  17.                 Instantiate(equippedPrefab, handTransform);//实例化武器
  18.             }
  19.             if(animatorOverride != null)
  20.             {
  21.                 animator.runtimeAnimatorController = animatorOverride;//状态机更改为装备武器的状态
  22.             }
  23.         }
  24.         public float GetDamage() //获取伤害
  25.         {
  26.             return weaponDamage;
  27.         }
  28.         public float GetRange()//获取武器攻击范围
  29.         {
  30.             return weaponRange;
  31.         }
  32.     }
  33. }
复制代码
Fighter

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using RPG.Movement;
  5. using RPG.Core;
  6. namespace RPG.Combat
  7. {
  8.     //攻击
  9.     public class Fighter : MonoBehaviour, IAction
  10.     {
  11.       
  12.         [SerializeField] float timeBetweenAttacks = 1f;//攻击间隔时间
  13.       
  14.         [SerializeField] Transform handTransform = null;//武器实例化的地方
  15.         [SerializeField] Weapon defaultWeapon = null;//设置默认武器脚本
  16.         Health target;// 当前攻击的目标
  17.         float timeSinceLastAttack = Mathf.Infinity;//上次攻击的时间为 为无穷大
  18.         Weapon currentWeapon = null;
  19.         private Mover mover;// 用于移动角色的 Mover 组件
  20.         private bool isInRange;// 标记目标是否在攻击范围内
  21.         private Animator animator;
  22.         private void Start()
  23.         {
  24.             mover = GetComponent<Mover>();// 获取 Mover 组件
  25.             animator = GetComponent<Animator>();//获取动画组件
  26.             EquipWeapon(defaultWeapon);
  27.         }
  28.         private void Update()
  29.         {
  30.             timeSinceLastAttack += Time.deltaTime;//设置攻击后的时间统计累加
  31.            
  32.             if (target == null) return;// 如果目标为空,则不进行任何操作
  33.             if (target.IsDead()) return;//如果目标已经死亡,直接return
  34.             if (!GetIsInRange()) // 如果目标不在攻击范围内,则移动到目标位置
  35.             {
  36.                 mover.MoveTo(target.transform.position,1f);//设置战斗时百分比为1
  37.                
  38.             }
  39.             else
  40.             {
  41.                 mover.Cancel(); // 目标在攻击范围内,取消移动,并触发攻击动画
  42.                 AttackBehaviour();
  43.             }
  44.         }
  45.         public void EquipWeapon(Weapon weapon)//实例化武器
  46.         {
  47.             currentWeapon = weapon;
  48.             if (weapon == null) return;
  49.             weapon.Spawn(handTransform, animator);
  50.         }
  51.         private void AttackBehaviour()//攻击行为
  52.         {
  53.             transform.LookAt(target.transform.position);//攻击时面向敌人
  54.             if (timeSinceLastAttack > timeBetweenAttacks)//任何时候都大于攻击间隔
  55.             {
  56.                 TriggerAttack();
  57.                 timeSinceLastAttack = 0;//重置攻击后的时间为0
  58.             }
  59.         }
  60.         
  61.         private void TriggerAttack()//动画状态机 攻击触发
  62.         {
  63.             animator.ResetTrigger("stopAttack");
  64.             animator.SetTrigger("attack");
  65.         }
  66.         // 动画事件:攻击时触发的事件
  67.         private void Hit()
  68.         {
  69.            if (target == null) return;
  70.             target.TakeDamage(defaultWeapon.GetDamage());//造成伤害
  71.         }
  72.         private bool GetIsInRange()// 检查目标是否在攻击范围内
  73.         {
  74.             return Vector3.Distance(transform.position, target.transform.position) < defaultWeapon.GetRange();
  75.         }
  76.         
  77.         public bool CanAttack(GameObject combatTarget)//检测是否可以攻击
  78.         {
  79.             if(combatTarget == null) //如果攻击目标为空 跳出
  80.             {
  81.                 return false;
  82.             }
  83.             Health targetToTest = combatTarget.GetComponent<Health>();//获取目标的生命组件
  84.             return targetToTest != null && !targetToTest.IsDead();//目标不为空,并且没有死亡
  85.         }
  86.         public void Attack(GameObject combatTarget)//攻击
  87.         {
  88.             
  89.             GetComponent<ActionScheduler>().StartAction(this); // 启动当前动作并设置目标
  90.             target = combatTarget.GetComponent<Health>();//获取目标的生命组件
  91.         }
  92.         public void Cancel()//取消
  93.         {
  94.             StopAttack();//调用停止攻击
  95.             target = null;//清除目标
  96.             mover.Cancel();//取消移动
  97.         }
  98.         private void StopAttack()//动画状态机 停止攻击
  99.         {
  100.             animator.ResetTrigger("attack");//重置攻击
  101.             animator.SetTrigger("stopAttack");//播放暂停攻击
  102.         }
  103.     }
  104. }
复制代码
WeaponPickup

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace RPG.Combat
  5. {
  6.     //
  7.     public class WeaponPickup : MonoBehaviour
  8.     {
  9.         [SerializeField]Weapon weapon = null;
  10.       
  11.         private void OnTriggerEnter(Collider other)//碰撞触发
  12.         {
  13.             if(other.gameObject.tag == "Player")//如果玩家和拾取武器碰撞触发
  14.             {
  15.                 other.GetComponent<Fighter>().EquipWeapon(weapon);//获取玩家的战斗组件,调用准备武器的方法
  16.                Destroy(gameObject);//删除自身
  17.             }
  18.         }
  19.     }
  20. }
复制代码


回复

举报

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

本版积分规则

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