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; [SerializeField] Material[] materials; public void ChangeColorByType(int type) { GetComponentInChildren().material = materials[type - 1]; } void Awake() { ap = GetComponent(); agent = GetComponent(); } void Start() { //不同个体动画播放速度差异化 ap.speed = Random.value * 0.2f + 0.8f; //初始动画 playAniForIdle(); //初始化自动策略 InitAutoStrategy(); } void Update() { //寻路过程监测 if (HasCloseToDestination()) { OnReachDestination(); } else { OnMovingToDestination(); } UpdateAction(); UpdateActionTime(); UpdateAutoStrategy(); } 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" || partName == "Ear") hp -= 1; else if (partName == "Body") hp -= 2; else if (partName == "Head") hp -= 3; if (hp <= 0) { Die(arrow); } else { Hurt(); } } void Die(Arrow arrow) { if (dead) return; arrow.onDoNextShoot += delegate() { Disappear(); }; dead = true; this.agent.enabled = false; PuaseAutoStrategy(); onDie?.Invoke(this); AudioMgr.ins.PlayAnimalEffect("rabbit_injured", AudioMgr.GetAudioSource(this.gameObject)); } void Hurt() { RunAwayFromHunter(); addHurtFlag(); PuaseAutoStrategy(); AudioMgr.ins.PlayAnimalEffect("rabbit_injured", AudioMgr.GetAudioSource(this.gameObject)); } JC.CS.CountLocker hurtFlag = new JC.CS.CountLocker(); void addHurtFlag() { hurtFlag.Lock(); Invoke("clearOneHurtFlag", 5); } void clearOneHurtFlag() { hurtFlag.Unlock(); if (hurtFlag.IsReleased()) { 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 (Vector3.Distance(this.agent.nextPosition, this.agent.destination) < 0.15f) { return true; } if (movingTime > 0.1f && 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; // } if (!moving) { Stay(); RandomWillMoveTime(); autoMoving = false; autoMovingTime = 0; } else { autoMovingTime += Time.deltaTime; } } } void InitAutoStrategy() { autoStrategy = true; this.willStayTime = 3 + 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 * 2 + 10; } void RandomWillMoveTime() { this.willMoveTime = Random.value * 2 + 3; } //逃跑远离猎人 void RunAwayFromHunter() { Vector3 backVec = GetPointerHunterToMe(); SetDestination(transform.position + backVec.normalized * 5); } [System.NonSerialized] public float baseDistance = 10; [System.NonSerialized] public float baseDistanceMoveRange = 3; //随机移动 void RandomMove() { Vector3 standardPointer = animalsBaseT.forward; Vector3 pointerWithLen = standardPointer.normalized * (baseDistance + Random.value * baseDistanceMoveRange); pointerWithLen = Quaternion.AngleAxis(Random.Range(-22f, 22f), Vector3.up) * pointerWithLen; Vector3 newPos = animalsBaseT.position + pointerWithLen; // GameObject.Find("BBAA").transform.position = newPos; // GameObject.Find("BBBA").transform.LookAt(GameObject.Find("BBAA").transform); SetDestination(newPos); } //停留 void Stay() { if (moving) { this.agent.destination = this.agent.nextPosition; OnReachDestination(); } } //当前动画索引 int curAnimIndex = 0; void playAniEat() { ap.play(curAnimIndex = 0, WrapMode.Loop); } bool isAniEat() { return curAnimIndex == 0; } void playAniDie() { ap.play(curAnimIndex = 2, WrapMode.Once); } bool isAniDie() { return curAnimIndex == 2; } void playAniJump() { ap.play(curAnimIndex = 7, WrapMode.Loop); } bool isAniJump() { return curAnimIndex == 7; } bool IsAniForIdle() { return curAnimIndex == 0 || curAnimIndex == 4 || curAnimIndex == 5 || curAnimIndex == 6; } int[] idleIndexes = {0, 4, 5, 6}; void playAniForIdle() { curAnimIndex = idleIndexes[Random.Range(0, idleIndexes.Length)]; ap.play(curAnimIndex, WrapMode.Loop); } //委托 public System.Action onDie; }