🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

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

Unity

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

Q&A

解決済

1回答

2067閲覧

「NullReferenceException: Object reference not set to an instance of an object」を解決し、シーン遷移をしたいです。

qreUrnU

総合スコア1

C#

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

Unity

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

0グッド

0クリップ

投稿2021/03/28 16:43

前提・実現したいこと

初めて質問します。よろしくお願いします。
就活でポートフォリオを提出するため、シューティングゲームを作っています。
残弾数が0になったら、「Rukyoku Scene」(ゲームオーバー画面)に遷移させたいです。
※麻雀を模したゲームなので、シーン名にも「流局」を模しています。すみません。

【前提】
・残弾数を「Main Camera」内の「ShootScript」で管理
・「Bullet Prefab」内の「BulletScript」

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

シーン遷移をするのか確かめようとしたところ、弾丸を一発発射したらエラーが報告されました。
弾丸を発射するたびに同じエラーが出続けます。結果、遷移しませんでした。

NullReferenceException: Object reference not set to an instance of an object BulletScript.OnEnable () (at Assets/BulletScript.cs:33) UnityEngine.Object:Instantiate(GameObject, Vector3, Quaternion) ShootScript:Update() (at Assets/ShootScript.cs:45)

該当のソースコード

BulletScript

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5using UnityEngine.SceneManagement; 6 7public class BulletScript : MonoBehaviour 8{ 9 [SerializeField] private float power = 50f; //弾丸に与えるパワー 10 [SerializeField] private float deleteTime = 5f; //弾丸の消滅時間 11 private Rigidbody rigid; 12 private Ray ray; 13 GameObject MainCamera; 14 ShootScript shootScript; 15 16 void Start() 17 { 18 MainCamera = GameObject.Find("Main Camera"); 19 shootScript = MainCamera.GetComponent<ShootScript>(); 20 } 21 22 void Awake() 23 { 24 rigid = GetComponent<Rigidbody>(); //Rigidbodyを取得し速度を0に初期化 25 } 26 27 void OnEnable() //弾丸がアクティブになった時 28 { 29 ray = Camera.main.ScreenPointToRay(Input.mousePosition); //カメラからクリックした位置にレイを飛ばす 30 rigid.AddForce(ray.direction * power, ForceMode.Force); 31 Destroy(this.gameObject, deleteTime); //弾丸を発射してから指定した時間が経過したら自動で削除 32 33 if(shootScript.shootcount == 0) //33行目 34 { 35 SceneManager.LoadScene("Rukyoku Scene"); 36 } 37 } 38 39 void FixedUpdate() //弾丸が存在していればレイの方向に力を加える 40 { 41 rigid.AddForce(ray.direction * power, ForceMode.Force); 42 } 43 44 void OnCollisionEnter(Collision collision) //当たり判定メソッド 45 { 46 if (collision.gameObject.CompareTag("Enemy")) 47 { 48 Destroy(gameObject); 49 } 50 } 51} 52

ShootScript

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5using UnityEngine.SceneManagement; 6 7public class ShootScript : MonoBehaviour 8{ 9 [SerializeField] private GameObject bullet;//弾丸のプレハブ 10 [SerializeField] private float offset; //レンズからのオフセット値 11 12 [SerializeField] private float waitTime = 0.1f; //弾丸を飛ばす間隔時間 13 private float elapsedTime = 0f; //経過時間 14 15 public float shootcount; 16 17 GameObject BulletText; 18 Text Bullet_text; 19 20 // Start is called before the first frame update 21 void Start() 22 { 23 BulletText = GameObject.Find("Bullet Text"); 24 Bullet_text = BulletText.GetComponent<Text>(); 25 } 26 27 // Update is called once per frame 28 void Update() 29 { 30 elapsedTime += Time.deltaTime; 31 if (elapsedTime < waitTime) //待ち時間を超えなければ次の処理に行かない 32 { 33 return; 34 } 35 36 if (Input.GetButton("Fire1")) 37 { 38 if (shootcount < 1) //0になると処理しない 39 return; 40 41 shootcount -= 1; //撃つたびに減る 42 Bullet_text.text = string.Format("残弾数:{0,2}", shootcount); 43 44 var centerOfLens = Camera.main.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, Camera.main.nearClipPlane + offset)); //カメラのレンズの中心を求める 45 var bulletObj = Instantiate(bullet, centerOfLens, Quaternion.identity) as GameObject; //45行目 カメラのレンズの中心から弾を飛ばす 46 elapsedTime = 0f; //待ち時間初期化 47 } 48 } 49}

試したこと

値の取得に関してはエラーが出ていないはずなので、遷移だけの問題を解決したい一心です。
Nullエラーに何度も悩まされてきました。今回は他を崩したくないので、エラーが出た瞬間悩みました。

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

unity(2020.2.5f1)

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/03/29 00:22

デバッガを使って何が null になるのか調べられないのですか?
qreUrnU

2021/03/29 09:21

nullになっているのはエラーに該当する行の「何か」だと思っていました。そして、fiveHundred様の回答により解決しました。今後は何がnullなのかよく調べてみようと思います。ありがとうございます。
guest

回答1

0

ベストアンサー

C#

1 if(shootScript.shootcount == 0) //33行目

「値の取得に関してはエラーが出ていないはず」とのことですが、上記では「shootScript」と「shootScript.shootcount」しか変数がありません。
そして、「shootScript.shootcount」は値型なので、nullになることはあり得ません。
したがって、「shootScript」がnullになっており、値の取得が上手く出来ていないことは明白です。
(後述の理由により、今回は関係なさそうですが、GetComponent<~>()は「失敗した場合はnullを返す」ため、エラーを表示することや例外を投げることはありません。
他の類似の関数もそのような仕様になっているので、気を付けた方がいいです)

この理由として考えられるのは、おそらく関数の実行順序を勘違いしているのではないかなと思います。
Unity公式のドキュメントによれば、以下の順序で呼ばれます。

  1. Awake()
  2. OnEnable()
  3. Start()

しかし、現状の内容では、「shootScript」はStart()で取得しているので、OnEnable()の時点では取得されておらず、デフォルト値であるnullになっており、それでエラーになっているのだと考えられます。

投稿2021/03/29 00:55

fiveHundred

総合スコア10152

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

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

qreUrnU

2021/03/29 09:29

「参照できていないよ」などの経験したエラーとは違う表記だったので、そこまではできているのか。と思い込んでいました。ご指摘ありがとうございます。 関数の実行順序については勉強不足でした。修正しやすいご回答ありがとうございます。無事にシーン遷移させることができました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問