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

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

ただいまの
回答率

90.61%

  • C#

    6845questions

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

  • Unity

    3801questions

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

Unityの親子関係とGetComponentについて

解決済

回答 1

投稿

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

naa

score 3

Unityで設置したボタンを押すと一定ラインにあるPrefabを消すというリズムゲームを作っています。
JsonからMIDIを読み出してPrefabをInstantiateさせ、消えるラインを決めるためにInstantiateした
Prefabを命名してDestroyさせています。
今回、流れてくるPrefab(clone)をDestroyする際にその位置によって得点を付けようと思ったのですが
Vector3をGetComponentできずにnullが返されてしまい、得点の計算ができません。
親子関係の問題かと思うのですが初心者のためどう対処していいのか分からない状況です。


エラーメッセージ

NullReferenceException: Object reference not set to an instance of an object
ScoreDelete1.ScoreDelete () (at Assets/ScoreDelete1.cs:11)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BoardMove : MonoBehaviour {

    // Use this for initialization
    void Start () {
    }

    // Update is called once per frame
    void Update () {
        transform.localPosition = new Vector3 (-TimeManager.tick * 0.8f, 0, 0);
    }
}
public class ScoreCreator : MonoBehaviour {

    //プレハブ一覧
    public GameObject ScorePrefab1;
    public GameObject ScorePrefab2;
    public GameObject ScorePrefab3;
    public GameObject ScorePrefab4;
    public GameObject ScorePrefab5;

    //プレハブのリスト
    private static float [] ScorePrefabList = new float[]{
        1,2,3,4,5
    };

    //タイマー宣言
    //private float timer;
    //ここのタイマーはスコアの生成専用なのでprivate

    //Jsonテキストデータ
    public TextAsset jsonData;

    //スコアの配列
    public List<MusicData> scoreData;


    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

    // Use this for initialization
    void Start () {

        //タイマー初期化
        //timer = TimeManager.time + 1f;

        //ランダム初期化
        Random.seed = 100;

        //テキストデータを配列に変換
        IDictionary temData = (IDictionary)Json.Deserialize (jsonData.text);

        //scoreの配列の格納
        List<object> arrayData = (List<object>)temData ["score"];

        //スコアの初期化
        scoreData = new List<MusicData> ();

        //arrayDataを解析
        foreach (IDictionary val in arrayData) {

            //eventがnote_onの場合
            if ((string)val ["event"] == "note_on") {
                scoreData.Add (
                    new MusicData (
                        (long)val ["tick"],
                        (int)(long)val ["value"]
                    )
                );
            }

            //eventがset_tempoの場合
            if ((string)val ["event"] == "set_tempo") {
                TimeManager.tempo = (int)(long)val ["value"];
            }
        }

    }

    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::




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

        //ランダムの決定
        int rand = Random.Range (0, ScoreCreator.ScorePrefabList.Length);
        float x = ScoreCreator.ScorePrefabList [rand];

        //とりあえず1秒ごとに実行って事にしとく
        //if (timer < TimeManager.time) {


        //scoreDataをループ
        foreach (MusicData tmp in scoreData) {

            //指定したTickを超えたものから生成
            if (!tmp.isCreated && tmp.tick < TimeManager.tick) {


                //譜面のxの位置を決定
                float z = tmp.tick * 0.8f + 1000;

                //譜面生成

                if (x == 1) {
                    GameObject obj1 = Instantiate (ScorePrefab1) as GameObject;
                    obj1.name = "keynote1";
                    obj1.transform.parent = transform;
                    obj1.transform.localPosition = new Vector3 (z, 300, 0);
                    obj1.transform.localScale = new Vector3 (1, 1, 1);
                    obj1.transform.SetAsFirstSibling ();
                }

                if (x == 2) {
                    GameObject obj2 = Instantiate (ScorePrefab2) as GameObject;
                    obj2.name = "keynote2";
                    obj2.transform.parent = transform;
                    obj2.transform.localPosition = new Vector3 (z, 200, 0);
                    obj2.transform.localScale = new Vector3 (1, 1, 1);
                    obj2.transform.SetAsFirstSibling ();
                }

                if (x == 3) {
                    GameObject obj3 = Instantiate (ScorePrefab3) as GameObject;
                    obj3.name = "keynote3";
                    obj3.transform.parent = transform;
                    obj3.transform.localPosition = new Vector3 (z, 100, 0);
                    obj3.transform.localScale = new Vector3 (1, 1, 1);
                    obj3.transform.SetAsFirstSibling ();
                }

                if (x == 4) {
                    GameObject obj4 = Instantiate (ScorePrefab4) as GameObject;
                    obj4.name = "keynote4";
                    obj4.transform.parent = transform;
                    obj4.transform.localPosition = new Vector3 (z, 0, 0);
                    obj4.transform.localScale = new Vector3 (1, 1, 1);
                    obj4.transform.SetAsFirstSibling ();
                }

                if (x == 5) {
                    GameObject obj5 = Instantiate (ScorePrefab5) as GameObject;
                    obj5.name = "keynote5";
                    obj5.transform.parent = transform;
                    obj5.transform.localPosition = new Vector3 (z, -100, 0);
                    obj5.transform.localScale = new Vector3 (1, 1, 1);
                    obj5.transform.SetAsFirstSibling ();
                }


                tmp.isCreated = true;
            }


            //タイマー更新
            //timer = TimeManager.time + 1f;

        }

    }

}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ScoreDelete1 : MonoBehaviour {

    public void ScoreDelete(){

        //Board外の位置を計算
        Vector3 PositionInGame
        =GetComponentInParent<BoardMove> ().transform.localPosition + transform.localPosition;

        //距離を計算
        int Distance = (int)Mathf.Abs (PositionInGame.x - (-750));

        //ポイントを計算して正規化
        float distancePoint = (100 - Distance) / 100f;

        //ポイントが0の時の処理
        if (distancePoint < 0) distancePoint = 0;

        //ポイントを加算
        GameData.score += (int)(distancePoint * 1000);

        //表示
        Debug.Log (GameData.score);

        if (distancePoint < 0) {
            Destroy (GameObject.Find ("keynote1"));
        }
    }

    public void AutoDestroy(){
        //削除//
        Destroy (GameObject.Find("keynote1"));
    }

    // Use this for initialization
    void Start () {

        int tick = 2300;

        Invoke (
            "AutoDestroy",
            (60 * tick) / (TimeManager.tempo * 480f));

    }

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



    }

}

 試したこと

ScoreDelete()で

Debug.Log(name);
Debug.Log(transform.parent.name);

と調べたところ自身は「score1(Prefab名)」、親の方は「null」が返ってきました。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

ScoreDelete1がアタッチされている親のオブジェクトにBoardMoveがアタッチされていないと動かないように見えます

ScoreDelete();
Debug.Log(name);
Debug.Log(transform.parent.name);
と調べたところ自身は「score1(Prefab名)」、親の方は「null」が返ってきました。

とのことなのでそもそも親のオブジェクトが無いようです。
何のスクリプトがどこのアタッチされているか再確認してみてください。
もしScoreDelete1BoardMoveが同じオブジェクトにアタッチされているのでしたら GetComponent<BoardMove>() を使ってみてください

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/26 18:11

    回答頂きましてありがとうございます!
    アタッチの確認・変更をしてみたところ何とか動かす事はできました…。
    ですがスコアの計算がそもそも上手くできていなかったようで悪戦苦闘しております。
    keynoteのxの位置から計算をしてスコアとして反映させる簡単な方法があったら嬉しいです…。

    キャンセル

  • 2018/04/26 18:35

    動いたようで良かったです
    スコア計算の件ですが詳細がわからないので別質問として挙げることをおすすめします
    より多くの人の目についたほうが解決率も上がると思います

    キャンセル

  • 2018/04/26 18:53

    何から何まで教えて頂きましてありがとうございます。
    スコアの計算に関しては教えて頂いたようにまた質問してみたいと思います!
    本当にありがとうございました!

    キャンセル

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

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

関連した質問

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

  • C#

    6845questions

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

  • Unity

    3801questions

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