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

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

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

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

Unity3D

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

Unity

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

Q&A

解決済

3回答

907閲覧

プレハブをインスタンス化しても、2個目以降、Awakeが動かない

kudo201810

総合スコア30

C#

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

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2018/12/14 01:10

プレハブをインスタンス化すると2個目以降のインスタンス化されたものが
Awakeが動きません。

インスタンス化するオブジェクトには、プレハブ化しており
Awakeの処理を入れており、そこで、すべての子オブジェクトに
メッシュコライダーとリジッドボディを設定する処理を入れていますが
なぜか、インスタンス化の2個目以降にこのAwakeが動きません。

インスタンス化するスクリプトは、綺麗に並べるだけの処理で

無理やり、

Instantiate(blockPrefab, placePosition, q);
blockPrefab.SetActive(false);
blockPrefab.SetActive(true);

という処理をいれて非アクティブ化して、アクティブ化しているのですが
これでも、2個目以降、Awakeが動きません。

どうすればよいのでしょうか?

ちなみにプレハブではない
実体化しているものの場合は、正常に動きました。

具体的にやろうとしているのは、
粉々に破壊できるブロックを綺麗に配置しようとしています。

このブロックには破片の子オブジェクトが多数あり
その子オブジェクトにメッシュコライダーとリジッドボディを
スクリプトで設定する処理が
プレハブをインスタンス化した場合、なぜか2個目以降に動いていないため、
すり抜けてしまっていました。

色々調べたのですがわからなかったので
投稿させていただきました。
よろしくお願いいたします。

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

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

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

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

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

MMashiro

2018/12/14 08:34

こちらの環境で同じことを試してみましたが、ヒエラルキー上にPrefabオブジェクトが存在・存在していないにかかわらず何度InstantiateしてもAwake, Start共に呼ばれました。情報として投稿しておきます。
kudo201810

2018/12/14 08:57

ありがとうございます。 参考までに、プレハブにアタッチしているスクリプトのAwakeのソースは以下です。 ------ private void Awake() { var childTransform = GameObject.Find(this.gameObject.name).transform; foreach (Transform child in childTransform.transform) { if (child.name != "181214kabe_kowareru") { if (null != child.GetComponent<MeshRenderer>()) { if (null == child.GetComponent<MeshCollider>()) { child.gameObject.AddComponent<MeshCollider>(); child.GetComponent<MeshCollider>().convex = true; } if (child.GetComponent<Rigidbody>() == null) { child.gameObject.AddComponent<Rigidbody>(); child.GetComponent<Rigidbody>().isKinematic = true; } } } } } ---- うーん、なんなんでしょうか・・2個目以降、 コライダーとリジッドボディを設定する処理が動いていなくて 2個目以降が、動かないのです。
guest

回答3

0

ベストアンサー

処理は走っているが、期待する処理でないっていうパターンだと思います。
Awakeが動いていないと思った場合はAwakeの次の行に Debug.Log 等を仕込んでみると本当に動いていないかどうかの判別がつきます。
問題の本質がどこにあるのか問題の切り分けを正確にすることをお勧めします


var childTransform = GameObject.Find(this.gameObject.name).transform;

1行目のこちらですがthis.gameObject.nameのオブジェクトを取得していますが
スクリプトから複数Instantiateした場合オブジェクト名が
~~~(Clone) になります
そしてこの名前はいくつ生成されても同じ名前です
その為2つ目を生成しても上記スクリプトでは1つ目のオブジェクトが取得されてしまい実質Awakeが動いていないように見えたというのが今回の問題になります
また名前をInstantiate直後に変更してもAwakeが呼ばれるほうが先なので意味がありません

その為自身の子オブジェクトの取得方法を変更すれば解決すると思います。
自身の子オブジェクト一覧を取得する場合は検索コストがかかるGameObeject.FindではなくGetComponentInChildren<Transform>()のほうが軽く問題も少ないのでこちらををお勧めします。

csharp

1// var childTransform = GameObject.Find(this.gameObject.name).transform; 2var childTransform = GetComponentInChildren<Transform>();

投稿2018/12/14 09:14

編集2018/12/14 09:15
MMashiro

総合スコア2378

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

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

kudo201810

2018/12/14 09:47

解決いたしました。ありがとうございました。
guest

0

このblockPrefabってシーン内に(つまりヒエラルキーに)存在しますか?
それともファイルとして保存されているものを使用していますか?

前者の場合は最初のやつしかAwake呼ばれないかもなーと思ったので。

投稿2018/12/14 07:19

edo_m18

総合スコア2283

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

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

kudo201810

2018/12/14 09:12

このblockPrefabってシーン内に(つまりヒエラルキーに)存在しません。 プレハブとして存在しているものを設定しています。(プロジェクト内) シーン内に存在するものを設定すればできます。 プレハブとしてはできないのだろうかという質問です。
guest

0

Instantiate()はプレハブを「コピーして」インスタンス化する関数です。
blockPrefabはあくまでコピー元の物なので、インスタンス化してもそのままです。
コピーしたインスタンスは返り値にあり、以下の場合のblockObjが該当します。

C#

1GameObject blockObj = Instantiate(blockPrefab, placePosition, q);

投稿2018/12/14 03:19

fiveHundred

総合スコア9797

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

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

kudo201810

2018/12/14 03:28

GameObject blockObj = Instantiate(blockPrefab, placePosition, q); blockObj.SetActive(false); blockObj.SetActive(true); にしたのですが、同じでした・・。
fiveHundred

2018/12/14 03:37

2個作成したい場合は、Instantiate()を2回呼んでください。 SetActive()をしなくとも、Instantiate()で新しく生成すれば、Awake()は実行されるはずです。
kudo201810

2018/12/14 05:04

以下のようにループしております。並べて配置したかったためです。 ------------------------ void Awake() { placePosition = this.gameObject.transform.position; boxcol = blockPrefab.GetComponent<BoxCollider>(); Xsunpou = boxcol.size.x; Ysunpou = boxcol.size.y; Zsunpou = boxcol.size.z; initX = placePosition.x; initY = placePosition.y; //配置する回転角を設定 Quaternion q = new Quaternion(); ///q = Quaternion.identity; q = Quaternion.Euler(kaiten_x, kaiten_y, kaiten_z); //配置 for (int iz = 0; iz < MAX_z; iz++) { for (int iy = 0; iy < MAX_y; iy++) { for (int i = 0; i < MAX_x; i++) { placePosition.x += Xsunpou * blockPrefab.gameObject.transform.localScale.x + offset_x; GameObject blockObj = Instantiate(blockPrefab, placePosition, q); blockObj.SetActive(false); blockObj.SetActive(true); } placePosition.x = initX; //初期のX位置に戻し placePosition.y += Ysunpou * blockPrefab.gameObject.transform.localScale.y + offset_y; } placePosition.y = initY; //初期のX位置に戻し placePosition.z += Zsunpou * blockPrefab.gameObject.transform.localScale.z + offset_z; } } ------------------------ やはり、Awakeで動くはずですよね・・うーん・・。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問