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

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

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

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

Q&A

解決済

1回答

2251閲覧

Instantiateのジェネリック

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

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

0グッド

0クリップ

投稿2018/08/12 09:11

前提・実現したいこと

以前こちらでInstantiateの質問をさせていただいて、
理解したつもりだったのですが、意図したいコードを書くとエラーになってしまいました。

前提条件。

Cubeオブジェクトには、CubeScriptスクリプトコンポーネントとSampleスクリプトコンポーネントをアタッチしています。

エラー①

下記、cubeオブジェクトを生成して、生成したものにアタッチしているCubeScriptコンポーネントを取得できるはずと
思っているのですが、エラーになってしまいます。

C#

1 [SerializeField] 2 GameObject cube; 3 4 // Use this for initialization 5 void Start () { 6 CubeScript cubes = Instantiate<CubeScript>(cube); 7 }

エラーメッセージ

Assets/GameManager.cs(11,22): error CS1502: The best overloaded method match for `UnityEngine.Object.Instantiate<CubeScript>(CubeScript)' has some invalid arguments
Assets/GameManager.cs(11,46): error CS1503: Argument `#1' cannot convert `UnityEngine.GameObject' expression to type `CubeScript'

エラー②

下記、cubeオブジェクトを生成して、生成したものにアタッチしているSampleコンポーネントを取得できるはずと
思っているのですが、エラーになってしまいます。

C#

1 [SerializeField] 2 CubeScript cubes; 3 4 void Start () { 5 Sample sp = Instantiate<Sample>(cubes); 6 }

エラーメッセージ

Assets/GameManager.cs(11,15): error CS1502: The best overloaded method match for `UnityEngine.Object.Instantiate<Sample>(Sample)' has some invalid arguments
Assets/GameManager.cs(11,35): error CS1503: Argument `#1' cannot convert `CubeScript' expression to type `Sample'

エラーにならないコード。

C#

1 [SerializeField] 2 CubeScript cubes; 3 4 void Start () { 5 CubeScript cubes2 = Instantiate<CubeScript>(cubes); 6 }

上記はエラーになりませんが、このコードは下記のように書き換えることもできますよね?

C#

1 [SerializeField] 2 CubeScript cubes; 3 4 void Start () { 5 CubeScript cubes2 = Instantiate(cubes); 6 }

とすると、わざわざ<CubeScript>の記述の分だけ長くなるだけのような気がして、意味がないように思えるのですが、
いかがでしょうか?

Instantiateで<>を書く場合、()内と同じコンポーネントを指定しなければならないのでしょうか?
エラー①②のような書き方はできないのでしょうか?
<>を書くメリットが知りたいです。

ご教示お願い致します。

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

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

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

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

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

guest

回答1

0

ベストアンサー

エラーコードに書いてある通りです。

1つ目のエラーは、cubeはGameObjectなのにCubeScriptとして複製しようとしているので「型変換が出来ない」というエラーになります。
一度GameObjectを複製してからGetComponent<CubeScript>()で取得してください。

2つ目も、cubesはCubeScriptなのにSampleとして複製しようとしているので同様のエラーになります。


上記はエラーになりませんが、このコードは下記のように書き換えることもできますよね?

可能です。
キャストの省略、というもののようです。
Unity - 5.6.6では発生しない5.4.3の型変換問題(137534)|teratail

昔のUnityにはInstantiate()のみ存在していて、Instantiate<T>()がありませんでした。
Instantiate<T>()が出来た後も、(私が記憶する限りでは)前者の返り値はObject型だったので自分で型変換を行う必要がありました。
今では(どのバージョンからか分かりませんが)Instantiate()を使用した場合も、渡した物と同じ型で返って来るようになったようです。(多分内部でInstantiate<T>()を呼んでいる、同じ挙動の別名メソッドになっているのではないかと思います)

**「今から使う人はInstantiate()を使えばOK。<>を使うメリットは無い。これまでのプロジェクトではInstantiate(〜) as TInstantiate<T>(〜)が混在しているので、互換の為に両方使えるようにしてあるだけ」**ということじゃないかなと思います。
(ただ公式ドキュメントではInstantiate()の返り値はObject型になっているので若干疑問は残ります……)

投稿2018/08/14 05:00

sakura_hana

総合スコア11427

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

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

退会済みユーザー

退会済みユーザー

2018/08/15 15:55

ご回答ありがとうございます。 理解力が悪くてすみません。 Instantiate<T>(〜)は、Instantiate(〜) as Tと同じということですか? 昔は、Instantiate()の戻り値がObject型だったけど、今はInstantiate()の戻り値は、()内で指定した型が返ってくるということですね? ここで、昔のInstantiate()で戻り値がObject型が返ってきていたときの動きに関して混乱してしまったのですが、 Instantiate(〜) as T としたとき、 ①Instantiate(〜)でObject型が返る。 ②そのObject型をas TでT型に変換する。 だったら、「Object型の方が上位のはずなのに、それを下位のT型に変換できないのでは?」と思ってしまったのですが、 そうではなく、Instantiate(〜) as Tによって、 「Object型で返る前に最初からT型で返している」という解釈で合っていますか?
sakura_hana

2018/08/15 23:57

>Instantiate<T>(〜)は、Instantiate(〜) as Tと同じということですか? そうです。(T型で返って来るという意味で同じ) >今はInstantiate()の戻り値は、()内で指定した型が返ってくるということですね? 厳密には「()内で指定したオブジェクト(=複製元)と同じ型」ですね。 >Object型の方が上位のはずなのに、それを下位のT型に変換できないのでは? 上位下位については私は詳しくないですが、継承において「Objectは全てのクラスの基底クラス」なのでどんな型にも変換出来ます。 なので、「Object型で返る前に最初からT型で返している」のではなく、「①Instantiate(〜)でObject型が返る。②そのObject型をas TでT型に変換する。」で合ってます。
退会済みユーザー

退会済みユーザー

2018/08/16 03:00 編集

ご回答ありがとうございます。 理解できました。 ありがとうございます。 今からは、Instantiate<T>(〜)もInstantiate(〜) as Tも使う必要がなく、 Instantiate()を使えばOKということですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問