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

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

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

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

Unity

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

Q&A

解決済

4回答

1114閲覧

Unityでオブジェクトの切り替えをしたい

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity

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

0グッド

0クリップ

投稿2021/08/31 15:19

編集2021/09/01 09:07

実現したいこと

Unityで2Dゲームを開発中で、aというGameObject(アニメーション付き)とbというGameObject(アニメーションなし)を、あるif文の条件式で表示または非表示にうまく切り替えることが目的です。

発生している問題・エラーメッセージ

エラー表示は特になく、Unity上でゲームを再生することは可能です。なので、原因はプログラミングによるエラーではないと考えられますが(Debug.Logで指示を書きたい領域が機能しているかをすでに確認済)、原因の箇所が全く分からずにいます。
<具体的な症状>
・以下のスクリプト参照
if(割愛)
{
ToBchange();
}
において、aはGame画面上に表示されたままアニメーションはなぜか静止する。bはGame画面上に表示されない。
else
{
ToAchange();
}
において、aはGame画面上に表示されたままアニメーションが再び動き出す。bはGame画面上に表示されない

<理想>
if(割愛)
{
ToBchange();
}
において、aはGame画面上から消え、bはGame画面上に表示される。
else
{
ToAchange();
}
において、aはGame画面上に表示され、bはGame画面上から消える。

該当のソースコード

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class PlayerManager : MonoBehaviour 6{ 7 public GameObject migimigiba; 8 public GameObject hidarihidariba; 9 10 [SerializeField] GameObject a; 11 [SerializeField] GameObject b; 12 13 14 void Start() 15 { 16 migimigiba = GameObject.Find("migiba"); 17 hidarihidariba = GameObject.Find("hidariba"); 18 } 19 20 // Update is called once per frame 21 void Update() 22 { 23 for (int i = 0; i <= 8; i++) 24 { 25 for (int j = 0; j <= 8; j++) 26 { 27 if (migimigiba.GetComponent<BluebarMove>().rightbar[i] == true && hidarihidariba.GetComponent<RedbarMove>().leftbar[j] == true) 28 { 29 ToBchange(); //Debug.Logで確認済 問題なし 30 } 31 else 32 { 33 ToAchange(); //Debug.Loでg確認済 問題なし 34 } 35 } 36 } 37 38 39 public void ToBchange() 40 { 41 a.SetActive(false); 42 b.SetActive(true); 43 } 44 45 public void ToAchange() 46 { 47 a.SetActive(true); 48 b.SetActive(false); 49 } 50 51}

試したこと

Debug.Logで指定の領域がちゃんと機能していることは確認済みです。エラーもないです。 [SerializeField] で書けば非アクティブ状態のオブジェクトも取得できるとの情報があったので、そうしましたが、目的は達成できませんでした。となると、SetActiveの使い方が間違っているのでしょうか?

追記

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class PlayerManager : MonoBehaviour 6{ 7 public GameObject migimigiba; 8 public GameObject hidarihidariba; 9 10 GameObject a; 11 GameObject b; 12 13 14 void Start() 15 { 16 migimigiba = GameObject.Find("migiba"); 17 hidarihidariba = GameObject.Find("hidariba"); 18 a = GameObject.Find("A"); 19 b = GameObject.Find("B"); 20 } 21 22 // Update is called once per frame 23 void Update() 24 { 25 if(migimigiba.GetComponent<BluebarMove>().rightbar[0] == true && hidarihidariba.GetComponent<RedbarMove>().leftbar[0] == true) 26 { 27 a.transform.position = new Vector3(-4.2f, -0.19f, 0); 28 b.transform.position = new Vector3(-1.6f, -0.19f, 0); 29 } 30 else 31 { 32 a.transform.position = new Vector3(-1.63f, -0.19f, 0); 33 b.transform.position = new Vector3(-4.13f, -0.19f, 0); 34 } 35 36 if (migimigiba.GetComponent<BluebarMove>().rightbar[0] == true && hidarihidariba.GetComponent<RedbarMove>().leftbar[1] == true) 37 { 38 a.transform.position = new Vector3(-4.2f, -0.19f, 0); 39 b.transform.position = new Vector3(-1.6f, -0.19f, 0); 40 } 41 else 42 { 43 a.transform.position = new Vector3(-1.63f, -0.19f, 0); 44 b.transform.position = new Vector3(-4.13f, -0.19f, 0); 45 } 46     というような感じで同じような処理が続いていきます。 47 } 48}

というような感じで、for文ではなく上記のように(rightbar[0]かつleftbar[0]のとき,rightbar[0]かつleftbar[1]のとき, rightbar[0]かつleftbar[2]のとき ・・・と個別に処理を書くと目的の動作が実行されました。for文だとi=8, j=8の最後の処理しか実行されないとの指摘を受け、まさにその通りでした。

ただ、これだと(rightbar[0]かつleftbar[0]~rightbar[8]かつleftbar[8]の計81個の処理をコピペする必要があり、もっとスマートに書ける処理を考え中です。)
この記載しているスクリプト内で処理が完結できればいいなと思っています。

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

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

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

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

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

YAmaGNZ

2021/08/31 22:22

SetActiveの使い方については知りませんが、ループ内で行うとループの最後の条件の処理(i=8、j=8の時の結果)となりますがいいのですか?
退会済みユーザー

退会済みユーザー

2021/09/01 01:05

再び回答して頂き、ありがとうございます。おっしゃる通り、forだとi=8, j=8の処理しか実行されませんでした。なので、for以外のベストな方法を探っています。詳細は質問内容の編集で記載しました。
YAmaGNZ

2021/09/01 01:10

追記されたソースでも migimigiba.GetComponent<BluebarMove>().rightbar[0]=true hidarihidariba.GetComponent<RedbarMove>().leftbar[0]=rue hidarihidariba.GetComponent<RedbarMove>().leftbar[1]=false の場合 a.transform.position = new Vector3(-4.2f, -0.19f, 0); が実行された直後に a.transform.position = new Vector3(-1.63f, -0.19f, 0); が実行され、最終結果が a.transform.position = new Vector3(-1.63f, -0.19f, 0); となりますがいいのですか? というかソースを出すたびになんで処理が変わるんでしょう?
YAmaGNZ

2021/09/01 01:18

なんとなくaやbの表示・非表示を切り替えるための条件の考え方がよくないように感じます。 追記されたソースを見る限り、 migimigiba.GetComponent<BluebarMove>().rightbarとhidarihidariba.GetComponent<RedbarMove>().leftbarの中にそれぞれtrueがあれば a.transform.position = new Vector3(-4.2f, -0.19f, 0); b.transform.position = new Vector3(-1.6f, -0.19f, 0); を実行し全部falseであれば a.transform.position = new Vector3(-1.63f, -0.19f, 0); b.transform.position = new Vector3(-4.13f, -0.19f, 0); を実行するという処理を作りたいように読めます。 一旦この配列の組み合わせ81通りを全部チェックする必要があるのかから考え直してはどうでしょうか?
退会済みユーザー

退会済みユーザー

2021/09/01 01:30

確かにそうですね。もう一度根本の部分から考え直して見ます。
退会済みユーザー

退会済みユーザー

2021/09/01 09:16

無事解決に至りました。いろいろアドバイス頂き、ありがとうございました。
guest

回答4

0

C#

1for (int i = 0; i <= 8; i++) 2{ 3 if(migimigiba.GetComponent<BluebarMove>().rightbar[i] == true) right = true; 4 if(hidarihidariba.GetComponent<RedbarMove>().leftbar[i] == true) left = true; 5} 6if(right && left) 7{ 8 a.transform.position = new Vector3(-4.2f, -0.19f, 0); 9 b.transform.position = new Vector3(-1.65f, 0.03f, 0); 10} 11else 12{ 13 a.transform.position = new Vector3(-1.63f, -0.19f, 0); 14 b.transform.position = new Vector3(-4.13f, -0.19f, 0); 15}

で終わりだったりしません?

投稿2021/09/01 10:11

YAmaGNZ

総合スコア10489

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

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

YAmaGNZ

2021/09/01 10:51

どのような条件時にダメだったのでしょうか?
guest

0

rightbar と leftbar の型が不明ですが List や配列であれば Linq の Any を使うのがスマートでしょう。

C#

1using System.Linq; 2 3if (migimigiba.GetComponent<BluebarMove>().rightbar.Any(n => n == true) && hidarihidariba.GetComponent<RedbarMove>().leftbar.Any(n => n == true)) { 4 a.transform.position = new Vector3(-4.2f, -0.19f, 0); 5 ... 6}

投稿2021/09/01 10:03

lehshell

総合スコア1156

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

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

0

C#

1 void Update() 2 { 3 bool flag = false; 4 5 for (int i = 0; i <= 8; i++) 6 { 7 for (int j = 0; j <= 8; j++) 8 { 9 if (migimigiba.GetComponent<BluebarMove>().rightbar[i] == true 10 && hidarihidariba.GetComponent<RedbarMove>().leftbar[j] == true) 11 { 12 flag = true; 13 } 14 } 15 } 16 17 if (flag) 18 { 19 a.transform.position = new Vector3(-4.2f, -0.19f, 0); 20 b.transform.position = new Vector3(-1.65f, 0.03f, 0); 21 } 22 else 23 { 24 a.transform.position = new Vector3(-1.63f, -0.19f, 0); 25 b.transform.position = new Vector3(-4.13f, -0.19f, 0); 26 } 27 }

投稿2021/09/01 09:42

fiveHundred

総合スコア10152

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

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

退会済みユーザー

退会済みユーザー

2021/09/01 10:30

回答ありがとうございます。 確かにこのコードでも動作しましたので、これを参考にさせて頂きます。「配列とboolの組み合わせ」ということですね! 大変勉強になりました。
guest

0

ベストアンサー

以下のコードに変更することで、目的を達成できました(動作確認済)。1度だけ81個の処理をif文の()に書くことを我慢すれば、{}内での処理を気軽にまとめて変更できるようになりました。if((A&&B)||(A&&C)||(A&&D)||・・・)と無限に使えることを知らなかったのが原因でした。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class PlayerManager : MonoBehaviour 6{ 7 public GameObject migimigiba; 8 public GameObject hidarihidariba; 9 10 GameObject a; 11 GameObject b; 12 13 14 void Start() 15 { 16 migimigiba = GameObject.Find("migiba"); 17 hidarihidariba = GameObject.Find("hidariba"); 18 a = GameObject.Find("A"); 19 b = GameObject.Find("B"); 20 } 21 22 // Update is called once per frame 23 void Update() 24 { 25 if((migimigiba.GetComponent<BluebarMove>().rightbar[0] == true && hidarihidariba.GetComponent<RedbarMove>().leftbar[0] == true) || (migimigiba.GetComponent<BluebarMove>().rightbar[0] == true && hidarihidariba.GetComponent<RedbarMove>().leftbar[1] == true) || (migimigiba.GetComponent<BluebarMove>().rightbar[0] == true && hidarihidariba.GetComponent<RedbarMove>().leftbar[2] == true)・・・全部で81個の条件を書く) 26 { 27 a.transform.position = new Vector3(-4.2f, -0.19f, 0); 28 b.transform.position = new Vector3(-1.65f, 0.03f, 0); 29 } 30 else 31 { 32 a.transform.position = new Vector3(-1.63f, -0.19f, 0); 33 b.transform.position = new Vector3(-4.13f, -0.19f, 0); 34 } 35 } 36}

投稿2021/09/01 09:15

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

fiveHundred

2021/09/01 09:43

> 1度だけ81個の処理をif文の()に書くことを我慢すれば、 ということになっていること自体、とてもいい方法だとは思えません。 代案を回答しましたので、ご確認ください。
YAmaGNZ

2021/09/01 10:08 編集

その条件って migimigiba.GetComponent<BluebarMove>().rightbarのどれかがtrue かつ hidarihidariba.GetComponent<RedbarMove>().leftbarのどれかがtrue って単純な条件に思えます 9x9のループではなく 9回のループを1つで済むんじゃないですかね?
退会済みユーザー

退会済みユーザー

2021/09/01 10:34

YAmaGNZさん 回答頂いたコードを試したのですが、elseの部分の処理がうまく動作しませんでした。ほかに回答いただいたfiveHundredさんのコードではうまく実行されました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問