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

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

ただいまの
回答率

91.36%

  • C#

    4756questions

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

  • Unity

    2293questions

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

スクリプトをアクティブにする

解決済

回答 1

投稿 2017/11/24 15:19

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

tyint121

score 3

unityでゲームを作ろうと思っています。
ボールを動かし、そのボールから最も近い距離にあるキューブの色を変更したいです。
色を変更するスクリプト(colorc)はキューブにアタッチしており、ボールを動かして最も距離が近くなった際にそのスクリプトをアクティブにしようと思っています。(シーン開始時そのスクリプトは非アクティブ)
以下を実行したのですが、Object reference not set to an instance of an objectとエラーが出てしまいます。
何が原因でしょうか?

using UnityEngine;
using System.Collections;


    public class Distance_detection : MonoBehaviour
    {
        private GameObject nearObj;
        private float searchTime = 0;

        // Use this for initialization
        void Start()
        {

            nearObj = serchTag(gameObject, "Player");
        }

        // Update is called once per frame
        void Update()
        {
            searchTime += Time.deltaTime;
            if (searchTime >= 1.0f)
            {
                nearObj = serchTag(gameObject, "Player");
                searchTime = 0;
            }
            //nearObj = GameObject.Find("Sphere").GetComponent<Renderer>();
            //nearObj.material.color = Color.yellow;
            //nearObj.transform.LookAt(nearObj.transform);
            //nearObj.transform.Translate(Vector3.forward * 0.01f);
             nearObj.GetComponent<colorc>().enabled = true;

        }

        GameObject serchTag(GameObject nowObj, string Player)
        {
            float tmpDis = 0;
            float nearDis = 0;
            GameObject targetObj = null;


            foreach (GameObject obs in GameObject.FindGameObjectsWithTag(Player))
            {
                tmpDis = Vector3.Distance(obs.transform.position, nowObj.transform.position);
                if (nearDis == 0 || nearDis > tmpDis)
                {
                    nearDis = tmpDis;
                    targetObj = obs;
                }

            }

            return targetObj;
        }
    }
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

Object reference not set to an instance of an objectとエラーが出てしまいます。何が原因でしょうか? 

おそらくnullチェックしていないのが原因です。
GetComponent<colorc>()をしてもnearObjにnullが代入された場合、オブジェクトが存在していないのでエラーが出るということだと思います。

    void Update()
    {
        searchTime += Time.deltaTime;
        if (searchTime >= 1.0f)
        {
            nearObj = serchTag(gameObject, "Player");
            searchTime = 0;

            //nearObjが存在するなら
            if (nearObj != null)
            {
                //nearObj = GameObject.Find("Sphere").GetComponent<Renderer>();
                //nearObj.material.color = Color.yellow;
                //nearObj.transform.LookAt(nearObj.transform);
                //nearObj.transform.Translate(Vector3.forward * 0.01f);
                nearObj.GetComponent<colorc>().enabled = true;
            }
        }
    }

nullが存在する言語は常にnullを意識する必要があります。
nullはクラッシュの原因になるのでできる限り初期値を設定するのがおすすめです。設定できないところは必ずnullチェックをするといいと思います。

//数値は初期値が0なので初期化の必要はありません
int SumNum;
//stringは初期値がnullなので初期化
string SumTxt = string.Empty;
//配列もできれば初期化
string[] SumAry = new string[5];
List<string> SumAry2 = new List<string>();

おまけ

Updateは毎フレーム実行されるので少々高コストです。OO秒毎の実行でしたらCoroutineを使うといいと思います。Coroutineの注意点はゲームオブジェクトが非アクティブの時に実行するとエラーが出るので注意が必要です。

//ループ間隔をfloatで指定
static readonly float LOOP_INTERVAL = 1f;
Coroutine m_distanceCorutine;

void Start ()
{
    //処理のスタート
    StartDistanceCorutine ();
}

void StartDistanceCorutine ()
{
        StopDistanceCorutine ();
    m_distanceCorutine = StartCoroutine ( DistanceCorutine() );
}

//ストップしたいときはこの関数を呼ぶ
void StopDistanceCorutine ()
{
    //nullの可能性があるのでnullチェック
    if (m_distanceCorutine != null) StopCoroutine ( m_distanceCorutine );
}

IEnumerator DistanceCorutine()
{
    var waitTime = new WaitForSeconds( LOOP_INTERVAL );
    while (true)
    {
        yield return waitTime;

        //LOOP_INTERVAL毎にここに記述した処理が実行されます

    }
}

(追記) 最も近いオブジェクトとそれ以外を分ける

※コードは未検証です。挙動がおかしければご自分で修正してみてください。

//serchTagが返すオブジェクトを定義
struct serchCallBackObj
{
    public GameObject neartObj;
    public GameObject[] otherObj;
}

void Start ()
{
    serchCallBackObj objs = serchTag(gameObject, "Player");

    //objs.neartObjで近いオブジェクトを取得
    //objs.otherObjでそれ以外のオブジェクトが配列で格納
}

serchCallBackObj serchTag(GameObject nowObj, string Player)
{
    float tmpDis = 0;
    float nearDis = 0;

    serchCallBackObj callBackOnj = new serchCallBackObj();
    callBackOnj.otherObj = GameObject.FindGameObjectsWithTag(Player);

    if (callBackOnj.otherObj == null
       || callBackOnj.otherObj != null && callBackOnj.otherObj.Length == 0) return callBackOnj;

    int neartObjIdx = 0;

    for (int i = 0; i < callBackOnj.otherObj.Length; i++)
    {
        tmpDis = Vector3.Distance(callBackOnj.otherObj[i].transform.position, nowObj.transform.position);
        if (nearDis == 0 || nearDis > tmpDis)
        {
            nearDis = tmpDis;
            callBackOnj.neartObj = callBackOnj.otherObj[i];
            neartObjIdx = i;
        }
    }

    //一番近い要素を削除
    System.Array.Clear(callBackOnj.otherObj, neartObjIdx, 1);

    return callBackOnj;
}

投稿 2017/11/24 16:30

編集 2017/11/27 17:59

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/11/27 16:13

    ありがとうございます!
    解決できました!
    もし、最も近いオブジェクトとそれ以外の処理を分けるといった場合はどういった方法がありますでしょうか?教えていただけましたら幸いです。

    キャンセル

  • 2017/11/27 18:02

    追記したので見てみてください。あと、次からでいいので質問する際はご自分でやってみてできなかったソースを提示するようにしてください。それと、今回2重質問になっているので次からは質問が変わる場合は別の質問として投稿してください。

    キャンセル

  • 2017/11/29 00:42

    ありがとうございます。
    以後気をつけます。

    キャンセル

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

ただいまの回答率

91.36%

関連した質問

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

  • C#

    4756questions

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

  • Unity

    2293questions

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