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

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

ただいまの
回答率

88.59%

コルーチンとUnityAction

解決済

回答 2

投稿 編集

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

tkmnusr

score 323

 前提・実現したいこと

以前の質問でActionを使うことをご教示いただき、UnityActionを使って、
コールバッグコールバックする方法を実装しているのですが、UnityActionの書き方が間違っているらしく、エラーが出てしまいます。
解決方法のご教示をお願い致します。

 試したこと

Mathf.Lerpで取得した値を毎回コールバックさせて、cubeのtransfrom.postion.xに反映させることを試みています。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class Sample : MonoBehaviour {

    [SerializeField]
    GameObject cube;

    void Start () {
        StartCoroutine(ChangeCoroutine(UnityAction=>{cube.transform.position = new Vector3(x, cube.transform.position.y, cube.transform.position.z)}, 1f, 5f, 3f));           
    }

    IEnumerator ChangeCoroutine(UnityAction<float> action, float start, float end, float duration){

        float t = 0;
        float x = 0;

        while(t < 1){
          x = Mathf.Lerp(start, end, t);
          t += Time.deltaTime/duration;
          action(x);    
          yield return null;
        }

        //Mathf.Lerpに渡されるときのtが1未満でwhile文から抜ける為、調整。
        x = end;
        action(x);
    }        
}

 発生している問題・エラーメッセージ

「UnityAction=>{cube.transform.position = new Vector3(x, ~」のxに赤の下線がついていて、エラー箇所はこちらです。

error CS1002: ; expected

 続いて発生しているエラーメッセージ

error CS0103: The name `x' does not exist in the current context

 ご回答を受けて。

    void Start () {
        StartCoroutine(ChangeCoroutine(cube.transform.position.x, 5f, 3f, (posx)=>{cube.transform.position = new Vector3(posx, cube.transform.position.y, cube.transform.position.z);} ));
    }

    IEnumerator ChangeCoroutine(float start, float end, float duration, UnityAction<float> action){

        float t = 0;
        float x = 0;

        while(t < 1){
          x = Mathf.Lerp(start, end, t);
          t += Time.deltaTime/duration;
          action(x);    
          yield return null;
        }

        //Mathf.Lerpに渡されるときのtが1未満でwhile文から抜ける為、調整。
        x = end;
        action(x);
    }        

分ける場合。

    void Start () {
        StartCoroutine(ChangeCoroutine(1f, 5f, 3f, MyAction));
    }

    void MyAction(float posx){
        cube.transform.position = new Vector3(posx, cube.transform.position.y, cube.transform.position.z);
    }

    IEnumerator ChangeCoroutine(float start, float end, float duration, UnityAction<float> action){

        float t = 0;
        float x = 0;

        while(t < 1){
          x = Mathf.Lerp(start, end, t);
          t += Time.deltaTime/duration;
          action(x);    
          yield return null;
        }

        //Mathf.Lerpに渡されるときのtが1未満でwhile文から抜ける為、調整。
        x = end;
        action(x);
    }        

 UnityActionで何でジェネリックが必要なのか自分なりの解釈。

namespace UnityEngine.Events
{
    public delegate void UnityAction();
    public delegate void UnityAction<T0>( T0 arg0 );
    public delegate void UnityAction<T0, T1>( T0 arg0, T1 arg1 );
    public delegate void UnityAction<T0, T1, T2>( T0 arg0, T1 arg1, T2 arg2 );
    public delegate void UnityAction<T0, T1, T2, T3>( T0 arg0, T1 arg1, T2 arg2, T3 arg3 );
}

疑問だった点、「UnityAction<T0>( T0 arg0 );」じゃなくて、「UnityAction(T0 arg0 );」でもいいのでは?という疑問がありました。
しかし、UnityActionは、呼び出すときにUnityAction(値)の形で呼び出すので、呼び出し時には、引数の型を設定できない。
UnityAction型を宣言をするときに、UnityAction<float>のようにジェネリックに型を指定して、そのUnityActionの引数が何の型を扱うものなのか指定している。上記のようにUnityActionは宣言されているので、UnityActionのジェネリックの型指定の数が、引数の数と一致するようになっている。

UnityAction<T0>の型宣言をした場合、UnityAction<T0>(T0 arg0)を使用することになる。
UnityAction<T0, T1>の型宣言をした場合、UnityAction<T0, T1>( T0 arg0, T1 arg1 )を使用することになる。
UnityAction<T0, T1, T2>の型宣言をした場合、UnityAction<T0, T1, T2>( T0 arg0, T1 arg1, T2 arg2 )を使用することになる。
UnityAction<T0, T1, T2, T3>も同様。

    

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

0

エラー文にもそんな感じのメッセージがある通り、
cube.transform.position = new Vector3(x, cube.transform.position.y, cube.transform.position.z)の後ろに;が必要です。
UnityAction=>{ }の{}の中は普通のスクリプトと同様なので、命令行の最後には;が要ります。

ちなみに本題と無関係ですが「コールバッグ」ではなく「コールバック(callback)」です。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/20 11:38

    >カクッとした動きになる
    思い当たる点としては、startはオブジェクトの元の位置になっていますか?
    例えばオブジェクトの元の位置(position.x)が「0」でstart変数に「1」を渡した場合、
    最初の1フレームで「0→1」に移動するので急激に移動した(ワープした)ように見えます。

    あとは処理負荷でフレーム落ちしている場合が考えられます。
    こちらはソースコードだけでは判断出来ないので(Unity全体の処理負荷が影響するので)、Profilerを見ながら検証してください。

    私もジェネリックの詳細はよく分かってないんで(とりあえず型指定しないよりは、しておいた方が負荷減るんじゃね?ぐらいの認識)、そこの言及は避けます。

    キャンセル

  • 2018/11/20 11:40

    すいません、ちゃんとソース見てませんでした。startには初期位置渡してますね。
    となると処理負荷の方かな?と思います。

    キャンセル

  • 2018/11/20 23:49

    ご回答ありがとうございます。
    処理負荷かもしれないということですね。
    Profilerの見方を勉強しようと思います。
    ご教示いただきありがとうございました。

    キャンセル

0

error CS0103: The name `x' does not exist in the current context

ChangeCoroutine(UnityAction=>{cube.transform.position = new Vector3(x, cube.transform.position.y, cube.transform.position.z);部分のxが認識出来ていません。

ここのUnityActionと書かれている部分はfloatで返ってくる変数なのでUnityActionという名前ではなくxとした方が良いです。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/19 23:16

    ご回答ありがとうございます。
    ラムダ式をよく理解してなかったです。引数を書くのですね。
    ありがとうございます。

    キャンセル

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

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

関連した質問

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