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

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

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

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

Unity

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

Q&A

3回答

9056閲覧

Unity プレハブ(GameObject)の参照を保存(永続化)し、ロードする方法

retas

総合スコア49

C#

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

Unity

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

0グッド

1クリップ

投稿2018/08/17 14:17

例えばUnityのインスペクターで、Prefabへの参照をドラッグアンドドロップやピッカーでセットすることがありますが
そのインスペクターの欄にセットされているプレハブが、ゲーム中に変更されるものとします。

オブジェクトそのものではなく、そこの欄になんのPrefabがセットされているかという参照を保存したいのですがどうすればいいでしょうか。

また、永続化したその参照データをロードした後、インスタンスを生成する方法はありますでしょうか。

イメージ説明

うまく言葉で説明できませんが、Unity GUI上でやっているように、
インスペクターに参照をセットしたら、スクリプトからFindやResorcesを使わなくてもプロパティでアクセスできてインスタンス生成ができるので、それと同じことをやりたいです。

上記画像のように、インスペクターにセットされているアセットからのプレハブの参照をデータ保存して、復元をするためにはどうすればいいのでしょうか。

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

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

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

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

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

guest

回答3

0

ちょっと気になるご質問だったので調べてみましたが、すみませんがこれだという情報は得られませんでした...

エディタ上での制作中にはAssets内の好きなプレハブへの参照をセットすることができますが、ビルドしたプログラムにおいては、使いたい各種プレハブはResources内に仕込んでおいたり、アセットバンドルとして供給したり、あるいはシーン上にあらかじめ全種類こっそり配置しておくなど工夫してやらないと、そもそもプレハブが存在せずアクセスできないかと思います。

Resourcesを使わない...という制限は破ってしまいましたが、下記のようにResourcesへのアクセスをメソッド内に隠してしまい、メソッドを使う側からは直接プレハブ参照を保存・復元しているように見せかけるのはどうでしょうか?

C#

1using System.Collections; 2using UnityEngine; 3 4public class Spawner : MonoBehaviour 5{ 6 public GameObject FruitPrefab; 7 8 // 「SavePrefab」という名前だが、実際には... 9 private static void SavePrefab(GameObject prefab) 10 { 11 // ...与えられたプレハブの名前だけをPlayerPrefsに保存する 12 var prefabName = prefab == null ? string.Empty : prefab.name; 13 PlayerPrefs.SetString("PrefabName", prefabName); 14 PlayerPrefs.Save(); 15 } 16 17 // 「LoadPrefab」という名前だが、実際には... 18 private static GameObject LoadPrefab() 19 { 20 // PlayerPrefsに保存されている名前と同名のプレハブをResourcesからロードして返す 21 var prefabName = PlayerPrefs.GetString("PrefabName"); 22 return string.IsNullOrEmpty(prefabName) ? null : Resources.Load<GameObject>("Prefabs/" + prefabName); 23 } 24 25 private void OnApplicationQuit() 26 { 27 SavePrefab(this.FruitPrefab); 28 } 29 30 private IEnumerator Start() 31 { 32 this.FruitPrefab = LoadPrefab(); 33 while (true) 34 { 35 yield return new WaitWhile(() => this.FruitPrefab == null); 36 37 var fruit = Instantiate( 38 this.FruitPrefab, 39 this.transform.position, 40 Quaternion.Euler(0.0f, 0.0f, Random.value * 360.0f)); 41 fruit.name = this.FruitPrefab.name; 42 Destroy(fruit, 10.0f); 43 yield return new WaitForSeconds(3.0f); 44 } 45 } 46}

ご質問者さんのご要望の通りの動作ではなくて申し訳ないですが、使いたいプレハブはAssets/Resources/Prefabsに入れておいて...

Assets

終了時にプレハブ名を保存して、次回起動時にその名前のプレハブをロードしてセットすれば、プレハブへの参照を保存しているかのように見えませんかね...?

プレビュー

投稿2018/08/18 01:10

Bongo

総合スコア10807

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

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

retas

2018/08/18 02:47

サンプルまで作成していただきご丁寧にありがとうございます。 私も英語で「unity save prefab reference」等で調べてみたりもしたのですがわからず、質問してみました。 やはりResourcesを使うしか方法はないようですね。
guest

0

プレハブが完全に動的に生成してるものだとダメですが、パターンが決まっている場合(例えば10種の内1種とか)であれば、そいつを配列に入れておくことで何とかなるかもしれません。

public GameObject[] prefabs;←こいつは永続。Project内のプレハブを複数入れておく。
public int prefabId;←どのプレハブを使うか。ここの値を変えたり保存したりする。
player = prefabs[prefabId];←呼び出し時。

投稿2018/08/20 06:44

sakura_hana

総合スコア11425

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

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

0

GameObject型の変数を作ってそこに、インスペクターで設定したGameObjectを代入するだけでいいんではないでしょうか。
何か違う風にとらえていたらすいませんが。GameObject.Findという言葉も出てきていたので、そんな感じなのではないかと考えました。

投稿2018/08/17 14:37

編集2018/08/17 14:41
UDON3

総合スコア80

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

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

retas

2018/08/18 02:52

そのインスペクターで設定されている参照を保存し、復元したいということでした。 FindやResourceを使うのはインスペクター上で参照をセットしていない場合ですよね。 スクリプトで、その作業を経由せず参照自体を得る方法はないのかなと思いまして。
UDON3

2018/08/18 04:38

あなたのしたいことは、Inspectorで指定しないということでしょうか。 質問なのですが、FindやResourceを使わない理由はなんですか。 もしかすると役に立てるかもしれません。
retas

2018/08/18 14:39

それらの方法は知っています。知ってることはわざわざ質問しません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問