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

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

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

Nullとは、プログラミング言語やデータベースにおけるデータ表現の一種です。コンテキストによって"空"もしくは"長さ0の文字列"、”未知・不明”を意味します。

Unity

Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

解決済

あるスクリプトのメソッドを他のスクリプトから呼び出すと、そのメソッドでだけ変数の値がnullや0になる

Errors
Errors

総合スコア1

Null

Nullとは、プログラミング言語やデータベースにおけるデータ表現の一種です。コンテキストによって"空"もしくは"長さ0の文字列"、”未知・不明”を意味します。

Unity

Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

3回答

0リアクション

0クリップ

642閲覧

投稿2021/08/07 14:58

編集2021/08/08 02:56

他のスクリプトからWeaponActiveメソッドを実行すると、その時だけあらゆる変数が0やnullなどになる。

キャラにInstantiateで武器を持たせて(ここではSwordというオブジェクト)キャラにAddComponentでSwordスクリプトをアタッチし、持っている武器をSetActiveで表示非表示を切り替えたいと思い、別のスクリプトからinvokeで呼び出されるWeaponActiveメソッドを作りました。

SwordクラスのStart()から呼び出したWeaponActive(false)は、ちゃんと武器は消えるし、それ以外の変数も問題なく値を保持していました。

しかしTechniquePerformerと言う同じオブジェクトにアタッチした別のスクリプトでボタン入力を検知し、Invokeを利用してWeaponActiveを実行しました。

するとなぜかNullReferenceとなり、武器が表示されませんでした。
調べてみると、swordObというGameObject型で武器を参照している場所がnullでした

public class Sword : MonoBehaviour { CharaData charaData; SwordCol swordCol; GameObject swordOb; public void Start() { charaData = this.GetComponent<CharaData>(); swordOb = this.gameObject.transform.Find("StickHuman/body/R_upperarm/R_forearm/Sword").gameObject; swordCol = swordOb.transform.Find("grip").GetComponent<SwordCol>(); WeaponActive(false); } public void WeaponActive(bool a) { swordOb.SetActive(a); } int count; void FixedUpdate() { Debug.Log(swordOb); count++;//強制的にswordObを表示する if (count == 300) { WeaponActive(true); } } }

試しにFixedUpdateでDebug.Log(swordOb)を実行してみましたが、Startで呼び出された後もオブジェクトの名前を出力し続け、ErrorPauseを無効にしてRullReference後の状況も見てみましたが、FixedUpdateからswordObがnullだと表示されたことは一度もありませんでした。

試しに同じスクリプトからゲームスタート5秒後にWeaponActiveを呼び出させてみましたが、そうすると正常にswordは実行されました。
しかし第三者のスクリプトからinvokeで実行すると、今度はTechniqueの方から呼んだのと同じようにエラーが発生しました。

そしてdebug.logを使っていくうちに分かったことが、他のスクリプトからWeaponActiveを実行した時のみあらゆる変数、更にthis.gameObjectまでもがnullや0となってエラーが発生していると分かりました。

ただしnullなどにならない変数もあって、たとえば宣言と同時に初期化したint型の変数は問題なし。
staticなクラスにjsonで保存していた変数とかも問題なし。しかしstartなどで値を入力したものはnullなどになる。

ちなみに宣言と同時に初期化して、その後startで別の値を入力してみましたが、weaponActiveでは変数の中が宣言時に初期化した値でした。

変数はprivateなので他のスクリプトからは変更できないはずで、Swordスクリプト内でも代入してるのはStart内のみで、他から参照先は変更されていません。

試したこと

Invokeでは無くGetComponentからメソッド実行、しかし同じ結果。

WeaponActiveの引数をなくして返り値からSetActive、返り値もnullだった。

補足情報(FW/ツールのバージョンなど)

WeaponActiveメソッドを使わずに武器を非アクティブ化したりするなど、別の方法を使えばいいような気もしますが、なぜこれでエラーが出るのか分からないので、できればこの方法を使う方針でよろしくお願いします。

unity 2020.3.15f2

NullReferenceException: Object reference not set to an instance of an object Sword.WeaponActive (System.Boolean a) (at Assets/Sclipt/Technique/Sword.cs:23) System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <695d1cc93cca45069c528c15c9fdd749>:0) Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation. System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <695d1cc93cca45069c528c15c9fdd749>:0) System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <695d1cc93cca45069c528c15c9fdd749>:0) TechniquePerformer.CallMethod (System.String className, System.String methodName, System.Object value) (at Assets/Sclipt/CharaCommon/TechniquePerformer.cs:247) TechniquePerformer.Equiped () (at Assets/Sclipt/CharaCommon/TechniquePerformer.cs:119) CharaDataという第三者のスクリプトからWeaponActiveを実行したとき NullReferenceException: Object reference not set to an instance of an object Sword.WeaponActive (System.Boolean a) (at Assets/Sclipt/Technique/Sword.cs:23) System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <695d1cc93cca45069c528c15c9fdd749>:0) Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation. System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <695d1cc93cca45069c528c15c9fdd749>:0) System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <695d1cc93cca45069c528c15c9fdd749>:0) CharaData.CallMethod (System.String className, System.String methodName, System.Object value) (at Assets/Sclipt/CharaCommon/CharaData.cs:254) CharaData.FixedUpdate () (at Assets/Sclipt/CharaCommon/CharaData.cs:238)

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

退会済みユーザー

退会済みユーザー

2021/08/08 07:17

関数の呼び出し元のTechniquePerformerの、Swordクラスを取得している場所と呼び出している部分のコードを記載することは可能でしょうか?
Errors

2021/08/08 08:28

TechniquePerformerに下記のメソッドを用意して、これで呼び出しています。 public void Equiped() { CallMethod("Sword", "WeaponActive", true); //"Sword"は本来変数。変数の中身がSwordなのはDebug.Logで確認済み } public void CallMethod(string className, string methodName, dynamic value = null) { System.Type types = System.Type.GetType(className); object weaponClass = System.Activator.CreateInstance(types); MethodInfo methodinfo = types.GetMethod(methodName); object[] ob = new object[] { value }; methodinfo.Invoke(weaponClass, ob); }
Errors

2021/08/08 08:35 編集

NullReferenceのエラー前に、黄色三角のこんな警告が発生しています 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 UnityEngine.MonoBehaviour:.ctor () Sword:.ctor () System.Activator:CreateInstance (System.Type) TechniquePerformer:CallMethod (string,string,object) (at Assets/Sclipt/CharaCommon/TechniquePerformer.cs:243) TechniquePerformer:Equiped () (at Assets/Sclipt/CharaCommon/TechniquePerformer.cs:121)
Errors

2021/08/08 08:37

ちなみにTechniquePerformerの121行目はCallMethod("Sword", "WeaponActive", true) 243行目は object weaponClass = System.Activator.CreateInstance(types); という処理となります
Errors

2021/08/08 09:29

汎用性を捨ててEquipedメソッド内のCallMethodを、下記の処理に入れ替えると普通に動きました。 this.gameObject.GetComponent<Sword>().WeaponActive(true); どうやら原因はCallMethodの処理のようです。 しかし習得したいスクリプトは10個以上になる可能性もあり、それをif文とかで分岐しまくるのは嫌なので、出来ればCallMethodを使って文字列でメソッド実行したいです。
退会済みユーザー

退会済みユーザー

2021/08/08 11:20

そうですね…… 最悪出来そうになければ、効率は悪いですがswitch文で分岐させる方が良さそうかもしれないです。 わざわざ追記依頼をしておいて申し訳ないですが、私ではお役に立てそうにないですね。 お役に立てず申し訳ありません。
退会済みユーザー

退会済みユーザー

2021/08/10 06:41

全く分かりませんがMonoBehaviourを継承していると無理っぽい? 警告の通り、MonoBehaciourを継承しているクラスをnewして作る事は許可しません、ってことらしいので、て事はMonoBehaviourを継承しないなら出来るっぽい? object weaponClass = System.Activator.CreateInstance(types); Debug.Log(weaponClass); // MonoVehaviourを継承しているとnullになる

まだ回答がついていません

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

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

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Null

Nullとは、プログラミング言語やデータベースにおけるデータ表現の一種です。コンテキストによって"空"もしくは"長さ0の文字列"、”未知・不明”を意味します。

Unity

Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。