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

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

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

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

Unity

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

Q&A

解決済

1回答

563閲覧

【Unity】動的に生成したPrefabについているボタンを押し、動的に生成された別PrefabをDestroyしたい

RyotaTakada

総合スコア6

C#

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

Unity

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

0グッド

1クリップ

投稿2020/05/06 04:03

編集2020/05/06 07:36

前提・実現したいこと

私自身Unityやプログラミングに触れたことがほぼなく、独学での勉強のため言葉足らずになってしまう箇所などがあるかもしれませんが、ご了承くださいm(_ _)m

子供向けの英語の勉強ゲームを作っているのですが、Destroy関数を使用する際に問題にぶつかってしまいました。

ゲームの構成としては

●カエルオブジェクト×1
●題材オブジェクト×1
●ハエオブジェクト×3(それぞれのハエにはアルファベット1文字が振られている)

上記3種類のオブジェクトで成り立っており、
題材オブジェクトを英語で読んだ時の頭文字と同じ頭文字が書いてあるハエオブジェクトをクリックすると正解(カエルの表情が笑顔になる)、
違うハエオブジェクトをクリックすると不正解(カエルの表情が泣き顔になる)という内容のゲームを作ろうとしています。

流れとしては
ハエオブジェクトの子についているボタンを押すとPushButton()関数が実行され、カエルオブジェクトがDestroyされ、別の表情のカエルオブジェクトがInstantiateされるという流れになっています。
また、frogObj = Instantiate(frogNormal); というように、一度frogObjに格納した上でDestroy(frogObj);を実行しようとしています。

別の表情のカエルオブジェクトをInstantiateすることは成功するのですが、元々あったカエルオブジェクトを削除することがうまくいきません。

よろしくお願い致しますm(_ _)m

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

別の表情のカエルオブジェクトをInstantiateすることには成功するのですが、
元々あった変えるオブジェクトを削除することができません。

該当のソースコード

もしかするとInstantiateやDestroy以外の部分のコードが悪さをしているのかもしれませんので、
現状のコードをそのまま載せます。

↓FrogGameManager.cs↓

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5 6namespace frogGame 7{ 8 public class FrogGameManager : MonoBehaviour 9 { 10 // Inspectorパネルで各ゲームオブジェクトにPrefabを設定 11 // カエルは4種類の表情 12 public GameObject frogNormal; 13 public GameObject frogSmile; 14 public GameObject frogSad; 15 public GameObject frogCatch; 16 17 // ハエオブジェクト 18 public GameObject fly; 19 20 // 題材オブジェクト(配列) 21 public GameObject[] subject; 22 23 // どの題材オブジェクトを使用するかを決めるための変数 24 public int number; 25 26 27 public GameObject frogObj; 28 public GameObject flyObj; 29 public GameObject subObj; 30 31 // 題材オブジェクトの答えを格納するための変数 32 public string answer; 33 34 // ハエオブジェクトそれぞれのアルファベットを設定するための変数 35 public string choise1; 36 public string choise2; 37 public string choise3; 38 39 40 // Start is called before the first frame update 41 void Start() 42 { 43 // 題材オブジェクトを生成 44 subObj = Instantiate(subject[number], new Vector3(-6.0f, 2.5f), Quaternion.identity); 45 // カエルオブジェクトを生成 46 frogObj = Instantiate(frogNormal, new Vector3(-6.0f, -2.5f), Quaternion.identity); 47 48 // 3匹のハエを生成し、それぞれのランダム移動範囲を指定 49 for (int i = 0; i <= 2; i++) 50 { 51 flyObj = Instantiate(fly, new Vector3(Random.Range(-2.5f, 6.5f), Random.Range(-3.0f, 3.0f)), Quaternion.identity); 52 var flyController = flyObj.GetComponent<FlyController>(); 53 54 if (i == 0) 55 { 56 flyController.X_MAX_MOVE_RANGE = 4.0f; 57 flyController.X_MIN_MOVE_RANGE = -1.0f; 58 flyController.Y_MAX_MOVE_RANGE = 3.5f; 59 flyController.Y_MIN_MOVE_RANGE = 1.6f; 60 61 flyController.choise = choise1; 62 } 63 64 if (i == 1) 65 { 66 flyController.X_MAX_MOVE_RANGE = 0.0f; 67 flyController.X_MIN_MOVE_RANGE = -2.0f; 68 flyController.Y_MAX_MOVE_RANGE = -1.2f; 69 flyController.Y_MIN_MOVE_RANGE = -3.0f; 70 71 flyController.choise = choise2; 72 } 73 74 if (i == 2) 75 { 76 flyController.X_MAX_MOVE_RANGE = 6.5f; 77 flyController.X_MIN_MOVE_RANGE = 3.0f; 78 flyController.Y_MAX_MOVE_RANGE = -1.2f; 79 flyController.Y_MIN_MOVE_RANGE = -3.0f; 80 81 flyController.choise = choise3; 82 } 83 } 84 85 } 86 87 public void PushButton() 88 { 89 // ここのDestroyがうまくいきません。 90 Destroy(frogObj); 91 Debug.Log("Destoyed frogNormal."); 92 93 // このInstantiateは正常に動きます。 94 frogObj = Instantiate(frogCatch, new Vector3(-6.0f, -2.5f), Quaternion.identity); 95 Debug.Log("Instantiated frogCatch."); 96 } 97 } 98} 99

↓FlyController.cs↓

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using frogGame; 5using UnityEngine.UI; 6 7public class FlyController : MonoBehaviour 8{ 9 private bool activeMethod; 10 11 private bool caught; 12 public float speed = 10.0f; 13 14 private bool isReachTargetPosition; 15 private Vector3 targetPosition; 16 17 public float X_MIN_MOVE_RANGE; 18 public float X_MAX_MOVE_RANGE; 19 public float Y_MIN_MOVE_RANGE; 20 public float Y_MAX_MOVE_RANGE; 21 public float SPEED = 0.02f; 22 23 public Text text; 24 public string choise; 25 26 private void Start() 27 { 28 activeMethod = true; 29 caught = false; 30 this.isReachTargetPosition = false; 31 decideTargetPosition(); 32 33 text.text = choise; 34 } 35 36 private void Update() 37 { 38 if(activeMethod == true) 39 { 40 decideTargetPosition(); 41 42 transform.position = Vector3.MoveTowards(transform.position, targetPosition, SPEED); 43 44 if (transform.position == targetPosition) 45 { 46 isReachTargetPosition = true; 47 } 48 } 49 50 if(caught == true) 51 { 52 float step = speed * Time.deltaTime; 53 transform.position = Vector2.MoveTowards(transform.position, new Vector2(-6.0f, -2.5f), step); 54 } 55 56 } 57 58 public void decideTargetPosition() 59 { 60 if (!isReachTargetPosition) 61 { 62 return; 63 } 64 65 targetPosition = new Vector3(Random.Range(X_MIN_MOVE_RANGE, X_MAX_MOVE_RANGE), Random.Range(Y_MIN_MOVE_RANGE, Y_MAX_MOVE_RANGE)); 66 isReachTargetPosition = false; 67 } 68 69 public void PushedButton() 70 { 71 activeMethod = false; 72 caught = true; 73 } 74}

###追記
実際の挙動を動画し、Youtubeに限定公開しました。
必要であればこちらもご覧くださいm(_ _)m

カエルゲーム挙動動画

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

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

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

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

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

tsuki01

2020/05/06 05:13

Destroyに関しては特に問題ない様な気がします。 「発生している問題・エラーメッセージ」の欄に記載している、"元々あったカエルオブジェクト"というのは、Startメソッド内で生成しているオブジェクトでしょうか? それとも、あらかじめUnityプロジェクトのHerarchy上に存在するオブジェクトでしょうか? もし後者であれば、Destroyで消えないかもしれません。
RyotaTakada

2020/05/06 07:30

ありがとうございます! 元々あったオブジェクトというのは、Startメソッド内で生成しているオブジェクトです。 上記のスクリプトでUnity側でもエラーがないため、原因が何なのかが理解できていない状態となっています。。。
tsuki01

2020/05/06 09:30

返信と動画リンクありがとうございました。 動画を拝見しましたが、ログも出ているしInstantiateも記載頂いているように出来ていますね。 また、frogObj自体がGameObjectとして定義されているので、「Destroy(frogObj);」もしくは「Destroy(frogObj.gameobject);」のどちらでも消えそうですし。。 パッとお役に立てず申し訳ないですが、現状は以下などで地道にデバッグすることしか思い浮かばない状態です。 1、Canvas上に仮のボタンを配置し、そこからFrogGameManagerクラスのPushButtonメソッドを直接読んで確認してみる。もし消えるなら、FlyControllerクラスが影響している? 2、Destroyではなく、SetActive(false)などを指定した場合も状態が変わらないか確認してみる。
RyotaTakada

2020/05/06 11:40

ご覧いただきありがとうございます! ご提示いただいた1.2.の方法を試してみましたが、やはりうまく動きませんでした。。。 そのため今回は、新しく生成するカエルオブジェクトのOrder in Layerを1に設定し、無理やりオブジェクトが変わったように見せる形にしました。笑 なにか原因が分かり次第、こちらの投稿を更新させていただきますm(_ _)m
tsuki01

2020/05/06 12:57

提示したものを試して頂いてありがとうございます。 やはりダメだったとのことで申し訳ありません。。 はい、もし原因分かりましたらぜひお願いいたします。 他の方からの回答もあることを祈ってます。
guest

回答1

0

ベストアンサー

手元でうまく再現できなかったのでとりあえずの案として
まず原因の切り分けを行うためにFrogGameManager.cs単体で動作するかを見てみるとかですかね。

↓ 私がよくやるのはとりあえず画面クリックしたらメソッド叩くようにして動作確認する方法です

cs

1 void Update() { 2 if (Input.GetMouseButtonDown(0)) { 3 PushButton(); 4 } 5 }

これをどこかに入れてもらうと、画面をクリックするとPushButtonが呼び出されて処理が走るかと思います。デバッグログが出ているのでおそらく動くとは思うんですが、念の為です。

次に、参照がちゃんと取れているかを確認してみます。消す前、消したあと、作ったあとでfrogObjの名前を表示してみることで参照がどうなってるかをチェックしてみます。

cs

1 public void PushButton() 2 { 3 // ここのDestroyがうまくいきません。 4 Debug.Log("[BEFORE DESTROY] frogObj is " + frogObj.name); 5 Destroy(frogObj); 6 Debug.Log("Destoyed frogNormal."); 7 8 Debug.Log("[AFTER DESTROY] frogObj is " + frogObj.name); 9 10 // このInstantiateは正常に動きます。 11 frogObj = Instantiate(frogCatch, new Vector3(-6.0f, -2.5f), Quaternion.identity); 12 Debug.Log("[INSTANTIATE] frogObj is " + frogObj.name); 13 Debug.Log("Instantiated frogCatch."); 14 }

あとはそもそもDestroyがちゃんと動くのかを確かめるためにインスタンス化の部分を一旦コメントアウトしてみるのも手です。原因を切り分けます。

cs

1 public void PushButton() 2 { 3 // ここのDestroyがうまくいきません。 4 Debug.Log("[BEFORE DESTROY] frogObj is " + frogObj.name); 5 Destroy(frogObj); 6 Debug.Log("Destoyed frogNormal."); 7 8 // このInstantiateは正常に動きます。 9 //frogObj = Instantiate(frogCatch, new Vector3(-6.0f, -2.5f), Quaternion.identity); 10 //Debug.Log("[INSTANTIATE] frogObj is " + frogObj.name); 11 //Debug.Log("Instantiated frogCatch."); 12 }

投稿2020/05/08 04:56

hogefugapiyo

総合スコア3302

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

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

RyotaTakada

2020/05/09 01:57

お返事が遅れてしまい申し訳ございません。 ご回答ありがとうございます! 一つ一つ順を追って正常に動作しているのかを確かめるということですね。 こちらの方法で一度試してみようと思います! ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問