実現したいこと
前提として、playerControllerというスクリプトを持っているオブジェクトはプレイヤーと呼ぶことにし、pushControllerというスクリプトを持っているオブジェクトはオブジェクト+アルファベット(例えば、オブジェクトA、オブジェクトB)と呼ぶことにする。
プレイヤーがpushControllerのスクリプトをもつオブジェクトAと同じ位置に移動するとき、オブジェクトAはプレイヤーの進行方向に押し出されるような形で移動してほしい。
左からプレイヤー、オブジェクトA、オブジェクトB、オブジェクトCが4つ並んで位置するとき、プレイヤーが右に移動すればオブジェクトA、オブジェクトB、オブジェクトCは全部右方向に移動してほしい。
参考として画像を載せます。
発生している問題・分からないこと
プレイヤーの隣に位置するオブジェクト(pushContorollerを持っている)が二つ以上あるとき、プレイヤーがそれらを押し出そうと移動すると、unityがフリーズして動かなくなります。
一つのオブジェクトを押し出すときは基本的にはフリーズしませんが、たまにフリーズします。
エラーメッセージ
error
1エラーメッセージはありません。
該当のソースコード
特になし
PlayerController
1private LevelManager levelManager; 2private PushController[] pushcontroller; 3 4void Start() 5{ 6 levelManager = GameObject.Find("LevelManager").GetComponent<LevelManager>(); 7} 8 9public void Left() 10{ 11 PushController[] pushcontrollers = GameObject.FindObjectsOfType<PushController>(); 12 StopController[] stopcontrollers = GameObject.FindObjectsOfType<StopController>(); 13 transform.position += new Vector3(-1, 0, 0); 14 Vector3 pos = Rounding.Round(transform.position); 15 transform.position = pos; 16 Task.Delay(100); 17 foreach (StopController obj in stopcontrollers) 18 { 19 if (obj.enabled) 20 { 21 obj.PositionSearch(); 22 obj.PositionCheck(); 23 } 24 } 25 foreach (PushController obj in pushcontrollers) 26 { 27 if(obj.enabled) 28 { 29 obj.PositionSearch(); 30 obj.PositionCheck(); 31 } 32 } 33} 34public void Right() 35{ 36 PushController[] pushcontrollers = GameObject.FindObjectsOfType<PushController>(); 37 StopController[] stopcontrollers = GameObject.FindObjectsOfType<StopController>(); 38 transform.position += new Vector3(1, 0, 0); 39 Vector3 pos = Rounding.Round(transform.position); 40 transform.position = pos; 41 Task.Delay(100); 42 foreach (StopController obj in stopcontrollers) 43 { 44 if (obj.enabled) 45 { 46 obj.PositionSearch(); 47 obj.PositionCheck(); 48 } 49 } 50 foreach (PushController obj in pushcontrollers) 51 { 52 if(obj.enabled) 53 { 54 obj.PositionSearch(); 55 obj.PositionCheck(); 56 } 57 } 58} 59public void Up() 60{ 61 PushController[] pushcontrollers = GameObject.FindObjectsOfType<PushController>(); 62 StopController[] stopcontrollers = GameObject.FindObjectsOfType<StopController>(); 63 transform.position += new Vector3(0, 1, 0); 64 Vector3 pos = Rounding.Round(transform.position); 65 transform.position = pos; 66 Task.Delay(100); 67 foreach (StopController obj in stopcontrollers) 68 { 69 if (obj.enabled) 70 { 71 obj.PositionSearch(); 72 obj.PositionCheck(); 73 } 74 } 75 foreach (PushController obj in pushcontrollers) 76 { 77 if (obj.enabled) 78 { 79 obj.PositionSearch(); 80 obj.PositionCheck(); 81 } 82 } 83} 84public void Down() 85{ 86 PushController[] pushcontrollers = GameObject.FindObjectsOfType<PushController>(); 87 StopController[] stopcontrollers = GameObject.FindObjectsOfType<StopController>(); 88 transform.position += new Vector3(0, -1, 0); 89 Vector3 pos = Rounding.Round(transform.position); 90 transform.position = pos; 91 Task.Delay(100); 92 foreach (StopController obj in stopcontrollers) 93 { 94 if (obj.enabled) 95 { 96 obj.PositionSearch(); 97 obj.PositionCheck(); 98 } 99 } 100 foreach (PushController obj in pushcontrollers) 101 { 102 if (obj.enabled) 103 { 104 obj.PositionSearch(); 105 obj.PositionCheck(); 106 } 107 } 108}
pushController
1private LevelManager levelManager; 2private PushController pushController; 3private GameObject a; 4private GameObject b; 5private GameObject c; 6private GameObject d; 7 8void Start() 9{ 10 levelManager = GameObject.Find("LevelManager").GetComponent<LevelManager>(); 11 a = GetObjectA(); 12 b = GetObjectB(); 13 c = GetObjectC(); 14 d = GetObjectD(); 15} 16 17// Update is called once per frame 18void Update() 19{ 20 21} 22 23private GameObject GetObjectA() 24{ 25 Vector3 targetPosition = new Vector3(gameObject.transform.position.x, gameObject.transform.position.y + 1, gameObject.transform.position.z); 26 GameObject[] allObjects = GameObject.FindObjectsOfType<GameObject>(); 27 foreach (GameObject obj in allObjects) 28 { 29 Vector3 position = obj.transform.position; 30 if (position == targetPosition) 31 { 32 return obj; 33 } 34 } 35 return null; 36} 37private GameObject GetObjectB() 38{ 39 Vector3 targetPosition = new Vector3(gameObject.transform.position.x + 1, gameObject.transform.position.y, gameObject.transform.position.z); 40 GameObject[] allObjects = GameObject.FindObjectsOfType<GameObject>(); 41 foreach (GameObject obj in allObjects) 42 { 43 Vector3 position = obj.transform.position; 44 if (position == targetPosition) 45 { 46 return obj; 47 } 48 } 49 return null; 50} 51private GameObject GetObjectC() 52{ 53 Vector3 targetPosition = new Vector3(gameObject.transform.position.x, gameObject.transform.position.y - 1, gameObject.transform.position.z); 54 GameObject[] allObjects = GameObject.FindObjectsOfType<GameObject>(); 55 foreach(GameObject obj in allObjects) 56 { 57 Vector3 position = obj.transform.position; 58 if (position == targetPosition) 59 { 60 return obj; 61 } 62 } 63 return null; 64} 65private GameObject GetObjectD() 66{ 67 Vector3 targetPosition = new Vector3(gameObject.transform.position.x - 1, gameObject.transform.position.y, gameObject.transform.position.z); 68 GameObject[] allObjects = GameObject.FindObjectsOfType<GameObject>(); 69 foreach(GameObject obj in allObjects) 70 { 71 Vector3 position = obj.transform.position; 72 if (position == targetPosition) 73 { 74 return obj; 75 } 76 } 77 return null; 78} 79public void PositionCheck() 80{ 81 a =GetObjectA(); 82 b =GetObjectB(); 83 c =GetObjectC(); 84 d =GetObjectD(); 85} 86public void PositionSearch() 87{ 88 if(a != null && a.transform.position == this.transform.position) 89 { 90 List<GameObject> S = new List<GameObject>(); 91 S.Add(gameObject); 92 Vector3 M = new Vector3(0, -1, 0); 93 PositionMove(S, M, a); 94 95 } 96 if (b != null && b.transform.position == this.transform.position) 97 { 98 List<GameObject> S = new List<GameObject>(); 99 S.Add(gameObject); 100 Vector3 M = new Vector3(-1, 0, 0); 101 PositionMove(S, M, b); 102 } 103 if (c != null && c.transform.position == this.transform.position) 104 { 105 List<GameObject> S = new List<GameObject>(); 106 S.Add(gameObject); 107 Vector3 M = new Vector3(0, 1, 0); 108 PositionMove(S, M, c); 109 } 110 if (d != null && d.transform.position == this.transform.position) 111 { 112 List<GameObject> S = new List<GameObject>(); 113 S.Add(gameObject); 114 Vector3 M = new Vector3(1, 0, 0); 115 PositionMove(S, M, d); 116 } 117} 118 119private void PositionMove(List<GameObject> s, Vector3 m, GameObject player) 120{ 121 Vector3 P = this.transform.position; 122 P += m; 123 124 bool loopContinue = true; 125 126 while (loopContinue) 127 { 128 Collider2D[] colliders = Physics2D.OverlapCircleAll(P, 0.4f); 129 if (colliders.Length > 0) 130 { 131 foreach (Collider2D collider in colliders) 132 { 133 PushController pushController = collider.GetComponent<PushController>(); 134 StopController stopController = collider.GetComponent<StopController>(); 135 if (pushController != null && pushController.enabled) 136 { 137 s.Add(collider.gameObject); 138 } 139 else if (stopController != null && stopController.enabled) 140 { 141 player.transform.position += m; 142 loopContinue = false; 143 } 144 else 145 { 146 foreach (GameObject obj in s) 147 { 148 obj.transform.position += m; 149 } 150 loopContinue = false; 151 } 152 } 153 P += m; 154 } 155 else 156 { 157 for(int i = s.Count - 1; i >= 0; i--) 158 { 159 Debug.Log(s[i]); 160 } 161 loopContinue = false; 162 } 163 } 164}
試したこと・調べたこと
上記の詳細・結果
無限ループの可能性を考えて、Debug.Logを使いしらべてみました。下記の①②の画像はpushControllerスクリプトのPositionMoveメソッドの部分です。画像①で実行すると無限ループが発生したのですが、cs180をDebug.Logに変更した画像②で実行すると無限ループは発生せず、画像③のように正常に動くようになりました。ですので、私は無限ループの可能性はないと考えています。
①
②
③
補足
わかりにくい箇所や説明不足の箇所について、質問いただけると助かります。
0 コメント