質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

783閲覧

回転時に壁を貫通してしまう

Rpt297

総合スコア8

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2020/05/28 10:55

編集2020/05/29 03:37

いつもお世話になっております。
現在、落ちモノパズルを作っています。
下記のプログラムのままだと下の画像のようにミノを回転させても壁を貫通しません
イメージ説明

Check_Ver()、Check_HoriL()、Check_HoriR()のコメントアウトされている部分を解除すると貫通できるようになってしまいます
イメージ説明
「Index was outside the bounds of the array」というエラーが出ます。
上のGIF画像の場合配列squaresの[縦,横]の横に10or11という値が入ったためこのエラーがでたと思うのですが、このエラーが原因で壁を貫通できるとは思えないのですが、これ以外怪しいところが見当たらないのでどのようにすれば壁を貫通しないようにできるかがわかりません。
どうか,お力添えよろしくお願いいたします

左側の壁のx座標は-1,右側の壁のx座標は10です ミノはx座標の0~9の間を移動できます
squares[0,0]はx座標0y,座標0
この状態で実行するとミノを回転させても壁は貫通はしませんがミノ同士の当たり判定はないです。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Mino_Move : MonoBehaviour 6{ 7 public Vector3 rotePos; //oミノの軸の軸調整 8 9 #region private変数 10 /// <summary> 11 /// 次の落下処理までの時間 12 /// </summary> 13 private float fall_Time; 14 /// <summary> 15 /// 次の落下処理までの時間の許可時間 16 /// </summary> 17 private float fall_PreTime = 1f; 18 /// <summary> 19 /// 突き抜けたときに戻させるキョリ 20 /// </summary> 21 private float respown = 1; 22 /// <summary> 23 /// 壁に下と左側の限界距離 -1 24 /// </summary> 25 private float limit_Side_DL = -1; 26 /// <summary> 27 /// 壁の右側の限界距離 10 28 /// </summary> 29 private float limit_Side_R = 10; 30 /// <summary> 31 /// ミノの落下速度 32 /// </summary> 33 private float down_Speed =-1; 34 /// <summary> 35 /// 次の横移動までの時間 36 /// </summary> 37 private float moveTime; 38 /// <summary> 39 /// 次の横移動可能時間の許可時間 40 /// </summary> 41 private float move_PremTime = 0.1f; 42 /// <summary> 43 /// 配列の高さ 20 44 /// </summary> 45 private int heigth = 20; 46 /// <summary> 47 /// 配列の幅 10 48 /// </summary> 49 private int width = 10; 50 #endregion 51 52 private static Transform[,] squares = new Transform[20, 10]; //縦20×横10の配列を準備 53 54 55 void Start() 56 { 57 Physics.gravity = new Vector3(0, 0, 0); 58 } 59 60 void Update() 61 { 62 MinoMove(); 63 } 64 65 void MinoMove() 66 { 67 fall_Time += Time.deltaTime; 68 if (fall_Time > (Input.GetKey(KeyCode.DownArrow) ? fall_PreTime / 10 : fall_PreTime)) 69 { 70 transform.position += new Vector3(0, down_Speed, 0); 71 fall_Time = 0;//時間の初期化 72 if (!Check_Ver()) //下の壁に貫通していないかcheck 73 { 74 transform.position += new Vector3(0, respown, 0); 75 if (!Check_Ver()) //Imino専用check 76 { 77 transform.position += new Vector3(0, respown, 0); 78 } 79 80 Squares_Save(); 81 this.enabled = false; 82 FindObjectOfType<Mino_Instance>().Instance_Mino(); 83 } 84 85 } 86 87 moveTime += Time.deltaTime; 88 if (moveTime > move_PremTime) //ミノの移動処理 89 { 90 if (Input.GetKey(KeyCode.LeftArrow)) 91 { 92 transform.position += new Vector3(-respown, 0, 0); 93 if (!Check_HoriL()) 94 { 95 transform.position += new Vector3(respown, 0, 0); 96 } 97 } 98 else if (Input.GetKey(KeyCode.RightArrow)) 99 { 100 transform.position += new Vector3(respown, 0, 0); 101 if (!Check_HoriR()) 102 { 103 transform.position += new Vector3(-respown, 0, 0); 104 } 105 } 106 moveTime = 0; 107 } 108 109 if (Input.GetKeyDown(KeyCode.Space)) //反時計回りの回転 110 { 111 //transform.TransformPoint 位置をローカル→ワールドへと変える 112 transform.RotateAround(transform.TransformPoint(rotePos), new Vector3(0, 0, 1), 90); 113 114 if (!Check_Ver())  //突き上げ処理 115 { 116 transform.position += new Vector3(0, respown, 0); 117 } 118 119 if (!Check_HoriR()) //右の壁に貫通していないかcheck 120 { 121 transform.position += new Vector3(-respown, 0, 0); 122 123 if (!Check_HoriR()) //Imino専用check 124 { 125 transform.position += new Vector3(-1, 0, 0); 126 } 127 } 128 129 if (!Check_HoriL()) //左の壁に貫通していないかcheck 130 { 131 transform.position += new Vector3(respown, 0, 0); 132 133 if (!Check_HoriL()) //Imino専用check 134 { 135 transform.position += new Vector3(respown, 0, 0); 136 } 137 } 138 139 140 } 141 else if (Input.GetKeyDown(KeyCode.LeftShift)) //時計回りの回転 142 { 143 transform.RotateAround(transform.TransformPoint(rotePos), new Vector3(0, 0, 1), -90); 144 if (!Check_Ver()) //縦方向に貫通していないかcheck 145 { 146 transform.position += new Vector3(0, respown, 0); 147 } 148 149 if (!Check_HoriR()) //右の壁に貫通していないかcheck 150 { 151 transform.position += new Vector3(-respown, 0, 0); 152 153 if (!Check_HoriR()) //Imino専用check 154 { 155 transform.position += new Vector3(-respown, 0, 0); 156 } 157 } 158 159 if (!Check_HoriL()) //左の壁に貫通していないかcheck 160 { 161 transform.position += new Vector3(respown, 0, 0); 162 163 if (!Check_HoriL()) //Imino専用check 164 { 165 transform.position += new Vector3(respown, 0, 0); 166 } 167 } 168 } 169 } 170 171 void Squares_Save() //ミノの位置を2次元配列に格納する 172 { 173 foreach(Transform _mino in transform) 174 { 175 int round_Pos_x = (int)_mino.position.x; //位置の取得 176 177 int round_Pos_y = (int)_mino.position.y; //位置の取得 178 179 squares[round_Pos_y, round_Pos_x] = _mino; //minoを2次元配列の[round_Pos_y, round_Pos_x]の位置に格納 180 } 181 182 } 183 184 bool Check_Ver() //下の壁貫通フラグ 185 { 186 foreach (Transform ver_mino in transform) 187 { 188 int round_Pos_x = (int)ver_mino.position.x; //位置の取得 189 190 int round_Pos_y = (int)ver_mino.position.y; //位置の取得 191 192 Vector2 round_Pos = new Vector2(round_Pos_x,round_Pos_y); //Ver_Flagに渡すためにVector2にする 193 194 if (Ver_Flag(round_Pos) == false) 195 { 196 return false; 197 } 198 199 //if (squares[round_Pos_y, round_Pos_x] != null) 200 //{ 201 // Debug.Log("配列 下"); 202 // return false; 203 //} 204 205 } 206 207 return true; 208 } 209 210 bool Check_HoriR() //右の貫通防止フラグ 211 { 212 foreach(Transform hori_mino in transform) 213 { 214 int round_Pos_x = (int)hori_mino.position.x; //位置の取得 215 216 int round_Pos_y = (int)hori_mino.position.y; //位置の取得 217 218 Vector2 round_Pos = new Vector2(round_Pos_x, round_Pos_y); //HoriR_Flagに渡すためにVector2にする 219 220 if (HoriR_Flag(round_Pos) == false) 221 { 222 return false; 223 } 224 225 //if (squares[round_Pos_y, round_Pos_x] != null) 226 //{ 227 // Debug.Log("配列 右"); 228 // return false; 229 //} 230 231 } 232 return true; 233 } 234 235 bool Check_HoriL() //左の貫通防止フラグ 236 { 237 foreach (Transform hori_mino in transform) 238 { 239 int round_Pos_x = (int)hori_mino.position.x; //位置の取得 240 241 int round_Pos_y = (int)hori_mino.position.y; //位置の取得 242 243 Vector2 round_Pos = new Vector2(round_Pos_x, round_Pos_y); //HoriL_Flagに渡すためにVector2にする 244 245 246 247 if (HoriL_Flag(round_Pos) == false) 248 { 249 return false; 250 } 251 252 253 //if (squares[round_Pos_y, round_Pos_x] != null) 254 //{ 255 // Debug.Log("配列 左"); 256 // return false; 257 //} 258 } 259 return true; 260 } 261 262 bool Ver_Flag(Vector2 minoEdge) //縦の判定 263 { 264 return minoEdge.y > limit_Side_DL; 265 } 266 267 bool HoriR_Flag(Vector2 minoEdge) //右側の判定 268 { 269 return minoEdge.x < limit_Side_R; 270 } 271 272 bool HoriL_Flag(Vector2 minoEdge) //左側の判定 273 { 274 return minoEdge.x > limit_Side_DL; 275 } 276 277} 278

修正:文章の修正 GIF画像の追加 位置取得時のMathf.Roundの削除

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

stdio

2020/05/29 00:39

物体の回転を前提にプログラムを書いていて、何故衝突判定で四捨五入の関数を呼んでいるのか、理解出来ません。回転しない前提のプログラムとお見受けします。 まず、どんなゲームにしたいのか質問文から一切イメージが湧いてこないので、ゲーム画面のキャプチャー画像を提示して頂けますか?
Rpt297

2020/05/29 03:42

わかりにくい質問で申し訳ございませんでした。 GIF画像を貼って修正いたしました。 四捨五入していた理由ですが、作り始めたころに座標で1.5などの半端な値が取得されることがあったので四捨五入して無理矢理直していたからです。今は四捨五入しなくても1.5などの半端な値は取得されません。
guest

回答1

0

自己解決

自己解決しました。理由は長くなるので割愛させていただきます

投稿2020/06/04 02:33

Rpt297

総合スコア8

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問