using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; public class Rabbit : TargetAnimal { //动画播放器 AnimationPlayer ap; //寻路代理 NavMeshAgent agent; //血量 [System.NonSerialized] public int hp = 1; //猎人的变换组件 Transform hunterT { get { return ArmBow.ins.transform; } } GrassAreaRecorder grassAreaRecorder { get { return GrassAreaRecorder.ins; } } [SerializeField] Material[] materials; public void ChangeColorByType(int type) { GetComponentInChildren().material = materials[type - 1]; } void Awake() { ap = GetComponent(); agent = GetComponent(); ap.completeCallback = onAniComplete; } void Start() { //不同个体动画播放速度差异化 ap.speed = Random.value * 0.2f + 0.8f; //初始动画 playAniForIdle(); //初始化自动策略 InitAutoStrategy(); } void Update() { //寻路过程监测 if (HasCloseToDestination()) { OnReachDestination(); } else { OnMovingToDestination(); } UpdateAction(); UpdateActionTime(); UpdateAutoStrategy(); //输入监听 if (Input.GetKeyDown(KeyCode.D)) { RandomMove(); } } public void Disappear() { Destroy(this.gameObject); } public override void OnHit(Arrow arrow, Vector3 hitPoint, string partName) { arrow.Head().position = hitPoint + arrow.transform.forward * 0.1f; arrow.Hit(); if (partName == "Leg") hp -= 1; else if (partName == "Body") hp -= 2; else if (partName == "Head") hp -= 3; if (hp <= 0) { Die(); } else { Hurt(); } } void Die() { if (dead) return; dead = true; this.agent.enabled = false; PuaseAutoStrategy(); onDie?.Invoke(this); AudioMgr.ins.PlayAnimalEffect("RabbitDie", AudioMgr.GetAudioSource(this.gameObject)); } void Hurt() { RunAwayFromHunter(); PuaseAutoStrategy(); addHurtFlag(); AudioMgr.ins.PlayAnimalEffect("RabbitHurt", AudioMgr.GetAudioSource(this.gameObject)); } Queue hurtFlagList = new Queue(); void addHurtFlag() { hurtFlagList.Enqueue(0); Invoke("clearOneHurtFlag", 5); } void clearOneHurtFlag() { if (hurtFlagList.Count > 0) { hurtFlagList.Dequeue(); if (hurtFlagList.Count == 0) { OnHurtFlagTimeOut(); } } } void OnHurtFlagTimeOut() { if (!dead) { ResumeAutoStrategy(); } } //是否已经死亡 bool dead = false; //是否处于移动状态 bool _moving = false; bool moving { get { return _moving; } set { if (_moving && !value) { movingTime = 0; } if (!_moving && value) stayingTime = 0; _moving = value; } } //实时记录“单次移动的持续时间” float movingTime = 0; //实时停留时间 float stayingTime = 0; //启动寻路 void SetDestination(Vector3 pos) { moving = true; this.agent.destination = pos; } //寻路过程 void OnMovingToDestination() { if (!moving) return; } //寻路结束 void OnReachDestination() { if (!moving) return; moving = false; } //是否已经接近目的地(寻路完成判断) bool HasCloseToDestination() { if (!moving) return true; if (movingTime > 0.1) { if (this.agent.velocity.magnitude < 0.05f) { return true; } } return false; } //更新动作 void UpdateAction() { if (dead) { if (!isAniDie()) playAniDie(); } else if (moving) { if (!isAniJump()) playAniJump(); } else { if (!IsAniForIdle()) { playAniForIdle(); } } } //记录动作时间 void UpdateActionTime() { if (moving) { movingTime += Time.deltaTime; } else { stayingTime += Time.deltaTime; } } float willStayTime; float willMoveTime; bool autoMoving = false; float autoMovingTime; bool autoStrategy = true; //自动策略的更新逻辑 void UpdateAutoStrategy() { if (!autoStrategy) return; if (stayingTime > willStayTime) { autoMoving = true; RandomMove(); RandomWillStayTime(); } if (autoMoving) { if (moving) { autoMovingTime += Time.deltaTime; } else if (autoMovingTime < willMoveTime) { RandomMove(); } else if (autoMovingTime >= willMoveTime) { Stay(); RandomWillMoveTime(); autoMoving = false; autoMovingTime = 0; } } } void InitAutoStrategy() { autoStrategy = true; this.willStayTime = 1 + Random.value * 4; RandomWillMoveTime(); } void PuaseAutoStrategy() { this.autoStrategy = false; } void ResumeAutoStrategy() { this.autoStrategy = true; RandomWillStayTime(); RandomWillMoveTime(); this.autoMoving = false; this.autoMovingTime = 0; } void RandomWillStayTime() { this.willStayTime = Random.value * 3 + 5; } void RandomWillMoveTime() { this.willMoveTime = Random.value * 2 + 3; } //逃跑远离猎人 void RunAwayFromHunter() { Vector3 backVec = GetPointerHunterToMe(); SetDestination(transform.position + backVec.normalized * 5); } //获取猎人到我的位移向量 Vector3 GetPointerHunterToMe() { Vector3 hunterPos = hunterT.position; Vector3 myPos = transform.position; hunterPos.y = myPos.y; return myPos - hunterPos; } //随机移动 void RandomMove() { if (Random.value < 0.5) { SetDestination(grassAreaRecorder.randomOneValidAreaPoint()); } else { Vector3 newDir = Quaternion.AngleAxis(Random.value * 180, Vector3.up) * this.transform.parent.forward; Vector3 newPos = this.transform.parent.position + newDir.normalized * 10 * Random.value; SetDestination(newPos); } } //停留 void Stay() { if (moving) { this.agent.destination = this.agent.nextPosition; OnReachDestination(); } } //当前动画索引 int curAnimIndex = 0; void playAniEat() { ap.play(curAnimIndex = 2, WrapMode.Loop); } bool isAniEat() { return curAnimIndex == 2; } void playAniDie() { ap.play(curAnimIndex = 4, WrapMode.Once); } bool isAniDie() { return curAnimIndex == 4; } void playAniJump() { ap.play(curAnimIndex = 3, WrapMode.Loop); } bool isAniJump() { return curAnimIndex == 3; } void onAniComplete(AnimationPlayerCompleteResult res) { if (res.index == 4) { Invoke("Disappear", 2); } } bool IsAniForIdle() { return curAnimIndex == 0 || curAnimIndex == 2; } void playAniForIdle() { if (grassAreaRecorder.isInValidArea(this.transform.position)) { curAnimIndex = 0; } else { curAnimIndex = 2; } ap.play(curAnimIndex, WrapMode.Loop); } //委托 public System.Action onDie; }