添加火球装备,火球特效,爆炸特效,给远程射出的攻击设定存在时间,一定时间后销毁。
修复武器动画bug,防止武器的攻击动画为空,设定武器动画为空时,使用角色的动画状态机默认攻击动画
Projectile
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- namespace RPG.Combat
- {
- // 定义远程射击类-主要用于发射出去的箭-魔法-
- public class Projectile : MonoBehaviour
- {
-
- [SerializeField] float speed = 1;//箭矢射出的速度
- [SerializeField] bool isHoming = true;//是否锁定目标
- [SerializeField] GameObject hitEffect = null;//命中特效
- [SerializeField] float maxLifeTime = 5f;//存在的最长时间
- [SerializeField] float lifeAfterTImpact = 2f;//存在的时间
- [SerializeField] GameObject[] destoryOnHit = null;//删除的对象列表
-
-
- Health target = null;//攻击目标
- float damage = 0;
-
- private void Start()
- {
- transform.LookAt(GetAimLocation());//让箭朝向目标位置
- }
-
- private void Update()
- {
- if (target == null)//如果攻击目标为空
- {
- return;
- }
- if (isHoming)
- {
- transform.LookAt(GetAimLocation());//让箭朝向目标位置
- }
- // 使用Translate方法让箭根据速度和时间增量来移动-- // Vector3.forward表示projectile的前向向量,speed是速度,Time.deltaTime是上一帧到当前帧的时间差
- transform.Translate(Vector3.forward * speed * Time.deltaTime);
- }
- public void SetTarget(Health target, float damage)//设置目标
- {
- this.target = target;
- this.damage = damage;
- Destroy(gameObject, maxLifeTime);//删除自身,防止当角色死亡后,最后一击的远程攻击一直存在,一定时间消失
- }
-
- private Vector3 GetAimLocation()//获取瞄准的目标位置
- {
- CapsuleCollider targetCapsule = target.GetComponent<CapsuleCollider>();//获取目标的碰撞组件
- if (targetCapsule == null)//如果碰撞为空
- {
- return target.transform.position;//返回目标坐标
- }
-
- // 如果有CapsuleCollider组件,则返回目标位置上方CapsuleCollider高度的一半处 -确保projectile瞄准的是目标的上半身或中心位置
- return target.transform.position + Vector3.up * targetCapsule.height / 2;
- }
-
- private void OnTriggerEnter(Collider other)
- {
-
- //print("箭的伤害:" + damage);
- Health health = other.GetComponent<Health>();//获取碰撞触发的生命值组件 return
- if (target != null && health != target) return;//如果目标不为空并且生命值不是攻击的目标 return
- if (health == null || health.IsDead()) return;//如果生命值为空 或者角色已经死亡 return
-
- target.TakeDamage(damage);//添加伤害
- // speed = 0;//击中后速度为0
-
- if (hitEffect != null || health.IsDead())//如果爆炸特效不为空 则实例化爆炸
- {
- Instantiate(hitEffect, GetAimLocation(), transform.rotation);
- }
-
- foreach (GameObject toDestory in destoryOnHit)// 遍历需要销毁的游戏对象列表
- {
- Destroy(toDestory);// 销毁当前游戏对象
- }
-
- Destroy(gameObject, lifeAfterTImpact);// 在碰撞后,延迟一段时间后销毁当前游戏对象
-
-
- }
- }
- }
-
-
复制代码
DestoryAfterEffect
- using System.Collections;
- using System.Collections.Generic;
- using Unity.VisualScripting;
- using UnityEngine;
-
- namespace RPG.Core
- {
- //删除特效
- public class DestoryAfterEffect : MonoBehaviour
- {
- float lifeTime = 0;//特效存在的时间
- private void Update()
- {
- lifeTime += Time.deltaTime;
- // 检查当前游戏对象上的粒子系统是否仍在运行,销毁
- if (lifeTime > 1f&&GetComponent<ParticleSystem>().IsAlive())
- {
- Destroy(gameObject);
- }
- }
- }
- }
-
复制代码
Weapon:
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- namespace RPG.Combat
- {
- /// <summary>
- /// 武器脚本
- /// </summary>
- [CreateAssetMenu(fileName = "Weapon", menuName = "Weapons/Make New Waepon", order = 0)]
- public class Weapon : ScriptableObject
- {
- [SerializeField] float weaponDamage = 5f;//武器伤害
- [SerializeField] float weaponRange = 2f;// 武器攻击范围
-
- [SerializeField] AnimatorOverrideController animatorOverride = null;//装备武器动画
- [SerializeField] GameObject equippedPrefab = null;//武器预制体
- [SerializeField] bool isRightHanded = true;//装备左右手武器,true为右手,false为左手
- [SerializeField] Projectile projectile = null;//箭矢
- [SerializeField] Vector3 projectileOffset = Vector3.zero;//箭矢的偏移
-
- const string weaponName = "Weapon";//声明一个常量武器
-
- /// <summary>
- /// 诞生武器
- /// </summary>
- /// <param name="rightHand">右手武器产生的位置</param>
- /// <param name="leftHand">左手武器产生的位置</param>
- /// <param name="animator">武器对应的动画状态机</param>
- public void Spawn(Transform rightHand, Transform leftHand, Animator animator)
- {
- DestroyOldWeapon(rightHand, leftHand);//产生武器之前先删除之前的旧武器,
-
- if (equippedPrefab != null)//如果不为空,就实例化,防止为空时出现错误
- {
- Transform handTransform = GetTransform(rightHand, leftHand);
-
- GameObject weapon = Instantiate(equippedPrefab, handTransform);//实例化武器
- weapon.name = weaponName;
-
- }
-
- //声明一个动画覆盖 给动画状态机添加别名
- var overrideController = animator.runtimeAnimatorController as AnimatorOverrideController;
-
- if (animatorOverride != null) //如果动画状态不为空,就改变为新的动画状态
- {
- animator.runtimeAnimatorController = animatorOverride;//状态机更改为装备武器的状态
- }
- else if (overrideController != null)
- {
- //当武器的攻击动画为空,把玩家动画控制器的攻击动画,设为当前武器的攻击动画
- animator.runtimeAnimatorController = overrideController;
-
- }
- }
-
- /// <summary>
- /// 删除旧的武器
- /// </summary>
- /// <param name="rightHand">右手武器</param>
- /// <param name="leftHand">左手武器</param>
- private void DestroyOldWeapon(Transform rightHand, Transform leftHand)
- {
- Transform oldWeapon = rightHand.Find(weaponName);// 在右手中查找旧武器
- if (oldWeapon == null)
- {
- oldWeapon = leftHand.Find(weaponName);// 如果右手中没有找到旧武器,则在左手中查找
- }
- if (oldWeapon == null) return;// 如果左右手中都没有找到旧武器,则直接返回
-
- oldWeapon.name = "Destroying";
- Destroy(oldWeapon.gameObject);
- }
-
- /// <summary>
- /// 获取武器出现的位置
- /// </summary>
- /// <param name="rightHand">右手</param>
- /// <param name="leftHand">左手</param>
- /// <returns></returns>
- private Transform GetTransform(Transform rightHand, Transform leftHand)
- {
- Transform handTransform;
- if (isRightHanded)
- {
- handTransform = rightHand;//fasle则装备右手武器
- }
- else
- {
- handTransform = leftHand;//装备左手武器
- }
- return handTransform;
- }
-
- public bool HasProjectile()//是否有箭矢
- {
- return projectile != null;//返回箭不为空
- }
-
- //发射箭矢
- public void LacunchProjectile(Transform rightHand, Transform leftHand, Health target)
- {
- //实例化箭矢 Quaternion.identity没有旋转的状态
- Projectile projectileInstance = Instantiate(projectile, GetTransform(rightHand, leftHand).position + projectileOffset, Quaternion.identity);
- projectileInstance.SetTarget(target, weaponDamage);//设置箭射击的攻击目标,伤害
-
-
- }
-
- public float GetDamage() //获取伤害
- {
- return weaponDamage;
- }
-
- public float GetRange()//获取武器攻击范围
- {
- return weaponRange;
- }
- }
- }
-
复制代码
|