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

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

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

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

Unity

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

Q&A

解決済

2回答

849閲覧

GetComponentのtype指定にstringを使用する

YMD_kts

総合スコア23

C#

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

Unity

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

0グッド

0クリップ

投稿2022/07/22 08:11

前提

Unityを使用し、タイトル画面から、見かけは同じだが、遷移先ごとにCPUの動作が異なるようなゲームを作成しました。

現在はCPUの動作の個数分の遷移先シーンを用意して、タイトル画面上のUIボタンごとに遷移先を紐づけているのですが、シーンの変更の手間や管理の関係上これらを1つにまとめたいです。

実現したいこと

CPUに複数のコンポーネントをアタッチしておいて、遷移元となるタイトル画面のボタンからコンポーネント名をstringで取得し、そのコンポーネントをGetComponentしたいと考えています。

エラーコード

error CS1525: Invalid expression term ')'

該当のソースコード

_cpuは動作させたいCPUのGameObjectです。

C#

1Type test = _cpu.GetComponent(_cpuName).GetType(); 2_cpu.GetComponent<test>();

C#

1 _cpu.GetComponent<_cpu.GetComponent(_cpuName).GetType()>();

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

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

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

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

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

guest

回答2

0

ベストアンサー

あなた、_cpu.GetComponent(_cpuName)と堂々と使っているではありませんか。
それを使えばOKです。

え、Component型で返ってくる?
そりゃそうです。「あるときはAという型、あるときはBという型」というように動的に型が変わる変数はC#ではありませんから。
ただ、「Component型を継承したAという型とBという型」であれば、どちらもComponent型の変数に代入することが出来ます。
_cpu.GetComponent(_cpuName)では型名を文字列でしか指定していないので、返り値の型を指定できず、Component型を継承しているという点しか共通していないので、Component型で返すしかないということになります。
また、文字列から型を取得する、という行為も、リフレクションというめんどくさいものを使わないと実現できないので、C#ではそのような書き方はあまりしません。

ただComponent型では、そのままではComponent型で定義している関数しか使えない、ということがあります。
その場合、Component型から本来の型にキャストすることで実現できます。
しかし、「本当にその型なのか」というのは分からない(別の型にキャストすると当然異常事態なのでエラーになる)ので、区別が必要な場合はis演算子を使います。

ここまでをコードにすると以下になります。
(面倒くさいので日本語使っていますが、実際のコードは英字のほうがいいでしょう)

C#

1Component component = _cpu.GetComponent(_cpuName); 2if (component is 本来の型名) 3{ 4 本来の型名 original = component as 本来の型名; 5 original.実行したい関数(); 6}

もっといい方法があるかもしれませんが、これで動作すると思います。
「複数のスクリプトで同じ関数を使う場合は親クラスをさらに作って共通化する」とかも考えられますが、長くなるのでここまでにしておきます。

ここいら辺の話はオブジェクト指向の話を含んでいるので、オブジェクト指向が分からないのであれば、まずはそちらを勉強したほうが分かりやすいと思います。

投稿2022/07/22 09:43

fiveHundred

総合スコア9805

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

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

YMD_kts

2022/07/22 10:08

ありがとうございます! 実装自体は別の方法で行ったのですが、学びがあったのでベストアンサーにさせていただきました。
guest

0

<>のナカミは型名じゃないとだめです

投稿2022/07/22 08:32

y_waiwai

総合スコア87774

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

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

YMD_kts

2022/07/22 09:30

GetType()の返り値が型名だと思うのですがなぜ返り値での型名指定だと使用できないのでしょうか
fiveHundred

2022/07/22 09:45

GetType()は「型の情報を持ったType型の変数」です。 従って、<>の中身には使えません。
Zuishin

2022/07/23 04:02 編集

<> の中を型パラメーターと言いますが、これに変数を使うことはできません。 型情報はコンパイル時に必要なため、実行する前にわかっていなければならないからです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問