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

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

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

Q&A

解決済

1回答

1469閲覧

同じ関数内の同じ変数でも,実行タイミングによってNULLになる時がある

chankane

総合スコア139

0グッド

0クリップ

投稿2018/05/31 12:58

前提・実現したいこと

お世話になております.チュートリアルのブロック崩しを作り終えたので,新しいギミックを追加しようとしたところ,エラーが出ました.お助けくださいませ.

実現したいことは,ボールがバーに当たった時に,ボールを加速させるというものです.

該当のソースコード

c#

1// Bar.cs(バーにアタッチしているスクリプト) 2using System.Collections; 3using System.Collections.Generic; 4using UnityEngine; 5 6public class Bar:MonoBehaviour 7{ 8 public GameObject obj; 9 Ball ball; 10 // Use this for initialization 11 void Start() 12 { 13 ball = obj.GetComponent<Ball>(); 14 } 15 16 void OnCollisionEnter2D(Collision2D col) 17 { 18 ball.Accelerate(); // 1 19 } 20} 21

c#

1// Ball.cs(ボールにアタッチしているスクリプト) 2using System.Collections; 3using System.Collections.Generic; 4using UnityEngine; 5 6public class Ball : MonoBehaviour { 7 const int MIN_SPEED = 10; 8 const int MAX_SPEED = 150; 9 Rigidbody2D rb; 10 11 // Use this for initialization 12 void Start () { 13 rb = GetComponent<Rigidbody2D> (); 14 rb.AddForce(Vector2.down*MIN_SPEED-Vector2.right, ForceMode2D.Impulse); 15 Debug.Log(rb); 16 } 17 18 // Update is called once per frame 19 void Update () { 20 Accelerate(); // 2 21 } 22 23 public void Accelerate(){ 24 Debug.Log(rb); 25 rb.velocity *= 1; // 本当は下の文が正しいですが,諸事情により加速しないような記述をしています(同じエラーが出ることには変わりありません) 26 //rb.velocity = rb.velocity.normalized * MAX_SPEED; 27 } 28 29 public void Decelerate(){ 30 rb.velocity = rb.velocity.normalized * MIN_SPEED; 31 } 32}

エラーが出るのは,長たらしいコメントを書いた部分です.ここで,rbがNULLになるときがあります.そのNULLになるときというのは,コメントで1と示してある部分からAccelerate()を呼んだときです.2側から呼んだときは必ずNULLではありませんでした.ちなみに上記2つとは別のスクリプトからDecelerate()を呼んでも同じ現象が起こりました.

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

UnassignedReferenceException: The variable rb of Ball has not been assigned. You probably need to assign the rb variable of the Ball script in the inspector. UnityEngine.Rigidbody2D.get_velocity () Ball.Accelerate () (at Assets/Objects/Ball/Ball.cs:41) Bar.OnCollisionEnter2D (UnityEngine.Collision2D col) (at Assets/Objects/Bar/Bar.cs:23)

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

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

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

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

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

guest

回答1

0

ベストアンサー

rb はStartメソッドで代入されてますんで、そのメソッドが呼ばれていないときはNULL ですね

投稿2018/05/31 13:11

y_waiwai

総合スコア87719

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

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

chankane

2018/05/31 13:31 編集

ご回答ありがとうございます(^^♪ 疑問に思ったのですが,仮にStartメソッドが呼ばれていないとしたら,Update内でも同様のエラーが出るはずです.(2とコメントした位置)しかしこちら側で呼んだ時には rb がNULLにならず,エラーが出ません.この違いはなぜ起こるのでしょうか?
y_waiwai

2018/05/31 13:33

Updateメソッドで、Accelerateメソッドが呼ばれますんで、結局Accelerateメソッドでエラーになることになりますが。
y_waiwai

2018/05/31 13:35

どういう呼び出され方してるのかわかりませんが、rbの初期化をコンストラクタに書くなりすればどうでしょう
chankane

2018/05/31 13:45

すみませんその通りです。 結局Accelerateメソッドでエラーが出ることになります。 しかし出ないのです。(nullでない)つまりStartメソッドでの初期化は上手くいっていると考えております。(順番的にもコメント1よりもコメント2のほうが先に実行されていますし...)申し訳ありません、俺の書き方が伝わりにくかったです(-人-;)
chankane

2018/05/31 13:46

コンストラクタで試してみます!
pepperleaf

2018/05/31 13:51

Accelerate() 呼出しの前に必ず、Start()が呼ばれていると考えてよいでしょうか? 同じオブジェクト内でと言う事で。 ボールが複数で、Strat()が呼ばれていないオブジェクトで、呼び出されているという事が無いかという事です。
y_waiwai

2018/05/31 13:59

なら、NULLチェックして、NULLなら無視するなり、Start実行するなりするってことで。
chankane

2018/05/31 14:01

ボールが複数だったので1つにしてみましたが、同様のエラーが出て上手くいきまんでした
chankane

2018/05/31 14:06

y_waiwai様、ありがとうございます!そのように致します ただこの挙動の原因を知りたかったため質問致しました。 こうかもしれないという見当がつく方は引き続きよろしくお願いいたします(-人-;)
y_waiwai

2018/05/31 14:06

StartのまえにAccelerateが実行されてしまうんでしょうね
chankane

2018/05/31 14:07

それ意外ないですものね(--;) 本当にstartが実行できているか1から確認してみます!
chankane

2018/06/02 01:58

結局Startが実行されていないことが原因でした.上記スクリプトのobjに,間違えてプレファブを設定していました.ご回答ありがとうございました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問