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

2024-09-25
154看过
添加火球装备,火球特效,爆炸特效,给远程射出的攻击设定存在时间,一定时间后销毁。
修复武器动画bug,防止武器的攻击动画为空,设定武器动画为空时,使用角色的动画状态机默认攻击动画


Projectile

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace RPG.Combat
  5. {
  6.     // 定义远程射击类-主要用于发射出去的箭-魔法-
  7.     public class Projectile : MonoBehaviour
  8.     {
  9.         [SerializeField] float speed = 1;//箭矢射出的速度
  10.         [SerializeField] bool isHoming = true;//是否锁定目标
  11.         [SerializeField] GameObject hitEffect = null;//命中特效
  12.         [SerializeField] float maxLifeTime = 5f;//存在的最长时间
  13.         [SerializeField] float lifeAfterTImpact = 2f;//存在的时间
  14.         [SerializeField] GameObject[] destoryOnHit = null;//删除的对象列表
  15.         Health target = null;//攻击目标
  16.         float damage = 0;
  17.         private void Start()
  18.         {
  19.             transform.LookAt(GetAimLocation());//让箭朝向目标位置
  20.         }
  21.         private void Update()
  22.         {
  23.             if (target == null)//如果攻击目标为空
  24.             {
  25.                 return;
  26.             }
  27.             if (isHoming)
  28.             {
  29.                 transform.LookAt(GetAimLocation());//让箭朝向目标位置
  30.             }
  31.             // 使用Translate方法让箭根据速度和时间增量来移动-- // Vector3.forward表示projectile的前向向量,speed是速度,Time.deltaTime是上一帧到当前帧的时间差
  32.             transform.Translate(Vector3.forward * speed * Time.deltaTime);
  33.         }
  34.         public void SetTarget(Health target, float damage)//设置目标
  35.         {
  36.             this.target = target;
  37.             this.damage = damage;
  38.             Destroy(gameObject, maxLifeTime);//删除自身,防止当角色死亡后,最后一击的远程攻击一直存在,一定时间消失
  39.         }
  40.         private Vector3 GetAimLocation()//获取瞄准的目标位置
  41.         {
  42.             CapsuleCollider targetCapsule = target.GetComponent<CapsuleCollider>();//获取目标的碰撞组件
  43.             if (targetCapsule == null)//如果碰撞为空
  44.             {
  45.                 return target.transform.position;//返回目标坐标
  46.             }
  47.             // 如果有CapsuleCollider组件,则返回目标位置上方CapsuleCollider高度的一半处  -确保projectile瞄准的是目标的上半身或中心位置  
  48.             return target.transform.position + Vector3.up * targetCapsule.height / 2;
  49.         }
  50.         private void OnTriggerEnter(Collider other)
  51.         {
  52.             //print("箭的伤害:" + damage);
  53.             Health health = other.GetComponent<Health>();//获取碰撞触发的生命值组件  return
  54.             if (target != null && health != target) return;//如果目标不为空并且生命值不是攻击的目标 return
  55.             if (health == null || health.IsDead()) return;//如果生命值为空 或者角色已经死亡 return
  56.             target.TakeDamage(damage);//添加伤害
  57.            // speed = 0;//击中后速度为0
  58.             if (hitEffect != null || health.IsDead())//如果爆炸特效不为空 则实例化爆炸
  59.             {
  60.                 Instantiate(hitEffect, GetAimLocation(), transform.rotation);
  61.             }
  62.             foreach (GameObject toDestory in destoryOnHit)// 遍历需要销毁的游戏对象列表
  63.             {
  64.                 Destroy(toDestory);// 销毁当前游戏对象
  65.             }
  66.             Destroy(gameObject, lifeAfterTImpact);// 在碰撞后,延迟一段时间后销毁当前游戏对象
  67.         }
  68.     }
  69. }
复制代码
DestoryAfterEffect

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using Unity.VisualScripting;
  4. using UnityEngine;
  5. namespace RPG.Core
  6. {
  7.     //删除特效
  8.     public class DestoryAfterEffect : MonoBehaviour
  9.     {
  10.          float lifeTime = 0;//特效存在的时间
  11.         private void Update()
  12.         {
  13.             lifeTime += Time.deltaTime;
  14.             // 检查当前游戏对象上的粒子系统是否仍在运行,销毁
  15.             if (lifeTime > 1f&&GetComponent<ParticleSystem>().IsAlive())
  16.             {
  17.                 Destroy(gameObject);
  18.             }
  19.         }
  20.     }
  21. }
复制代码
Weapon:
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace RPG.Combat
  5. {
  6.     /// <summary>
  7.     /// 武器脚本
  8.     /// </summary>
  9.     [CreateAssetMenu(fileName = "Weapon", menuName = "Weapons/Make New Waepon", order = 0)]
  10.     public class Weapon : ScriptableObject
  11.     {
  12.         [SerializeField] float weaponDamage = 5f;//武器伤害
  13.         [SerializeField] float weaponRange = 2f;// 武器攻击范围
  14.         [SerializeField] AnimatorOverrideController animatorOverride = null;//装备武器动画
  15.         [SerializeField] GameObject equippedPrefab = null;//武器预制体
  16.         [SerializeField] bool isRightHanded = true;//装备左右手武器,true为右手,false为左手
  17.         [SerializeField] Projectile projectile = null;//箭矢
  18.         [SerializeField] Vector3 projectileOffset = Vector3.zero;//箭矢的偏移
  19.         const string weaponName = "Weapon";//声明一个常量武器
  20.         /// <summary>
  21.         /// 诞生武器
  22.         /// </summary>
  23.         /// <param name="rightHand">右手武器产生的位置</param>
  24.         /// <param name="leftHand">左手武器产生的位置</param>
  25.         /// <param name="animator">武器对应的动画状态机</param>
  26.         public void Spawn(Transform rightHand, Transform leftHand, Animator animator)
  27.         {
  28.             DestroyOldWeapon(rightHand, leftHand);//产生武器之前先删除之前的旧武器,
  29.             if (equippedPrefab != null)//如果不为空,就实例化,防止为空时出现错误
  30.             {
  31.                 Transform handTransform = GetTransform(rightHand, leftHand);
  32.                 GameObject weapon = Instantiate(equippedPrefab, handTransform);//实例化武器
  33.                 weapon.name = weaponName;
  34.             }
  35.             //声明一个动画覆盖       给动画状态机添加别名  
  36.             var overrideController = animator.runtimeAnimatorController as AnimatorOverrideController;
  37.             if (animatorOverride != null) //如果动画状态不为空,就改变为新的动画状态
  38.             {
  39.                 animator.runtimeAnimatorController = animatorOverride;//状态机更改为装备武器的状态
  40.             }
  41.             else if (overrideController != null)
  42.             {
  43.                 //当武器的攻击动画为空,把玩家动画控制器的攻击动画,设为当前武器的攻击动画
  44.                 animator.runtimeAnimatorController = overrideController;
  45.             }
  46.         }
  47.         /// <summary>
  48.         /// 删除旧的武器
  49.         /// </summary>
  50.         /// <param name="rightHand">右手武器</param>
  51.         /// <param name="leftHand">左手武器</param>
  52.         private void DestroyOldWeapon(Transform rightHand, Transform leftHand)
  53.         {
  54.             Transform oldWeapon = rightHand.Find(weaponName);// 在右手中查找旧武器
  55.             if (oldWeapon == null)
  56.             {
  57.                 oldWeapon = leftHand.Find(weaponName);// 如果右手中没有找到旧武器,则在左手中查找
  58.             }
  59.             if (oldWeapon == null) return;// 如果左右手中都没有找到旧武器,则直接返回
  60.             oldWeapon.name = "Destroying";
  61.             Destroy(oldWeapon.gameObject);
  62.         }
  63.         /// <summary>
  64.         /// 获取武器出现的位置
  65.         /// </summary>
  66.         /// <param name="rightHand">右手</param>
  67.         /// <param name="leftHand">左手</param>
  68.         /// <returns></returns>
  69.         private Transform GetTransform(Transform rightHand, Transform leftHand)
  70.         {
  71.             Transform handTransform;
  72.             if (isRightHanded)
  73.             {
  74.                 handTransform = rightHand;//fasle则装备右手武器
  75.             }
  76.             else
  77.             {
  78.                 handTransform = leftHand;//装备左手武器
  79.             }
  80.             return handTransform;
  81.         }
  82.         public bool HasProjectile()//是否有箭矢
  83.         {
  84.             return projectile != null;//返回箭不为空
  85.         }
  86.         //发射箭矢
  87.         public void LacunchProjectile(Transform rightHand, Transform leftHand, Health target)
  88.         {
  89.             //实例化箭矢 Quaternion.identity没有旋转的状态
  90.             Projectile projectileInstance = Instantiate(projectile, GetTransform(rightHand, leftHand).position + projectileOffset, Quaternion.identity);
  91.             projectileInstance.SetTarget(target, weaponDamage);//设置箭射击的攻击目标,伤害
  92.         }
  93.         public float GetDamage() //获取伤害
  94.         {
  95.             return weaponDamage;
  96.         }
  97.         public float GetRange()//获取武器攻击范围
  98.         {
  99.             return weaponRange;
  100.         }
  101.     }
  102. }
复制代码



回复

举报

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

本版积分规则

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