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

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

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

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

Unity

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

Q&A

1回答

552閲覧

テトリスで相手側の画面でブロックを消したい

unity_teratail

総合スコア7

C#

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

Unity

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

0グッド

0クリップ

投稿2017/11/07 08:52

編集2017/11/07 09:01

Unity,Photonを用いて通信対戦型のテトリスを作成しております。自分の画面で一列ブロックが消えると、相手画面でも同じく消えるようにしたいのですが、やり方が分かりません。ブロックは4つのCubeを空のGameObjectに入れて構成しており、GameObjectにもCube一つ一つにもPhotonViewとPhotonTransFormViewを付けました。
また、GameクラスのDeleteTetrominoAt()内でDestroyする際、PhotonNetwork.Destroyを試してみましたが、上手くいきません。
今は確認のために"I"ブロックしか生成されないようにしています。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.SceneManagement; 5 6public class Game : Photon.MonoBehaviour { 7 8 public static int Width = 10; 9 public static int Height = 20; 10 11 public static Transform[,] grid = new Transform[Width,Height]; 12 13 // Use this for initialization 14 void Start () { 15 //SpawnNextTetromino (); 16 } 17 18 public bool CheckIsAboveGrid(Tetromino tetromino){ 19 20 for (int x = 0; x < Width; ++x){ 21 22 foreach(Transform mino in tetromino.transform){ 23 24 Vector2 pos = Round (mino.position); 25 26 if (pos.y > Height ) { 27 28 return true; 29 } 30 } 31 } 32 return false; 33 } 34 35 public bool IsFullRowAt(int y){ 36 37 for (int x = 0; x < Width; ++x) { 38 if (grid [x, y] == null) { 39 40 return false; 41 } 42 } 43 return true; 44 } 45 46 public void DeleteMinoAt(int y){ 47 48 49 for (int x = 0; x < Width; ++x) { 50 51 grid [x, y].gameObject; 52 Destroy (grid [x, y].gameObject) 53 grid [x, y] = null; 54 55 } 56 } 57 58 public void MoveRowDown(int y){ 59 60 for (int x = 0; x < Width; ++x) { 61 62 if (grid [x, y] != null) { 63 64 grid [x, y - 1] = grid [x, y]; 65 66 grid [x, y] = null; 67 68 grid [x, y - 1].position += new Vector3 (0, -1, 0); 69 } 70 } 71 } 72 73 public void MoveAllRowsDown(int y){ 74 75 for (int i = y; i < Height; ++i) { 76 MoveRowDown (i); 77 } 78 } 79 80 public void DeleteRow(){ 81 82 for (int y = 0; y < Height; ++y) { 83 84 if (IsFullRowAt (y)){ 85 86 DeleteMinoAt (y) 87 88 MoveAllRowsDown (y + 1); 89 90 --y; 91 } 92 } 93 } 94 public void UpdateGrid(Tetromino tetromino){ 95 96 for (int y = 0; y < Height; ++y) { 97 98 for (int x = 0; x < Width; ++x) { 99 100 if (grid [x, y] != null) { 101 102 if (grid [x, y].parent == tetromino.transform) { 103 104 grid [x, y] = null; 105 } 106 } 107 } 108 } 109 110 foreach (Transform mino in tetromino.transform) { 111 112 Vector2 pos = Round (mino.position); 113 114 if (pos.y < Height) { 115 116 grid [(int)pos.x, (int)pos.y] = mino; 117 } 118 } 119 } 120 121 public Transform GetTransformAtGridPosition(Vector2 pos){ 122 123 if (pos.y > Height - 1) { 124 125 return null; 126 } else { 127 128 return grid [(int)pos.x, (int)pos.y]; 129 } 130 } 131 //GetRandomTetromino (), typeof(GameObject) 132// public void SpawnNextTetromino(){ 133// 134// PhotonNetwork.Instantiate ("I", transform.position, Quaternion.identity,0); 135// } 136 137 public bool CheckInsideGrid(Vector2 pos) 138 { 139 return((int)pos.x >= 0 && (int)pos.x < Width && (int)pos.y >= 0); 140 } 141 142 public Vector2 Round(Vector2 pos) 143 { 144 return new Vector2 (Mathf.Round (pos.x), Mathf.Round (pos.y)); 145 } 146 147 148 string GetRandomTetromino(){ 149 150 int randomTetromino = Random.Range (1, 8); 151 string randomTetrominoName = "Prefabs/T"; 152 153 switch (randomTetromino){ 154 155 case 1: 156 randomTetrominoName = "Prefabs/T"; 157 break; 158 case 2: 159 randomTetrominoName = "Prefabs/I"; 160 break; 161 case 3: 162 randomTetrominoName = "Prefabs/O"; 163 break; 164 case 4: 165 randomTetrominoName = "Prefabs/J"; 166 break; 167 case 5: 168 randomTetrominoName = "Prefabs/L"; 169 break; 170 case 6: 171 randomTetrominoName = "Prefabs/S"; 172 break; 173 case 7: 174 randomTetrominoName = "Prefabs/Z"; 175 break; 176 } 177 return randomTetrominoName; 178 } 179 180 public void GameOver() 181 { 182 SceneManager.LoadScene ("GameOver"); 183 } 184}

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Tetromino : MonoBehaviour { 6 7 float fall = 0; 8 public float fallspeed = 1; 9 10 public bool allowRotation = true; 11 public bool limitRotation = false; 12 13 14 // Use this for initialization 15 void Start () { 16 } 17 18 // Update is called once per frame 19 void Update () { 20 CheckUserInput (); 21 } 22 void CheckUserInput() 23 { 24 if (Input.GetKeyDown (KeyCode.RightArrow)) { 25 26 transform.position += new Vector3 (1, 0, 0); 27 28 if (CheckIsValidPosition ()) { 29 30 FindObjectOfType<Game> ().UpdateGrid (this); 31 32 } else { 33 transform.position += new Vector3 (-1, 0, 0); 34 } 35 36 37 } else if (Input.GetKeyDown (KeyCode.LeftArrow)) { 38 39 transform.position += new Vector3 (-1, 0, 0); 40 41 if (CheckIsValidPosition ()) { 42 43 FindObjectOfType<Game> ().UpdateGrid (this); 44 45 } else { 46 transform.position += new Vector3 (1, 0, 0); 47 } 48 49 } else if (Input.GetKeyDown (KeyCode.UpArrow)) { 50 51 transform.Rotate (0, 0, 90); 52 53 if (CheckIsValidPosition ()) { 54 55 FindObjectOfType<Game> ().UpdateGrid (this); 56 } else { 57 transform.Rotate (0, 0, -90); 58 } 59 60 61 } else if (Input.GetKeyDown (KeyCode.DownArrow)|| Time.time - fall >= fallspeed) { 62 transform.position += new Vector3 (0, -1, 0); 63 64 if (CheckIsValidPosition ()) { 65 66 FindObjectOfType<Game> ().UpdateGrid (this); 67 68 } else { 69 transform.position += new Vector3 (0, 1, 0); 70 71 FindObjectOfType<Game> ().DeleteRow (); 72 73 if (FindObjectOfType<Game> ().CheckIsAboveGrid (this)) { 74 FindObjectOfType<Game> ().GameOver (); 75 } 76 77 enabled = false; 78 79 FindObjectOfType<Spawner>().SpawnNext(); 80 } 81 82 fall = Time.time; 83 } 84 } 85 86 bool CheckIsValidPosition(){ 87 88 foreach (Transform mino in transform) { 89 90 Vector2 pos = FindObjectOfType<Game> ().Round (mino.position); 91 92 if (FindObjectOfType<Game> ().CheckInsideGrid (pos) == false) { 93 94 return false; 95 } 96 97 if(FindObjectOfType<Game>().GetTransformAtGridPosition(pos) != null && FindObjectOfType<Game>().GetTransformAtGridPosition(pos).parent != transform){ 98 99 return false; 100 } 101 } 102 return true; 103 } 104}

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Spawner : Photon.MonoBehaviour { 6 7 8 public void SpawnNext(){ 9 10 if (PhotonNetwork.isMasterClient) { 11 12 PhotonNetwork.Instantiate ("I", new Vector3 (5, 20, 0), Quaternion.identity, 0); 13 14 } 15 } 16 17 // Use this for initialization 18 void Start () { 19 20 SpawnNext (); 21 } 22 23 // Update is called once per frame 24 void Update () { 25 26 } 27}

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

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

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

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

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

guest

回答1

0

Photonには詳しくないため、それに依存する部分については分かりませんが、気になった点を挙げます。

生成はPhotonNetwork.Instantiate ("I", new Vector3 (5, 20, 0), Quaternion.identity, 0);でテトリミノ単位で行っていますが、削除はDestroy (grid [x, y].gameObject)とブロック単位で行っているのが気になりました。

以下のようにすれば上手くいくかもしれません。
(もっといい方法があるかもしれませんが…)

  1. テトリミノのゲームオブジェクトを生成
  2. テトリミノが配置されたら、テトリミノのゲームオブジェクトを削除し、該当する箇所にブロックのゲームオブジェクトを生成する
  3. ブロックが揃っているかチェックし、もし揃っていたらブロックのゲームオブジェクトを削除する

仮に上記で上手くいかなかったとしても、PhotonNetwork.Instantiate()で生成したテトリミノが削除されずにそのまま放置されているため、それをPhotonNetwork.Destroy()する処理は入れるべきだと思います。

投稿2017/11/08 01:45

fiveHundred

総合スコア9803

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問