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

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

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

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

Unity

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

Q&A

解決済

1回答

1896閲覧

unityで思っているように動作しない

Hayato555

総合スコア17

C#

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

Unity

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

0グッド

0クリップ

投稿2017/10/14 14:02

編集2017/10/14 14:08

###前提・実現したいこと
unityでテトリスを作ってます。 今、テトリスのミノ(ブロック)の移動のスクリプトを書いているのですが、ある部分がうまく動作しません。 このコードは、キーボードの入力でミノを動かせるようにしているのですが、縦移動(下方向)に動かしているときは ミノの回転が可能なのですが、横移動をしているとき(右および左)の移動をしているときはミノの回転ができません。 また、1秒で1マス下に落ちるようになるはずなのに、ミノを動かしている間は約1.5秒ほどになってしまいます。
何度も見直してみたのですが、原因がわかりません。誰かわかりませんか?

###該当のソースコード

C#

1using UnityEngine; 2using System.Collections; 3 4public class Imino : MonoBehaviour 5{ 6 // Time since last gravity tick 7 8 float lastFall = 0; 9 10 public float verticalTimer = 0; 11 public float horizontalTimer = 0; 12 13 public float continuosVerticalSpeed = 0.05f; 14 public float continuosHorizontalSpeed = 0.1f; 15 16 public float buttonDownWaitMax = 0.2f; 17 public float buttonDownWaitTimer = 0; 18 19 20 public bool movedImediateHorizontal = false; 21 public bool movedImediateVertical = false; 22 23 24 25 26 27 28 public bool isValidGridPos() 29 { 30 foreach (Transform child in transform) 31 { 32 Vector2 v = Grid.roundVec2(child.position); 33 34 // Not inside Border? 35 if (!Grid.insideBorder(v)) 36 return false; 37 38 // Block in grid cell (and not part of same group)? 39 if (Grid.grid[(int)v.x, (int)v.y] != null && 40 Grid.grid[(int)v.x, (int)v.y].parent != transform) 41 return false; 42 } 43 return true; 44 } 45 public void updateGrid() 46 { 47 // Remove old children from grid 48 for (int y = 0; y < Grid.h; ++y) 49 for (int x = 0; x < Grid.w; ++x) 50 if (Grid.grid[x, y] != null) 51 if (Grid.grid[x, y].parent == transform) 52 Grid.grid[x, y] = null; 53 54 // Add new children to grid 55 foreach (Transform child in transform) 56 { 57 Vector2 v = Grid.roundVec2(child.position); 58 Grid.grid[(int)v.x, (int)v.y] = child; 59 } 60 } 61 void Update() 62 { 63 64 if (Input.GetKeyUp(KeyCode.D) || Input.GetKeyUp(KeyCode.A) || Input.GetKeyUp(KeyCode.S)) 65 { 66 movedImediateHorizontal = false; 67 movedImediateVertical = false; 68 horizontalTimer = 0; 69 verticalTimer = 0; 70 buttonDownWaitTimer = 0; 71 } 72 73 // Move Left 74 75 if (Input.GetKey(KeyCode.A)) 76 { 77 if (movedImediateHorizontal) 78 { 79 if (buttonDownWaitTimer < buttonDownWaitMax) 80 { 81 buttonDownWaitTimer += Time.deltaTime; 82 return; 83 } 84 85 86 87 88 if (horizontalTimer < continuosHorizontalSpeed) 89 { 90 horizontalTimer += Time.deltaTime; 91 return; 92 } 93 } 94 if (!movedImediateHorizontal) 95 { 96 movedImediateHorizontal = true; 97 } 98 99 horizontalTimer = 0; 100 101 // Modify position 102 transform.position += new Vector3(-1, 0, 0); 103 104 // See if valid 105 if (isValidGridPos()) 106 { 107 108 // It's valid. Update grid. 109 updateGrid(); 110 } 111 else 112 // It's not valid. revert. 113 transform.position += new Vector3(1, 0, 0); 114 } 115 116 // Move Right 117 if (Input.GetKey(KeyCode.D)) 118 { 119 if (movedImediateHorizontal) 120 { 121 122 if (buttonDownWaitTimer < buttonDownWaitMax) 123 { 124 buttonDownWaitTimer += Time.deltaTime; 125 return; 126 } 127 128 if (horizontalTimer < continuosHorizontalSpeed) 129 { 130 horizontalTimer += Time.deltaTime; 131 return; 132 } 133 } 134 if (!movedImediateHorizontal) 135 { 136 movedImediateHorizontal = true; 137 138 } 139 horizontalTimer = 0; 140 141 // Modify position 142 transform.position += new Vector3(1, 0, 0); 143 144 // See if valid 145 if (isValidGridPos()) 146 { // It's valid. Update grid. 147 updateGrid(); 148 } 149 else 150 { // It's not valid. revert. 151 transform.position += new Vector3(-1, 0, 0); 152 } 153 } 154 155 // Right Rotate 156 if (Input.GetKeyDown(KeyCode.O)) 157 { 158 transform.Rotate(0, 0, -90); 159 160 // See if valid 161 if (isValidGridPos()) 162 // It's valid. Update grid. 163 updateGrid(); 164 else 165 // It's not valid. revert. 166 transform.Rotate(0, 0, 90); 167 } 168 //Left Rotate 169 if (Input.GetKeyDown(KeyCode.I)) 170 { 171 transform.Rotate(0, 0, 90); 172 if (isValidGridPos()) 173 // It's valid. Update grid. 174 updateGrid(); 175 else 176 // It's not valid. revert. 177 transform.Rotate(0, 0, -90); 178 } 179 180 // Move Downwards and Fall 181 if (Input.GetKey(KeyCode.S) || 182 Time.time - lastFall >= 1) 183 { 184 if (movedImediateVertical) 185 { 186 187 if (buttonDownWaitTimer < buttonDownWaitMax) 188 { 189 buttonDownWaitTimer += Time.deltaTime; 190 return; 191 } 192 193 194 if (verticalTimer < continuosVerticalSpeed) 195 { 196 verticalTimer += Time.deltaTime; 197 return; 198 } 199 } 200 if (!movedImediateVertical) 201 { 202 movedImediateVertical = true; 203 } 204 verticalTimer = 0; 205 206 207 // Modify position 208 transform.position += new Vector3(0, -1, 0); 209 210 // See if valid 211 if (isValidGridPos()) 212 { 213 // It's valid. Update grid. 214 updateGrid(); 215 } 216 else 217 { 218 // It's not valid. revert. 219 transform.position += new Vector3(0, 1, 0); 220 221 // Clear filled horizontal lines 222 Grid.deleteFullRows(); 223 224 // Spawn next Group 225 226 createRandObjs.Instance.spawnNext(); 227 228 // Disable script 229 enabled = false; 230 } 231 232 lastFall = Time.time; 233 } 234 } 235 236 // Use this for initialization 237 void Start() 238 { 239 240 } 241 242 243 244 245} 246

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

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

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

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

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

guest

回答1

0

ベストアンサー

おそらく、各パートの処理の順序に起因するものと思われます。

現状の順序では、

  • キーを離したときの処理
  • 左移動処理
  • 右移動処理
  • 右回転処理
  • 左回転処理
  • 下移動処理

となっています。このうち、「左移動処理」「右移動処理」「下移動処理」の3つのパートでは、移動スピード調整のためタイマーの値によってreturnでメソッドを抜けるケースがあります。

縦移動中には回転できて横移動中には回転できないという現象があるとのことですが、下移動パートは回転パートの後に位置しているので問題は顕在化しませんが、左右のいずれかの移動キーを押している場合、かなりの確率でタイマー条件に引っかかり、回転パートへ到達せずにメソッドが終了してしまうのが原因ではないでしょうか?

また、落下速度が遅くなる現象についても、同じく途中でメソッドが終了してしまうために落下処理の実行頻度が低下して、落下速度が遅くなったように見えるものと予想されます。

改善案としては、タイマー判定のあるパートでは、タイマー条件が満足されたときにreturnでメソッドを終える代わりに、フラグとなる変数を用意してそれをtrueとすることにし、そのパートの実際の移動処理部分をifで囲って、フラグ変数がfalseの時のみ移動処理が行われるようにする...というのはどうでしょう?
これならメソッドを中断させることなく後ろのパートへも処理を進めさせることができるのではないでしょうか。

[追記]
How to make a game like Tetris in Unity 5 - Part 14 - Increasing Difficultyの冒頭で左右キーを押している間に落下しなくなる問題に言及しており、これに対する処置として、この辺で「左移動」「右移動」「下移動」「回転」パートを別メソッドに分離して独立させています。こちらのスタイルの方がUpdateがシンプルになってよさそうですね。

投稿2017/10/14 16:34

編集2017/10/14 23:04
Bongo

総合スコア10807

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問