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

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

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

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

Unity

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

Q&A

解決済

1回答

4053閲覧

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

tyint121

総合スコア11

C#

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

Unity

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

0グッド

0クリップ

投稿2017/11/24 06:19

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

C#

1using UnityEngine; 2using System.Collections; 3 4 5 public class Distance_detection : MonoBehaviour 6 { 7 private GameObject nearObj; 8 private float searchTime = 0; 9 10 // Use this for initialization 11 void Start() 12 { 13 14 nearObj = serchTag(gameObject, "Player"); 15 } 16 17 // Update is called once per frame 18 void Update() 19 { 20 searchTime += Time.deltaTime; 21 if (searchTime >= 1.0f) 22 { 23 nearObj = serchTag(gameObject, "Player"); 24 searchTime = 0; 25 } 26 //nearObj = GameObject.Find("Sphere").GetComponent<Renderer>(); 27 //nearObj.material.color = Color.yellow; 28 //nearObj.transform.LookAt(nearObj.transform); 29 //nearObj.transform.Translate(Vector3.forward * 0.01f); 30 nearObj.GetComponent<colorc>().enabled = true; 31 32 } 33 34 GameObject serchTag(GameObject nowObj, string Player) 35 { 36 float tmpDis = 0; 37 float nearDis = 0; 38 GameObject targetObj = null; 39 40 41 foreach (GameObject obs in GameObject.FindGameObjectsWithTag(Player)) 42 { 43 tmpDis = Vector3.Distance(obs.transform.position, nowObj.transform.position); 44 if (nearDis == 0 || nearDis > tmpDis) 45 { 46 nearDis = tmpDis; 47 targetObj = obs; 48 } 49 50 } 51 52 return targetObj; 53 } 54 }

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

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

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

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

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

guest

回答1

0

ベストアンサー

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

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

C#

1 void Update() 2 { 3 searchTime += Time.deltaTime; 4 if (searchTime >= 1.0f) 5 { 6 nearObj = serchTag(gameObject, "Player"); 7 searchTime = 0; 8 9 //nearObjが存在するなら 10 if (nearObj != null) 11 { 12 //nearObj = GameObject.Find("Sphere").GetComponent<Renderer>(); 13 //nearObj.material.color = Color.yellow; 14 //nearObj.transform.LookAt(nearObj.transform); 15 //nearObj.transform.Translate(Vector3.forward * 0.01f); 16 nearObj.GetComponent<colorc>().enabled = true; 17 } 18 } 19 }

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

C#

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

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

C#

1//ループ間隔をfloatで指定 2static readonly float LOOP_INTERVAL = 1f; 3Coroutine m_distanceCorutine; 4 5void Start () 6{ 7 //処理のスタート 8 StartDistanceCorutine (); 9} 10 11void StartDistanceCorutine () 12{ 13 StopDistanceCorutine (); 14 m_distanceCorutine = StartCoroutine ( DistanceCorutine() ); 15} 16 17//ストップしたいときはこの関数を呼ぶ 18void StopDistanceCorutine () 19{ 20 //nullの可能性があるのでnullチェック 21 if (m_distanceCorutine != null) StopCoroutine ( m_distanceCorutine ); 22} 23 24IEnumerator DistanceCorutine() 25{ 26 var waitTime = new WaitForSeconds( LOOP_INTERVAL ); 27 while (true) 28 { 29 yield return waitTime; 30 31 //LOOP_INTERVAL毎にここに記述した処理が実行されます 32 33 } 34}

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

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

C#

1//serchTagが返すオブジェクトを定義 2struct serchCallBackObj 3{ 4 public GameObject neartObj; 5 public GameObject[] otherObj; 6} 7 8void Start () 9{ 10 serchCallBackObj objs = serchTag(gameObject, "Player"); 11 12 //objs.neartObjで近いオブジェクトを取得 13 //objs.otherObjでそれ以外のオブジェクトが配列で格納 14} 15 16serchCallBackObj serchTag(GameObject nowObj, string Player) 17{ 18 float tmpDis = 0; 19 float nearDis = 0; 20 21 serchCallBackObj callBackOnj = new serchCallBackObj(); 22 callBackOnj.otherObj = GameObject.FindGameObjectsWithTag(Player); 23 24 if (callBackOnj.otherObj == null 25 || callBackOnj.otherObj != null && callBackOnj.otherObj.Length == 0) return callBackOnj; 26 27 int neartObjIdx = 0; 28 29 for (int i = 0; i < callBackOnj.otherObj.Length; i++) 30 { 31 tmpDis = Vector3.Distance(callBackOnj.otherObj[i].transform.position, nowObj.transform.position); 32 if (nearDis == 0 || nearDis > tmpDis) 33 { 34 nearDis = tmpDis; 35 callBackOnj.neartObj = callBackOnj.otherObj[i]; 36 neartObjIdx = i; 37 } 38 } 39 40 //一番近い要素を削除 41 System.Array.Clear(callBackOnj.otherObj, neartObjIdx, 1); 42 43 return callBackOnj; 44}

投稿2017/11/24 07:30

編集2017/11/27 08:59
IShix

総合スコア1724

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

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

tyint121

2017/11/27 07:13

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

2017/11/27 09:02

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

2017/11/28 15:42

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問