P36-P37部分主要讲诉关于Prefab预制体的内容,可忽略,在动画状态机中添加死亡动画
把做好的Player复制一套,移除掉PlayerControler脚本用于当作敌人,命名Enemy,添加CombatTarget和Health组件,各自做成预制体。
具体代码如下:
Health
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- // 处理生命值系统的脚本
- namespace RPG.Combat
- {
- public class Health : MonoBehaviour
- {
- [SerializeField] float healthPoints = 100f;// 当前生命值,初始值为 100
-
- bool isDead = false;//是否死亡
-
- //死亡方法,这个方法用于给角色判断,是否继续进行攻击
- public bool IsDead()
- {
- return isDead;
- }
-
- // 处理受伤逻辑的方法
- public void TakeDamage(float damage)
- {
- healthPoints = Mathf.Max(healthPoints - damage, 0);// 减少生命值,确保生命值不会低于 0
- print(healthPoints);
- if (healthPoints == 0)//生命值等于0,
- {
- Die();
- }
- }
-
- /// <summary>
- /// 死亡逻辑
- /// </summary>
- private void Die()
- {
- if (isDead) return;//如果玩家已死亡,直接跳出该方法
-
- isDead = true;
- GetComponent<Animator>().SetTrigger("death");//播放死亡动画
- GetComponent<CapsuleCollider>().enabled = false;
- }
- }
- }
-
复制代码
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;// 武器范围,表示武器可以攻击的最大距离
- [SerializeField] float timeBetweenAttacks = 1f;//攻击间隔时间
- [SerializeField] float weaponDamage = 5f;//武器伤害
-
- Health target;// 当前攻击的目标
- float timeSinceLastAttack = 0;//攻击后的时间统计
-
- private Mover mover;// 用于移动角色的 Mover 组件
- private bool isInRange;// 标记目标是否在攻击范围内
-
- private Animator animator;
-
- private void Start()
- {
- mover = GetComponent<Mover>();// 获取 Mover 组件
- animator = GetComponent<Animator>();//获取动画组件
-
- }
-
- private void Update()
- {
-
- timeSinceLastAttack += Time.deltaTime;//设置攻击后的时间统计累加
-
- if (target.IsDead()) return;//如果目标已经死亡,直接return
-
- if (target == null) return;// 如果目标为空,则不进行任何操作
-
-
- if (!GetIsInRange()) // 如果目标不在攻击范围内,则移动到目标位置
- {
- mover.MoveTo(target.transform.position);
-
- }
- else
- {
- mover.Cancel(); // 目标在攻击范围内,取消移动,并触发攻击动画
-
- AttackBehaviour();
- }
- }
-
- private void AttackBehaviour()//攻击触发
- {
- if (timeSinceLastAttack > timeBetweenAttacks)
- {
- animator.SetTrigger("attack");
-
- timeSinceLastAttack = 0;//重置攻击后的时间为0
-
- }
- }
-
- // 动画事件:攻击时触发的事件
- private void Hit()
- {
-
- target.TakeDamage(weaponDamage);//造成伤害
- }
-
- private bool GetIsInRange()
- {
- return Vector3.Distance(transform.position, target.transform.position) < weaponRange;// 检查目标是否在攻击范围内
- }
-
- public void Attack(CombatTarget combatTarget)
- {
- GetComponent<ActionScheduler>().StartAction(this); // 启动当前动作并设置目标
- target = combatTarget.GetComponent<Health>();
-
- }
-
- public void Cancel()
- {
- animator.SetTrigger("stopAttack");
- target = null;// 取消攻击,清除目标
- }
- }
- }
复制代码
|