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

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

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

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

Unity

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

Q&A

解決済

2回答

1228閲覧

Unity - クラスのインスタンスを呼び出すたび、異なる結果を返してほしい

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Unity

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

0グッド

0クリップ

投稿2021/08/17 02:07

編集2021/08/17 05:16

2つ目のスクリプトからWeaponクラスのインスタンスを複数回呼び出し、リストに格納します。
Weapnクラスの中のweaponPowerが毎回違う値で格納されることを期待していますが、毎回同じになってしまいます。

C#

1public class Weapon : MonoBehaviour 2{ 3 public int weaponPower; 4 5 private void Start() 6 { 7 weaponPower = Random.Range(1, 100 + 1); 8 } 9}

C#

1public class WeaponList : MonoBehaviour 2{ 3 public List<Weapon> weaponDate = new List<Weapon>(); 4 5 public void WeaponCreate() //これを呼び出す 6 { 7 for (int i = 0; i < 5; i++) 8 { 9 //こう書くとエラーが出て、weaponPowerが0になる 10 //weaponDate.Add(new Weapon()); 11 12 //objはWeaponスクリプトがついたオブジェクト 13 weaponDate.Add(GameObject.Find("obj").GetComponent<Weapon>()); 14 Debug.Log(weaponDate[i].weaponPower); 15 } 16 } 17}

このように動いてほしい

コンソール画面に56,83,12,98,44のようにランダムな数字が5つ並んでほしい

実際の動作

24,24,24,24,24のように同じ数字が5つ並んでしまう

追記

objは空のオブジェクトでWeaponスクリプトが1つついています。
Unityのバージョンは2020.3.8f1です。

その他

2つ目のスクリプトで
weaponData.Add(new Weapon()); とすると

You are trying to create a MonoBehaviour using the 'new' keyword.
This is not allowed. MonoBehaviours can only be added using AddComponent().
Alternatively, your script can inherit from ScriptableObject or no base class at all

MonoBehaviourを継承したクラスをnewでインスタンス化するなと警告が出ます。
なので、
weaponDate.Add(GameObject.Find("obj").GetComponent<Weapon>()); としました。
(WeaponスクリプトでTransformやGetComponentを使用するのでMonoBehaviourは継承したいです。)

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

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

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

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

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

ku__ra__ge

2021/08/17 02:32

> ここで詰まってしまいました。 どのような動作を想定しており、実際にはどのような動作になってしまったのかを書いてください。
退会済みユーザー

退会済みユーザー

2021/08/17 04:16

修正依頼ありがとうございます。 質問内容をできるだけ簡潔にし、想定する動作と、実際の動作を載せました。
bboydaisuke

2021/08/17 04:48

修正前の内容を知らないと、修正後の内容だけ見ても意味がわからないのでは?
退会済みユーザー

退会済みユーザー

2021/08/17 04:55

修正後の内容だけでも意味がわかるように全てを書き換えました。 新しく質問するべきだったかもしれません。すみません。
BluOxy

2021/08/17 05:06

obj に Weapon オブジェクトはいくつアタッチされていますか
BluOxy

2021/08/17 05:08

また、Unityのバージョンを記載してください
退会済みユーザー

退会済みユーザー

2021/08/17 05:17

objにアタッチされているWeaponオブジェクトは1つだけです。 Unityのバージョンは2020.3.8f1です。 本文にも追記しました。
guest

回答2

0

GameObject.Findはシーン内でゲームオブジェクトの名前を検索し、一致する名前を持つ最初のゲームオブジェクト1つを取得します。
以下のコードは5回ほどWeapon.Start()を実行してweaponPowerが決定している、同じゲームオブジェクトを取得してweaponDateリストに追加してweaponPowerを表示します。
同じオブジェクトのweaponPowerを何度も表示しているため同じ数字が何度も出力されています。

javascript

1for (int i = 0; i < 5; i++) 2{ 3 weaponDate.Add(GameObject.Find("obj").GetComponent<Weapon>()); 4 Debug.Log(weaponDate[i].weaponPower); 5}

コンソール画面に56,83,12,98,44のようにランダムな数字が5つ並んでほしい

シーン内にWeaponスクリプトをアタッチしたオブジェクトが複数あって、その複数のゲームオブジェクトからそれぞれweaponPowerを取得したい場合、GameObject.FindGameObjectsWithTagなどを利用する方法が考えられます。
GameObject-FindGameObjectsWithTag - Unity スクリプトリファレンス

投稿2021/08/17 05:33

ku__ra__ge

総合スコア4524

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

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

退会済みユーザー

退会済みユーザー

2021/08/17 05:49

回答ありがとうございます! お二方をベストアンサーにしたかったのですが、 僅かではありますが先に答えてくださった方を選ばせていただきました。 申し訳ありません。
BluOxy

2021/08/17 06:00 編集

> シーン内にWeaponスクリプトをアタッチしたオブジェクトが複数あって、その複数のゲームオブジェクトからそれぞれweaponPowerを取得したい場合 上記がもし unipon さんの求めていたものであればこちらの回答が正解ですから、時系列を理由に選ぶのではなく、解決に最も貢献した回答をベストアンサーを選んでください。 (スクリプトを複数貼り付ける方法がまさに求めていたもの とのことなので、今回は違ったようですが) ※ 要件を出来るだけ言語化して質問に記載しておくと、このように回答が何通りもぶれることはなくなりますから、難しいかもしれませんが、今後に活かして頂けると回答する側として嬉しいです
退会済みユーザー

退会済みユーザー

2021/08/17 06:00

アドバイスありがとうございます。 今後質問する際は、気をつけます。
guest

0

ベストアンサー

objは空のオブジェクトでWeaponスクリプトが1つついています。

現在は obj に1つだけ Weapon インスタンスが存在する状態なので、そのインスタンスを参照しても同じ weaponPower しか取得できないでしょう。

5つ持たせたい場合は obj に対して Weapon オブジェクトを5つアタッチする必要があります。

そして、複数アタッチされた Weapon オブジェクトは Component.GetComponents で取得することができますから、下記のようなコードを記述して問題が解決するか試してみてください。

C#

1public class WeaponList : MonoBehaviour 2{ 3 public List<Weapon> weaponData = new List<Weapon>(); 4 5 public void WeaponCreate() 6 { 7 var weapons = GameObject.Find("obj").GetComponents<Weapon>(); 8 foreach(var weapon in weapons) 9 { 10 weaponData.Add(weapon); 11 Debug.Log(weapon.weaponPower); 12 } 13 } 14}

仮に同一のオブジェクトを参照したことが原因で同じ乱数が出力されるのであれば、このメソッドを利用することで解決するでしょう。


そうではなく Weapon が持つ weaponPower を5回変更したい場合はメソッドを定義して利用します。
MonoBehavior.Start はスクリプトが有効になったときに Unity 側で呼び出される特別なメソッドなので、別途ユーザが利用するためのメソッドを用意する必要があります。

C#

1public class Weapon : MonoBehaviour 2{ 3 public int weaponPower; 4 5 private void Start() 6 { 7 UpdateWeaponPower(); 8 } 9 10 public void UpdateWeaponPower() 11 { 12 weaponPower = Random.Range(1, 100 + 1); 13 } 14}

C#

1public class WeaponList : MonoBehaviour 2{ 3 public List<Weapon> weaponDate = new List<Weapon>(); 4 5 public void WeaponCreate() 6 { 7 var weapon = GameObject.Find("obj").GetComponent<Weapon>(); 8 weaponDate.Add(weapon); 9 // 5回処理をループしたいだけなので、i は使用しない 10 for (int i = 0; i < 5; i++) 11 { 12 weapon.UpdateWeaponPower(); 13 Debug.Log(weapon.weaponPower); 14 } 15 } 16}

投稿2021/08/17 05:24

編集2021/08/17 05:38
BluOxy

総合スコア2663

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

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

退会済みユーザー

退会済みユーザー

2021/08/17 05:46

回答ありがとうございます! スクリプトを複数貼り付ける方法がまさに求めていたものなので、それを使おうと思います。 とても助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問