スクリプトをアクティブにする
解決済
回答 1
投稿
- 評価
- クリップ 0
- VIEW 1,452
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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
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;
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 89.99%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2017/11/27 16:13
解決できました!
もし、最も近いオブジェクトとそれ以外の処理を分けるといった場合はどういった方法がありますでしょうか?教えていただけましたら幸いです。
2017/11/27 18:02
2017/11/29 00:42
以後気をつけます。