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

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

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

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

Unity

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

Q&A

解決済

2回答

667閲覧

【Unity】初期で宣言したプロパティや継承した変数の値やオブジェクトは、違うクラスからは参照できないのでしょうか。nullにどうしてもなってしまいます。

PotePui

総合スコア69

C#

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

Unity

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

0グッド

0クリップ

投稿2022/08/25 09:35

実現したいこと

2つのクラスがあります。

  • Test1.cs
  • Test2.cs

今、Test1でフィールド変数に定義したシリアライズ変数とその変数に対応したプロパティの値を
Test2で受け取りたいです。

実現したいのは、
Test1.csではInspector上でPlayerという名前のGameObject を設定しています
Test2.csでTest1をインスタンス化し、

C#

1 var player = _test.Obj; 2 _rb = player.GetComponent<Rigidbody>();

に記載しているような形で、PlayerのRigidbodyコンポーネントを取得したいです

nullになる理由はStart時はnullなので、Test1の値はもちろんnullなのは理解できています💦
こうなると確実にnullってことが分かるので、

  • Test2.csでは、普通にシリアライズしたオブジェクトを設定するや

Tagを設定してGameObject を検索して取得する

くらいしか打つ手はないのかなって思いまして。
インスタンス化や継承しても、初期値を取得できるだけで、
毎回値は初期値のままなのか、考え方が全然違うのか教えてください。

発生している問題・エラーメッセージ

NullReferenceException: Object reference not set to an instance of an object A.Test2.Start () (at Assets/_Sc/Sample/Test2.cs:16)

実際のテスト画像

イメージ説明
イメージ説明
イメージ説明

該当のソースコード

・Test1.cs

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5namespace A 6{ 7 public class Test1 : MonoBehaviour 8 { 9 [SerializeField] 10 GameObject _obj = null; 11 public GameObject Obj { get { return _obj; } set { _obj = value; } } 12 13 private Rigidbody _rb = null; 14 void Start() 15 { 16 _rb = Obj.GetComponent<Rigidbody>(); 17 Debug.Log(_rb); // Player (UnityEngine.Rigidbody) 18 Debug.Log(_rb.name); // Player 19 } 20 } 21} 22

・Test2.cs

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5namespace A 6{ 7 public class Test2 : MonoBehaviour 8 { 9 private Test1 _test = new Test1(); 10 11 private Rigidbody _rb = null; 12 void Start() 13 { 14 var player = _test.Obj; 15 _rb = player.GetComponent<Rigidbody>(); 16 Debug.Log(player.name); // null 17 Debug.Log(player); // null 18 Debug.Log(_rb); // null 19 Debug.Log(player.name); // null 20 } 21 } 22}

以上です。

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

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

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

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

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

guest

回答2

0

ベストアンサー

C#

1 private Test1 _test = new Test1();

上記、Unityでは「MonoBehaviourクラスを継承したものはnewをしてはいけない」という原則があるので、その点でダメです。

また、そもそもの疑問として、

Test2.csでTest1をインスタンス化し、

とありますが、インスタンス化とは「新しく生成する」という意味であり、にもかかわらず画像上でTest1はすでに存在しているので、新たに生成する必要はあるのかどうかすら、この質問文では読み取れません。
インスタンス化にするにしても、前述の通りnewは使ってはいけないので、Instantiate()関数を使ってゲームオブジェクトを複製することが基本になります。
その関数の戻り値はコピーしたオブジェクトになるので、そこから参照すればいいでしょう。

投稿2022/08/25 10:19

編集2022/08/25 10:21
fiveHundred

総合スコア9829

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

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

fiveHundred

2022/08/25 10:27

以下、追加で補足。 「newしてはいけない」と言いましたが、あくまで「MonoBehaviourクラスを継承したもの」に対してのことなので、例えば「new GameObject()」とすることは可能です。 (その場合、空のゲームオブジェクトが生成されます) もちろんVector3など、newする前提で作られているものもあります。
PotePui

2022/08/25 12:32

まずはお返事ありがとうございます。 以前にnewはダメなことは見て知っていながら軽く考えていて、やっていませんでした。 調べてみて、 Test1 _test1 = gameObject.AddComponent<Test1>() _test1.Method名や変数、プロパティ名など こちらでできました。 ご指摘ありがとうございます。
guest

0

Tagを設定してGameObject を検索して取得する

これで良いんじゃないんです?なんか駄目な理由が?
ちなみに他にもGameObjectの名前で検索するとかコンポーネントクラスで検索するとかあるけど、どっちみちヒエラルキーから検索して取ってくるのは変わらんので

投稿2022/08/25 12:26

drednote

総合スコア336

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問