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

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

ただいまの
回答率

88.91%

Unity2D Physics2D.Raycastでゲームが停止する事象の解決方法

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 171

unity_level1

score 4

Unity2Dでゲームを制作しているのですが、Physics2D.Raycastを使用して、オブジェクトの情報を取得しようとしておりますが、その際にオブジェクト以外に触れる(コライダーをつけていないオブジェクト)に触れるとエラーによりゲームが停止してしまいます。
スクリプトのうまい書き方が分からないため、ご教示いただけますと幸いです。

現在の環境

■開発OS Windows 10

■Unityバージョン:Unity2019 3.7f

■C#

実現したいこと

コライダーのついていないオブジェクトをクリック(Physics2D.Raycastでnullが帰ってきても)しても
ゲームが停止しないようにしたい。

スクリプト

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class ClickOjects : MonoBehaviour
{
    GameObject bg;

    GameObject stage;

    GameObject opObjects;

    SelectObjectTest selectObjects;

    //Clickしたオブジェクトを格納する変数
    string clickedObjectName;

    GameObject clickedObject;

    [SerializeField]
    public GameObject[] qusesion;

    [SerializeField]
    private int sicapture = 10;

    //不正解時に表示するオブジェクトを格納
    [SerializeField]
    public GameObject[] falseObjects;

    [SerializeField]
    private float quesionPosX;
    [SerializeField]
    private float quesionPosY;

    [SerializeField]
    private float quesionScaleX;
    [SerializeField]
    private float quesionScaleY;

    GameObject clone;
    public GameObject opObject;
    //不正解時に使用するオブジェクト
    GameObject falseSceneObject;
    GameObject falseSceneObject2;
    public int number;
    public int clone_Count = 4;


    // Start is called before the first frame update
    void Start()
    {


        //stage1を格納
        stage = GameObject.Find("stage1");
        opObjects = GameObject.Find("opObjects");
        StartCoroutine("opActiveFalse");


        //stage1のコンポーネントであるSelectObjectTestを参照
        selectObjects = stage.GetComponent<SelectObjectTest>();

        StartCoroutine("ObjectControl");

        //parentObject = GameObject.Find("ObjectGroup1");

    }

    // Update is called once per frame
    void Update()
    {

        //左クリックをした場合ブロック内を実行
        if (Input.GetMouseButtonDown(0)) {

        //Clickしたときに格納するため、スタート時点では何も入れない
        clickedObject = null;

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        RaycastHit2D hit2d = Physics2D.Raycast((Vector2)ray.origin, (Vector2)ray.direction);

            //ヒットしたオブジェクトの情報をstring型 clickedObjectName GameObject型 clickedObject に格納
            if (hit2d)
            {
                clickedObjectName = hit2d.transform.gameObject.name;
                clickedObject = hit2d.transform.gameObject;

         //格納した情報とclone変数の情報が一致したらブロック内を実行
         //一致しなければ、nullではない場合、ResultfalseScene()を実行
         //nullの場合はelse以下を実行 ※空白にして何も実行せずゲームを続行させたい
                if (clickedObject == clone)
                {
                    ResultTrueScene();

                }
                else if (clickedObject != clone && clickedObject != null)
                {
                    ResultfalseScene();
                }
                else
                {
                    Debug.Log(clickedObject);
                }
            }
            else
            {
                Debug.Log(clickedObjectName);
            }

            Debug.Log(clickedObjectName);
            Debug.Log(clone.name);



        }
    }

    public void ResultTrueScene()
    {
        Debug.Log(clickedObjectName);

        if (clickedObjectName == clone.name)
        {

            if(clone.name == "bowusagi")
            {
                Debug.Log("bowusagi");

            }
            else if(clone.name == "happyusagi")
            {
                 Debug.Log("happyusagi");

            }
            else if (clone.name == "laughusagi")
            {
                Debug.Log("laughusagi");

            }
            else if (clone.name == "pieceusagi")
            {
                Debug.Log("pieceusagi");

            }
            else if (clone.name == "troubledusagi")
            {
                Debug.Log("troubledusagi");

            }
            else if (clone.name == "coara")
            {
                Debug.Log("coara");
            }
            else if (clone.name == "kangaroo")
            {
                Debug.Log("kangaroo");
            }
            else if (clone.name == "nezumi")
            {
                Debug.Log("nezumi");
            }
            else if (clone.name == "saru")
            {
                Debug.Log("saru");
            }
            else if (clone.name == "usi")
            {
                Debug.Log("usi");
            }

            Debug.Log(true);

            activeFalse();
            StartCoroutine("NextQuesion");

        }


    }
    public void ResultfalseScene()
    {
            //不正解時に表示するゲームオブジェクト
            falseSceneObject = Instantiate(clickedObject, new Vector3(2.0f, 1.0f, 0.0f), Quaternion.identity);
            //表示したゲームオブジェクトのautoAnimal機能をオフにしておく
            falseSceneObject.GetComponent<autoAnimal>().enabled = false;
            //不正解演出のため、一度ゲームオブジェクトを非表示にする
            activeFalse();


            if (clone.name == "beartrouble")
            {
                falseSceneObject2 = Instantiate(falseObjects[0], new Vector3(2.0f, 1.0f, 0.0f), Quaternion.identity);
                falseSceneObject2.transform.position = new Vector3(-0.5f, 0, 0);
                falseSceneObject2.transform.localScale = new Vector3(0.2f, 0.2f, 0);
                Debug.Log("beartrouble");

            }
            else if (clone.name == "bowusagi")
            {

                Debug.Log("bowusagi");

            }
            else if (clone.name == "laughusagi")
            {
                Debug.Log("laughusagi");

            }
            else if (clone.name == "pieceusagi")
            {
                Debug.Log("pieceusagi");

            }
            else if (clone.name == "troubledusagi")
            {
                Debug.Log("troubledusagi");

            }
            else if (clone.name == "coara")
            {
                Debug.Log("coara");

            }
            else if (clone.name == "kangaroo")
            {
                Debug.Log("kangaroo");
            }
            else if (clone.name == "nezumi")
            {
                Debug.Log("nezumi");
            }
            else if (clone.name == "saru")
            {
                Debug.Log("saru");
            }
            else if (clone.name == "usi")
            {
                Debug.Log("usi");
            }


      

        //不正解時のオブジェクトを表示する
        falseSceneObject.transform.position = new Vector3(0.5f, 0, 0);
        falseSceneObject.transform.localScale = new Vector3(0.3f, 0.3f, 0);
        //3秒後に不正解時に出したオブジェクトを消す
        Destroy(falseSceneObject, 3.0f);
        Destroy(falseSceneObject2, 3.0f);

        //ゲームをリスタートする
        StartCoroutine("Restart");


    }
}

エラーの原因の可能性が高いコード

void Update()
    {

        //左クリックをした場合ブロック内を実行
        if (Input.GetMouseButtonDown(0)) {

        //Clickしたときに格納するため、スタート時点では何も入れない
        clickedObject = null;

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        RaycastHit2D hit2d = Physics2D.Raycast((Vector2)ray.origin, (Vector2)ray.direction);

            //ヒットしたオブジェクトの情報をstring型 clickedObjectName GameObject型 clickedObject に格納
            if (hit2d)
            {
                clickedObjectName = hit2d.transform.gameObject.name;
                clickedObject = hit2d.transform.gameObject;

         //格納した情報とclone変数の情報が一致したらブロック内を実行
         //一致しなければ、nullではない場合、ResultfalseScene()を実行
         //nullの場合はelse以下を実行 ※空白にして何も実行せずゲームを続行させたい
                if (clickedObject == clone)
                {
                    ResultTrueScene();

                }
                else if (clickedObject != clone && clickedObject != null)
                {
                    ResultfalseScene();
                }
                else
                {
                    Debug.Log(clickedObject);
                }
            }
            else
            {
                Debug.Log(clickedObjectName);
            }

            Debug.Log(clickedObjectName);
            Debug.Log(clone.name);



        }
    }

発生しているエラーと発生時点のコード

NullReferenceException: Object reference not set to an instance of an object
ClickOjects.ResultfalseScene () (at Assets/Script/ClickOjects.cs:194)
ClickOjects.Update () (at Assets/Script/ClickOjects.cs:105)

//原因コード1
//表示したゲームオブジェクトのautoAnimal機能をオフにしておく
//下記コードで生成したオブジェクトはランダムに移動するようにしている
            falseSceneObject.GetComponent<autoObject>().enabled = false;
//原因コード2
else if (clickedObject != clone && clickedObject != null)
                {
                    ResultfalseScene();
                }

試したこと

原因コード1でautoObjectをenableにする処理をしているが、Physics2D.Raycastでnullを拾ったときは、
autoObjectがついていないため、この処理でエラーが出ている可能性を考えコメントアウトしましたが、エラーが発生

■発生エラー
NullReferenceException: Object reference not set to an instance of an object
ClickOjects.activeFalse () (at Assets/Script/ClickOjects.cs:323)
ClickOjects.ResultfalseScene () (at Assets/Script/ClickOjects.cs:196)
ClickOjects.Update () (at Assets/Script/ClickOjects.cs:105)

Physics2D.Raycastでnullを検知した場合は何も処理を流さないようにelse以下に処理を記述しなかったが同様のエラーが発生

以上です。
お手数ですが、わかる方ご教示いただけますと非常に助かります。よろしくお願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

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

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

if (hit2d)

if (hit2d.collider)

と書き変えるとよいと思います。

参照: Physics2D.Raycast

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

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

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

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/22 10:54 編集

    ご回答いただきありがとうございました。

    ご教示いただきました点を修正し、その後、配置オブジェクトを確認したところ、空オブジェクトが配置されており、その空オブジェクトにautoObjectスクリプトがAddされていなかったため、発生したエラーでした。
    それらからすべてBoxColliderを外し、不要なオブジェクトは削除することで、正常に実行させることができました。

    本事象につきまして、ご教示いただきありがとうございました。

    キャンセル

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

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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