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

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

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

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

Unity

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

Q&A

解決済

3回答

427閲覧

【Unity】C#:2つずつ分岐していく木のツリー構造が作りたい

GamePlayer1

総合スコア1

C#

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

Unity

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

0グッド

0クリップ

投稿2024/06/22 09:09

実現したいこと

自身と同じプレファブを2つずつ分岐させて木のツリー構造を作りたいです。

発生している問題・分からないこと

public GameObject hueru; インスペクターでプレハブ参照

Instantiate(hueru, transform); // 2つ分岐させて木のツリー構造を作りたい。
Instantiate(hueru, transform);

上記の様に、自身を親として同じプレファブを2つ複製して分岐していく木のツリー構造が作りたいのですが、徐々に3、4、5… と複製される子の数が増えていきます。
恐らく、自身と自身の子供まで複製されているのかな?と思います。
Instantiate(hueru)の様に親を指定しなければ問題は起こりませんが、
ツリー構造なので親子関係を維持したまま作りたいです。
解決方法ご教示いただけたらと思います。

実行結果のヒエラルキービュー
hueru
---hueru(Clone)
------hueru(Clone)(Clone)
------hueru(Clone)(Clone)
---hueru(Clone)
------hueru(Clone)(Clone)
------hueru(Clone)(Clone)
------hueru(Clone)(Clone)  ← 複製ごとに3、4、5と子供が増えていってしまう。

該当のソースコード

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Hueru : MonoBehaviour 6{ 7 public GameObject hueru; // インスペクターで自身と同じプレファブを参照 8 9 void Start() 10 { 11 Instantiate(hueru, transform); // 2つ分岐させて木のツリー構造を作りたい。 12 Instantiate(hueru, transform); 13 } 14}

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

Resources.Loadを使うと回避できましたが、リソースを多く使い公式も非推奨との事ですので、ゆくゆくは使わない様にしたいです。

public GameObject hueru = Resources.Load<GameObject>("hueru");
Instantiate(hueru, transform);
Instantiate(hueru, transform);

補足

特になし

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

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

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

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

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

fiveHundred

2024/06/22 11:17 編集

「インスペクターで自身と同じプレファブを参照」とありますが、本当にプレハブ(シーン上のオブジェクトではない)ですか?
fiveHundred

2024/06/22 12:25

というか「自身と同じオブジェクト」と意味っぽいですね。 そのつもりで回答しましたので、間違っていたら指摘してください。
GamePlayer1

2024/06/23 08:58 編集

ありがとうございます。 失礼しました。 Projectタブにあるプレファブをちゃんと参照しているのですが、 初回起動用の GameDirector ゲームオブジェクトのスクリプトの方も記載するのを忘れました。 シーン上には GameDirector のみある状態です。 --------------------------------------------------------------------------- using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameDirector : MonoBehaviour {   public GameObject hueru; // 元となる木のプレファブ   void Start()   {   Instantiate(hueru, transform); // 1つ目の木を作る。   } } --------------------------------------------------------------------------- using System.Collections; using System.Collections.Generic; using UnityEngine; public class Hueru : MonoBehaviour {   public GameObject hueru; // インスペクターで自身と同じプレファブを参照   void Start()    {    Instantiate(hueru, transform); // 2つ分岐させて木のツリー構造を作りたい。    Instantiate(hueru, transform);    } } ---------------------------------------------------------------------------
GamePlayer1

2024/06/23 09:24 編集

また、下記の様に親transformを指定せずに、後から指定すると見かけ上は上手くいくのですが、 内部的には新しい hueru が生成されてるのか怪しい挙動をします。(検証中) Instantiate(hueru, transform); と書けば、自身と同じプレファブの、別のクローンが生成される訳じゃないのでしょうか。 2つ同時に Instantiate(hueru, transform); Instantiate(hueru, transform); と記載するのがまずいのでしょうか。 // 見かけ上は上手くいった例 void Start()  {    GameObject obj1 = Instantiate(hueru);    GameObject obj2 = Instantiate(hueru);    obj1.transform.SetParent(transform);    obj2.transform.SetParent(transform);  } 
guest

回答3

0

ベストアンサー

こちら(2022.3.17f1)で確認したところ、

  • Hueru内でDebug.Log(hueru.IsPrefabDefinition());(※)を出力するとFalseになる(※:using Unity.VisualScripting;が必要)
  • 新たにhueru2プレハブファイルを作成(スクリプトは同じHueru)し、hueruではhueru2を、hueru2ではhueruを参照すると正しい動作になる

となったので、インスペクターで自身と同じプレハブファイルを参照しようとすると、そのプレハブファイルではなく、生成済みの自身のゲームオブジェクトを参照してしまうようです。

不具合なのか仕様なのかは分かりませんが、最新版の動作を確認した上で、Unity公式に要望を出したほうがいいかもしれませんね。

あと、現状のコードだと無限ループになる気がしますが、その点は大丈夫ですか?
(先ほどの内容は、抜ける処理を追加して確認しました)

投稿2024/06/23 11:44

fiveHundred

総合スコア10037

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

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

GamePlayer1

2024/06/24 12:30

 こちら(Unity 2022.1.1f1)で再現できました。  詳しく調べていただきありがとうございます。 >Hueru内でDebug.Log(hueru.IsPrefabDefinition());(※)を出力するとFalseになる(※:using Unity.VisualScripting;が必要)     こちら、使いやすいメソッドを教えていただきありがとうございます。 >新たにhueru2プレハブファイルを作成(スクリプトは同じHueru)し、hueruではhueru2を、hueru2ではhueruを参照すると正しい動作になる  凄くシンプルな解法をありがとうございます!  再現できました。 >インスペクターで自身と同じプレハブファイルを参照しようとすると、そのプレハブファイルではなく、生成済みの自身のゲームオブジェクトを参照してしまうようです。  弾丸が分裂していくような物はゲームでよく使いそうですが、不具合なのか仕様なのか確認してみよう   と思います。 >あと、現状のコードだと無限ループになる気がしますが、その点は大丈夫ですか?   static int count で一定の処理数に達したら終わる様にしました。 ------------------- ※追記:Start()内で複製したのがダメなのかと思い、Update()内で試しましたが、同じ結果になりました。
guest

0

インスペクターで自身と同じプレファブを参照

あなたが設定したと言っている「プレファブ」は、プレハブではなくシーンで設置済みのhueruゲームオブジェクトです。
そのため、transformはシーン上のhueruのものであるため、既存のhueruに新しいhueruが追加されます。

ちゃんと以下の手順でプレハブのファイルを作成・設定してください。

  1. プレハブ化したいゲームオブジェクトをProjectタブ(ファイル一覧)にドラッグ&ドロップする
  2. プレハブのファイルが作成されるので、そのファイル自体を対象のコンポーネントの設定欄にドラッグ&ドロップする

投稿2024/06/22 12:25

fiveHundred

総合スコア10037

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

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

GamePlayer1

2024/06/23 10:13

ありがとうございます。 シーン上には GameDirectorオブジェクト しかなく、hueru はプレハブになっています。 質問へのコメント欄に詳細記載しました。
guest

0

GameObjectをpublicではなくstaticで宣言した後に間接的にプレファブを参照する方法でも上手くいきました。
staticだと前の状態を引き継がない状態で新規に複製できる様です。
※以下、ループを抜ける処理は記載していません。

// GameDirector.cs using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameDirector : MonoBehaviour { public static GameObject hueru; // staticで宣言 public GameObject hueruTemp; // インスペクタービューでプレファブを参照 void Start() { hueru = hueruTemp; // staticゲームオブジェクトに代入 Instantiate(hueru, transform); // 複製 } }
 // Hueru.cs using System.Collections; using System.Collections.Generic; using UnityEngine; public class Hueru : MonoBehaviour { GameObject hueru = GameDirector.hueru; // GameDirectorのstaticゲームオブジェクトを参照 void Start() { Instantiate(hueru, transform); // 2つに複製 Instantiate(hueru, transform); } }

投稿2024/06/22 09:41

編集2024/06/27 11:26
GamePlayer1

総合スコア1

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.40%

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

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

質問する

関連した質問