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

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

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

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

1回答

1547閲覧

ターン制ゲームのコルーチン

oniku_tabetai

総合スコア1

C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

0クリップ

投稿2020/05/26 09:56

編集2020/05/26 10:01

unity2Dでゲームを作成しております。

<実現したいこと>
ターン制のゲームを作成したいです。
コルーチンを使用して
①まず敵が攻撃する場所を出力(ランダムレンジを使ってます)。
②その後に自分が操作するターンがきてボタンを押してキャラクターを動かす(真ん中、右、左)、
③①で指定した数字の部分に敵の攻撃が開始。
1秒待機後にまた、①〜③の開始をしたいです。

<現状>
敵の攻撃場所の出力と攻撃だけはできたのですが、一度行われた後に繰り返しの処理が行われません。
また、プレイヤーのターンをboolで管理しボタンは押せるようにはなるのですが、押した際にターンを相手に返してあげ、moveメソッドにstringで返した値が移入されず移動がされません。

下記コードです。初心者で説明が拙く、お手数をおかけしますがアドバイスをいただけますと幸いです。
スクリプトはプレイヤーとエネミーに分けております。攻撃に関してのプログラムはすでに完了しており、攻撃は行われるようになっております。

今後①の場所を順番に複数指定して(右左といったように)、②も順番に押していき、所定の順番まで押し終わったら(右左)③攻撃が開始されようにして行きたいと思っているのでアドバイスをいただけますと幸いです。

EnemyManager

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5using UnityEngine.EventSystems; 6 7using System; 8 9public class EnemyManager 10{ 11 [SerializeField] 12 PlayerManager playerManager; 13 public Text targetText; 14 15 [NonSerialized] 16 public static bool Oppsiteturn1 = false; 17 18 [NonSerialized] 19 public static bool Oppsiteturn2 = false; 20 21 public int positon2; 22 public string direction2; 23 24 25 void Start() 26 { 27 Oppsiteturn1 = true; 28 fireCoroutine = StartCoroutine(StartFire()); 29 30 } 31 32 void Update() 33 { 34 direction2 = playerManager.direction; 35 36 } 37 38 39 40 41 IEnumerator StartFire() 42 { 43 44 while (Oppsiteturn1) 45 { 46 OnAttack1(); 47 Oppsiteturn1 = false; 48 //ここはtrueにできて移動のボタンはは出てくる 49 PlayerManager.isplayertrun = true; 50 51 } 52 53 54 55 while (Oppsiteturn2) 56 { 57 //ここのログにはfalseと出てくる。 58 Debug.Log(Oppsiteturn2); 59 60 //何も動きませんでした。 61 playerManager.Move(direction2); 62        63 64 OnAttack2(positon2); 65 Oppsiteturn2 = false; 66 67 } 68 69     //これをtrueにすることで繰り返し処理ができると考えたができませんでした。 70 Oppsiteturn1 = true; 71 72 73 74 75 } 76 77 public void OnAttack1() 78 { 79 int position = UnityEngine.Random.Range(0, 3); 80 81 82 switch (position) 83 { 84 case 0: 85 86 87 targetText.text += "真ん中,"; 88 positon2 = position; 89 90 91 92 break; 93 94 case 1: 95 96 targetText.text += "右,"; 97 positon2 = position; 98 99 100 break; 101 case 2: 102 103 104 targetText.text += "左,"; 105 positon2 = position; 106 107 108 break; 109 110 111 } 112 113 114 } 115 116 117 118 public void OnAttack2(int position) 119 { 120 int healElement = UnityEngine.Random.Range(0, 257); 121 122 123 124 switch (position) 125 { 126 case 0: 127 128   Debug.Log("0番目の攻撃"); 129 130 131 break; 132 133 134 case 1: 135 136 Debug.Log("1番目の攻撃"); 137 138 break; 139 140 141 case 2: 142 Debug.Log("2番目の攻撃"); 143 break; 144 145 146 } 147 } 148 149

PlayerManager

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5using UnityEngine.EventSystems; 6using System; 7using UnityEngine.SceneManagement; 8 9public class PlayerManager : 10{ 11 [SerializeField] 12 EnemyManager enemyManager; 13 14 [SerializeField] 15 GameObject gameManager; 16 17 GameObject playerCenter, playerRight, playerLeft; 18 19 [NonSerialized] 20 public static bool isplayertrun=false; 21 [SerializeField] 22 GameObject centerbutton,rightbutton,leftbutton; 23 24 25 26 27 28 29 void Update() 30 { 31 //ここの表示と非表示まではうまく行きました。 32 if (isplayertrun) 33 { 34 centerbutton.SetActive(true); 35 leftbutton.SetActive(true); 36 rightbutton.SetActive(true); 37 38 39 } 40 else 41 { 42 centerbutton.SetActive(false); 43 leftbutton.SetActive(false); 44 rightbutton.SetActive(false); 45 } 46} 47 48 49   50 public string OnbuttonCenter() 51 { 52 53 direction = "center"; 54 return direction; 55 } 56 57 //ボタンにアタッチしてます。 58 public void OnButtonCenter() 59 { 60 OnbuttonCenter(); 61 isplayertrun = false; 62 63 //ここがtrueにならずに上述のEnemyManagermのDebug.logではではfalseになってしまいます。 64 EnemyManager.Oppsiteturn2 = true; 65 66 67 } 68 69 public string OnbuttonRight() 70 { 71 72 direction = "right"; 73 return direction; 74 75 76 77 } 78//ボタンにアタッチしてます。 79 public void OnButtonRight() 80 { 81 OnbuttonRight(); 82 isplayertrun = false; 83 EnemyManager.Oppsiteturn2 = true; 84 85 86 } 87 88 89 90 91 public string OnbuttonLeft() 92 { 93 94 direction = "left"; 95 return direction; 96 97 } 98//ボタンにアタッチしてます。 99 public void OnButtonLeft() 100 { 101 OnbuttonLeft(); 102 isplayertrun = false; 103 EnemyManager.Oppsiteturn2 = true; 104 105 106 } 107 108 109//ここもEnemyManagerに上記のOnButtonで選んだstringを代入してあげて動かしてあげたいのですがうまく行きません。 110 111 public void Move(string direction) 112 { 113 114 switch (direction) 115 { 116 case "right": 117 118 activated = 2; 119 120 break; 121 case "left": 122 123 activated = 0; 124 125 break; 126 case "Center": 127 128 activated = 1; 129 130 break; 131 } 132 133 if (activated == 0) 134 { 135 playerLeft.SetActive(true); 136 playerCenter.SetActive(false); 137 playerRight.SetActive(false); 138 139 } 140 else if (activated == 1) 141 { 142 playerLeft.SetActive(false); 143 playerCenter.SetActive(true); 144 playerRight.SetActive(false); 145 146 } 147 else if (activated == 2) 148 { 149 playerLeft.SetActive(false); 150 playerCenter.SetActive(false); 151 playerRight.SetActive(true); 152 } 153 } 154 155 156} 157

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

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

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

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

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

guest

回答1

0

ベストアンサー

■ループさせる
コルーチンは勝手にループしません。
もう一度StartCoroutineするか、StartFire内部に全体を包むwhileを追加して無限ループ状態にする必要があります。
ちなみにyield return new WaitForSeconds(1.0f);を入れると1秒待機します。

playerManager.Moveが動かない
PlayerManagerにdirectionという変数が無いのでそもそもエラーが出る気がします。(質問記載時のミスでしょうか?)
また、わざわざEnemyManagerでdirection2を取得している意味が無いのでPlayerManagerのprivate変数で完結させた方がいい気がします(結局処理しているのはPlayerManager内なので)。
動かない原因ははっきりとは分かりませんが、Updateでdirection2が変更される前にplayerManager.Moveが実行されているせいで変化が無いのかな?と思います。このコードだと1回のUpdateが実行されるより早くwhileが実行される気がします。


ただ、そもそも論としてこの内容をコルーチンでやるべきではないと思います。

現在の状態を示す変数を用意して、
「①から②に状態が変わった時の処理(Updateで判別or状態を変える時に特定メソッド呼び出し)」「②の時だけ有効な処理(ボタンが押された時等)」「③から①に進む処理」などをそれぞれ作った方がいいのではないかと思います。

直接利用出来るかは別として、「unity 状態管理」でググると参考になるかと思います。
(初心者さんであれば自分で理解出来る範囲で実装するのがよいかと思います)

投稿2020/05/27 02:01

編集2020/05/27 02:01
sakura_hana

総合スコア11427

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

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

oniku_tabetai

2020/06/06 12:24

updateでの切り替えを行うことで解決ができました。 ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問