浏览代码

鸡的行为逻辑修改

lvjincheng 4 年之前
父节点
当前提交
6733e26abb

+ 5 - 0
Assets/BowArrow/Scenes/GameChallengeScene/TreeAreaRecorder.cs

@@ -33,6 +33,7 @@ public class TreeAreaRecorder : MonoBehaviour
         public float distanceInHorizontal(Vector3 pos) {
             return Mathf.Sqrt(Mathf.Pow(position.x - pos.x, 2) + Mathf.Pow(position.z - pos.z, 2));
         }
+        public object occupy; //被占用(例如鸟着落)
     }
 
     private AreaInfo[] areaInfos;
@@ -52,4 +53,8 @@ public class TreeAreaRecorder : MonoBehaviour
         System.Array.Copy(areaInfos, list, len);
         return list;
     }
+
+    public AreaInfo[] getAreaInfos() {
+        return areaInfos;
+    }
 }

+ 64 - 65
Assets/BowArrow/Scenes/GameChallengeScene/Yeji.cs

@@ -27,7 +27,6 @@ public class Yeji : TargetAnimal
         animator = GetComponent<Animator>();
         agent = GetComponent<NavMeshAgent>();
         this.agent.avoidancePriority = avoidancePriority;
-        RandomWillFlyTime();
     }
     static int _avoidancePriority = 0;
     static int avoidancePriority {
@@ -42,7 +41,7 @@ public class Yeji : TargetAnimal
     }
 
     void OnDestroy() {
-        ReleaseLandLock();
+        tryReleaseOccupyTree();
     }
 
     void Update()
@@ -145,12 +144,11 @@ public class Yeji : TargetAnimal
         
         float toFlyHeight = 2f;
         float canStandTime = 3f;
+        float canFlyStayTime = 3f;
         //能够在前几棵树徘徊
         [System.NonSerialized] public int canFlyTreeCount = 4;
-        //将会绕树转
-        bool willMoveRoundTree = false;
-        Queue<Vector3> roundTreePostions = new Queue<Vector3>();
-        //随机移动
+        const float downSpeed = 2.0f;
+        //更新逻辑-起飞降落
         void UpdateFlyUpDown() {
             if (state.up && state.landing) { //起飞阶段
                 AnimatorStateInfo animatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);
@@ -159,7 +157,6 @@ public class Yeji : TargetAnimal
                     if (animatorStateInfo.normalizedTime >= 1.0) {
                         state.landing = false;
                         state.flying = true;
-                        Invoke("ReleaseLandLock", Random.value * 3f + 1.0f);
                     }
                 }
                 return;
@@ -178,7 +175,7 @@ public class Yeji : TargetAnimal
                 return;
             }
             if (state.down && state.flying) { //下降阶段
-                float nextH = currentHeight - Time.deltaTime * 2f;
+                float nextH = currentHeight - Time.deltaTime * downSpeed;
                 if (nextH <= 0) { //下降完成
                     nextH = 0;
                     state.landing = true;
@@ -203,9 +200,18 @@ public class Yeji : TargetAnimal
                 return;
             }
         }
-        float willFlyTime;
-        float flyingTime;
+
+        TreeAreaRecorder.AreaInfo targetAreaInfo;
+        bool hasCheckFlyDown = false;
         void UpdateBehavior() {
+            if (state.flyStaying) {
+                canFlyStayTime -= Time.deltaTime;
+                if (canFlyStayTime <= 0) {
+                    state.flyStaying = false;
+                }
+                return;
+            }
+
             if (state.standing) {
                 canStandTime -= Time.deltaTime;
                 if (canStandTime <= 0) {
@@ -217,48 +223,37 @@ public class Yeji : TargetAnimal
             if (state.landing) return;
 
             if (state.flying && !state.down && !state.up) {
-                flyingTime += Time.deltaTime;
-                if (flyingTime >= willFlyTime && DoLandLock()) {
-                    flyingTime = 0;
-                    state.down = true;
+                if (!hasCheckFlyDown) {
+                    float downNeedTime = flyPlaneHeight / downSpeed;
+                    float keyDistance = this.agent.speed * downNeedTime; //触发下降的水平距离阈值
+                    if (Vector3.Distance(this.transform.position, this.agent.destination) < keyDistance) {
+                        hasCheckFlyDown = true;
+                        if (Random.value < 0.6 && tryOccupyTree()) {
+                            state.down = true;
+                        } else {
+                            state.flyStaying = true;
+                            canFlyStayTime = 4f + Random.value * 2f;
+                        }
+                    }
                 }
             }
             
             if (moving) return;
 
-            if (willMoveRoundTree && roundTreePostions.Count > 0) {
-                Vector3 pos = roundTreePostions.Dequeue();
-                SetDestination(pos);
-                return;
-            } else {
-                willMoveRoundTree = false;
-            }
-
-            //规划下一次行动路线
-            Vector3 myPos = this.transform.position; 
-            TreeAreaRecorder.AreaInfo[] areaInfos = treeAreaRecorder.copyAreaInfos(canFlyTreeCount); 
-            for (int i = 0; i < canFlyTreeCount; i++) {
-                areaInfos[i].teamCompareValue = areaInfos[i].distanceInHorizontal(myPos);
-            }
-            System.Array.Sort(areaInfos, new ComparerAreaInfosByDistance());
-            //如果离这棵树比较近,有几率使其绕着树转
-            TreeAreaRecorder.AreaInfo firstAreaInfo = areaInfos[0];
-            bool isNearTree4th = areaInfos.Length == 4 && firstAreaInfo == treeAreaRecorder.getValidAreaInfo(3);
-            if (!isNearTree4th && firstAreaInfo.teamCompareValue < firstAreaInfo.radius + 1.5f && Random.value < 0.5) {
-                willMoveRoundTree = true;
-                Vector3 treePos = areaInfos[0].transform.position; 
-                treePos.y = myPos.y;
-                Vector3 pointer = myPos - treePos;
-                roundTreePostions.Clear();
-                int direction = Random.value >= 0.5 ? 1 : -1;
-                for (int i = 1; i <= 6; i++) {
-                    roundTreePostions.Enqueue(treePos + Quaternion.AngleAxis(i * 60 * direction, Vector3.up) * pointer);
+            //飞向别的树
+            #region 
+                Vector3 myPos = this.transform.position; 
+                TreeAreaRecorder.AreaInfo[] areaInfos = treeAreaRecorder.copyAreaInfos(canFlyTreeCount); 
+                for (int i = 0; i < canFlyTreeCount; i++) {
+                    areaInfos[i].teamCompareValue = areaInfos[i].distanceInHorizontal(myPos);
                 }
-                return;
-            }
-            TreeAreaRecorder.AreaInfo areaInfo = areaInfos[Random.Range(1, canFlyTreeCount)];
-            Vector3 newPos = YejiHuntGameMode.CalculateNewPosByTreePos(animalsBaseT, flyPlaneHeight, areaInfo);
-            SetDestination(newPos);
+                System.Array.Sort(areaInfos, new ComparerAreaInfosByDistance());
+                TreeAreaRecorder.AreaInfo areaInfo = areaInfos[Random.Range(1, canFlyTreeCount)];
+                Vector3 newPos = YejiHuntGameMode.CalculateNewPosByTreePos(animalsBaseT, flyPlaneHeight, areaInfo);
+                SetDestination(newPos);
+                targetAreaInfo = areaInfo;
+                hasCheckFlyDown = false;
+            #endregion
         }
 
         class ComparerAreaInfosByDistance : IComparer {
@@ -276,45 +271,49 @@ public class Yeji : TargetAnimal
             state.up = true;
             toFlyHeight = RandomOnePreHeight();
             animator.CrossFade("FlyFromGround", 0.1f);
-            RandomWillFlyTime();
+            tryReleaseOccupyTree();
+        }
+
+        bool tryOccupyTree() {
+            if (targetAreaInfo == null) return false;
+            if (targetAreaInfo.occupy != null) return false;
+            else {
+                targetAreaInfo.occupy = this;
+                return true;
+            }
         }
-        void RandomWillFlyTime() {
-            willFlyTime = 4 + Random.value * 3f;
+
+        void tryReleaseOccupyTree() {
+            if (targetAreaInfo != null && targetAreaInfo.occupy != null && targetAreaInfo.occupy.Equals(this)) {
+                targetAreaInfo.occupy = null;
+            }
         }
+
         static float[] preFlyHeights;
-        static int[] preFlyHeightCools;
+        static bool[] preFlyHeightCools;
         public static void InitPreHeights() {
-            preFlyHeights = new float[]{2, 2.5f, 3, 3.5f, 4f};
-            preFlyHeightCools = new int[]{0, 0, 0, 0, 0};
+            preFlyHeights = new float[]{1.7f, 2.2f};
+            preFlyHeightCools = new bool[]{false, false};
         }
         public static float RandomOnePreHeight() {
             List<int> indexes = new List<int>();
             for (int i = 0; i < preFlyHeightCools.Length; i++) {
-                if (preFlyHeightCools[i] > 0) preFlyHeightCools[i] = preFlyHeightCools[i] - 1;
-                if (preFlyHeightCools[i] == 0) {
+                if (!preFlyHeightCools[i]) {
                     indexes.Add(i);
                 }
+                if (preFlyHeightCools[i]) preFlyHeightCools[i] = false;
             }
             int index = indexes[Random.Range(0, indexes.Count)];
-            preFlyHeightCools[index] = 3;
+            preFlyHeightCools[index] = true;
             return preFlyHeights[index];
         }
-        public static bool landLocked = false; //着陆锁,禁止地上同时存在两只鸟,避免穿模
-        private bool myLandLocked = false;
-        public bool DoLandLock() {
-            if (landLocked) return false;
-            return myLandLocked = landLocked = true;
-        }
-        public void ReleaseLandLock() {
-            if (!myLandLocked) return;
-            myLandLocked = landLocked = false;
-        }
     #endregion
 
     //状态
     [System.Serializable]
     public class State {
         public bool standing = false;
+        public bool flyStaying = false;
         [SerializeField] private bool _dead;
         public bool dead {
             get { return _dead; }

+ 10 - 18
Assets/BowArrow/Scenes/GameChallengeScene/YejiHuntGameMode.cs

@@ -1,6 +1,7 @@
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
+using DG.Tweening;
 
 public class YejiHuntGameMode : ChallengeGameMode
 {
@@ -20,7 +21,6 @@ public class YejiHuntGameMode : ChallengeGameMode
     public override void Start() {
         UnbanBowReady();
         Yeji.InitPreHeights();
-        Yeji.landLocked = false;
         if (nextLevel != null) {
             SetLevel(int.Parse(nextLevel));
             AddHuntGameView();
@@ -50,30 +50,20 @@ public class YejiHuntGameMode : ChallengeGameMode
         CreateAnimal();
     }
 
-    //野鸡的基础飞行高度
-    const float baseFlyHeightMin = 2;
-    float baseFlyHeight = 1.5f;
-    //野鸡将在哪棵树附近生成
-    int createNearTreeIndex = 0;
-    //能够在前几棵树徘徊
-    int canFlyTreeCount = 4;
-
     void CreateAnimal() {
         if (createAnimalIndex >= createCountMax) return;
 
-        //计算初始生成位置,后面的兔子生成越来越远,在标准方向的±30°内生成
         #region 
+            //野鸡将在哪棵树附近生成
+            int createNearTreeIndex = 0;
             if (createAnimalIndex < 2) {
                 createNearTreeIndex = createAnimalIndex;
-                canFlyTreeCount = 2;
             } else if (createAnimalIndex < 4) {
-                createNearTreeIndex = Random.Range(1, 3);
-                canFlyTreeCount = 3;
+                createNearTreeIndex = 2;
             } else {
-                createNearTreeIndex = Random.Range(2, 4);
-                canFlyTreeCount = 4;
+                createNearTreeIndex = 3;
             } 
-            baseFlyHeight = Yeji.RandomOnePreHeight();
+            float baseFlyHeight = Yeji.RandomOnePreHeight();
             TreeAreaRecorder.AreaInfo areaInfo = treeAreaRecorder.getValidAreaInfo(createNearTreeIndex);
             Vector3 newPos = CalculateNewPosByTreePos(animalsBaseT, flyPlaneHeight, areaInfo);
         #endregion
@@ -83,14 +73,16 @@ public class YejiHuntGameMode : ChallengeGameMode
 
         Yeji yeji = animalObject.GetComponent<Yeji>();
         yeji.treeAreaRecorder = treeAreaRecorder;
-        yeji.canFlyTreeCount = canFlyTreeCount;
         yeji.flyPlaneHeight = flyPlaneHeight;
         yeji.SetFlyHeight(baseFlyHeight);
         yeji.RotateByWorldY(Random.value * 360);
         yeji.onDie += delegate(Yeji yeji) {
             animalCount--;
             animalSet.Remove(yeji);
-            CreateAnimal();
+            //加一个延迟,避免新生成的鸟跟刚死的鸟出现同一位置时形成重叠
+            Sequence seq = DOTween.Sequence();
+            seq.AppendInterval(1.0f);
+            seq.AppendCallback(CreateAnimal);
         };
         animalSet.Add(yeji);
         createAnimalIndex++;

+ 1 - 1
Assets/BowArrow/Scripts/Manager/GameMgr.cs

@@ -8,7 +8,7 @@ using UnityEngine.SceneManagement;
 public class GameMgr : MonoBehaviour
 {
     public static bool debugInEditor = false;
-    public static int gameType = 5;
+    public static int gameType = 4;
     public GameMode gameMode;
     [System.NonSerialized] public bool gameOver = false;
     public static GameMgr ins;