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

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

ただいまの
回答率

87.78%

【Unity】コルーチンを使って他の値を取得できない?

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 3,903

score 19

コルーチンを使って以下のような投げのコルーチンを作りたいのですが、以下の様なエラー文が出てしまいます...

そもそもコルーチンを使って他の値を参照できないのでしょうか...
詳しい方おられましたらお教えください。

NullReferenceException: Object reference not set to an instance of an object
PlayerBodyCollider+<Bind_Damage>c__Iterator0.MoveNext () (at Assets/Scripts/Player/PlayerBodyCollider.cs:56)


以下、コードの抜粋です。
public IEnumerator Bind_Damage ()
    {
        //while文を10回ループ
        int count = 5;
        while (count > 0){
            //透明にする
            playerCtrl.transform.Translate( transform.right * 1.1f );
            //0.05秒待つ
            yield return new WaitForSeconds(0.4f);
            //元に戻す
            playerCtrl.transform.Translate( transform.right * -1.1f );
            //0.05秒待つ
            yield return new WaitForSeconds(0.4f);
            count--;
        }
        count = 0;
        playerCtrl.binded = false;
        playerCtrl.SetRelease();
        //enemyCtrl.Release();
    }
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

コルーチンからメンバ変数へのアクセスをすることは可能ですし、エラー文も未定義の変数へのアクセスをしたという内容ではないので、原因はコルーチンを使用していることではないと思います。
エラーが発生しているPlayerBodyCollider.csの56行目で一体どんな処理を行っているか教えていただけますか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/09/23 00:55 編集

    >hy3様
    色々試してみたのですが、同じエラーが出てしまい上手くいきませんでした...。
    同じエラー文ということは、値を取得できていない...ということなのでしょうか...?

    原因が究明できるかわかりませんが、PlayerBodyCollider.csのソースを一度確認していただけないでしょうか...。
    以下、ソースになります。

    //---------------PlayerBodyCollider.cs----------------
    using UnityEngine;
    using System.Collections;

    public class PlayerBodyCollider : MonoBehaviour {

    //== キャッシュ ==
    PlayerController playerCtrl;
    private EnemyController enemy;

    void Awake () {
    playerCtrl = transform.parent.GetComponent<PlayerController> ();
    enemy = GetComponent<EnemyController>();
    }

    void OnTriggerEnter2D(Collider2D other) {

    // トリガーチェック
    if (other.tag == "EnemyArm") {
    EnemyController enemyCtrl = other.GetComponentInParent<EnemyController>();
    //Debug.Log(string.Format("EnemyArm Hit {0}",ec.attackEnable));
    if (enemyCtrl.attackEnabled) {
    enemyCtrl.attackEnabled = false;
    playerCtrl.dir = (playerCtrl.transform.position.x < enemyCtrl.transform.position.x) ? +1 : -1;
    playerCtrl.AddForceAnimatorVx(-enemyCtrl.attackNockBackVector.x);
    playerCtrl.AddForceAnimatorVy( enemyCtrl.attackNockBackVector.y);
    playerCtrl.ActionDamage (enemyCtrl.attackDamage);
    }
    if (enemyCtrl.binded) {
    playerCtrl.dir = (playerCtrl.transform.position.x < enemyCtrl.transform.position.x) ? +1 : -1;
    playerCtrl.SetBind ();
    enemyCtrl.Bind ();
    StartCoroutine ("Bind_Damage");
    }
    }
    }

    public IEnumerator Bind_Damage ()
    {
    //while文を5回ループ
    int count = 5;
    while (count > 0){
    // 位置を変更
    playerCtrl.transform.Translate( transform.right * 1.1f );
    //0.05秒待つ
    yield return new WaitForSeconds(0.4f);
    //位置を変更
    playerCtrl.transform.Translate( transform.right * -1.1f );
    //0.05秒待つ
    yield return new WaitForSeconds(0.4f);
    count--;
    }
    count = 0;
    playerCtrl.binded = false;
    playerCtrl.SetRelease();
    enemy.Release ();
    }
    }

    また、Releaseの記述に関しては「BaseCharacterController,cs」に以下を記述しています。
    public virtual void Release(){
    //投げ状態を解除する
    bind = false;
    //投げの終わりのアニメーションを実行する
    animator.SetTrigger ("Release");
    }

    的はずれな受け答えをしていましたら、ご指摘ください。
    よろしくお願いいたします。

    キャンセル

  • 2015/09/23 15:04 編集

    PlayerBodyColliderのAwakeメソッド内で、PlayerBodyColliderが付けられたGameObjectからEnemyControllerを取得しようとしていますが、この仕様は正しいですか?
    PlayerBodyColliderはプレイヤーキャラクタ関連のオブジェクト、EnemyControllerは敵キャラクター関連のオブジェクトに付けられるオブジェクトなのだと思いますが、それらが同じGameObjectに付けられているというのは想像し難いです。

    おそらく、EnemyControllerが付いていないためAwakeメソッド内でGetComponent<EnemyController>()がnullを返しており、結果的にBind_Damageでenemy変数(=null)のメンバメソッドを参照することになり、エラーが発生しているのではないでしょうか。


    あくまで予想ですが、OnTriggerEnter2D内で使用しているenemyCtrl変数こそが本来Bind_Damage内でReleaseしたいEnemyControllerだと思いますので、これをBind_Damageの引数として渡し、Releaseしてやればよいのではないでしょうか。

    void OnTriggerEnter2D(Collider2D other) {
    if (other.tag == "EnemyArm") {
    EnemyController enemyCtrl = other.GetComponentInParent<EnemyController>();
    if (enemyCtrl.attackEnabled) {
    // 省略
    }
    if (enemyCtrl.binded) {
    // 省略
    StartCoroutine (Bind_Damage(enemyCtrl));
    }
    }
    }

    public IEnumerator Bind_Damage (EnemyController enemyCtrl) {
    // 省略
    enemyCtrl.Release ();
    }

    キャンセル

  • 2015/09/23 15:28 編集

    >hy3様
    ご教授いただきましたソースで無事動かすことが出来ました!
    丁寧な解説をありがとうございました!

    引数の引き渡し方など曖昧でしたので
    これを機に少し勉強してみようと思います。

    キャンセル

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

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

関連した質問

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