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

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

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

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

Q&A

解決済

2回答

2629閲覧

コルーチンとUnityAction

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

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

0グッド

0クリップ

投稿2018/11/18 07:20

編集2018/11/19 14:11

前提・実現したいこと

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

試したこと

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

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.Events; 5 6public class Sample : MonoBehaviour { 7 8 [SerializeField] 9 GameObject cube; 10 11 void Start () { 12 StartCoroutine(ChangeCoroutine(UnityAction=>{cube.transform.position = new Vector3(x, cube.transform.position.y, cube.transform.position.z)}, 1f, 5f, 3f)); 13 } 14 15 IEnumerator ChangeCoroutine(UnityAction<float> action, float start, float end, float duration){ 16 17 float t = 0; 18 float x = 0; 19 20 while(t < 1){ 21 x = Mathf.Lerp(start, end, t); 22 t += Time.deltaTime/duration; 23 action(x); 24 yield return null; 25 } 26 27 //Mathf.Lerpに渡されるときのtが1未満でwhile文から抜ける為、調整。 28 x = end; 29 action(x); 30 } 31} 32

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

「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>も同様。

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

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

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

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

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

guest

回答2

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 01:39

編集2018/11/19 01:44
Hawn

総合スコア1222

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

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

退会済みユーザー

退会済みユーザー

2018/11/19 14:16

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

0

ベストアンサー

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

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

投稿2018/11/18 08:20

sakura_hana

総合スコア11427

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

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

退会済みユーザー

退会済みユーザー

2018/11/18 09:49

ご回答ありがとうございます。 ;を挿入したら解消しました。 続いて、まだ他のエラーメッセージ(追記しました)が出まして、 xを認識していないようなのですが、ご教示いただけませんか? コールバックのご指摘ありがとうございます。
退会済みユーザー

退会済みユーザー

2018/11/19 14:41 編集

ご回答ありがとうございます。 =>の左側は引数を書いて、=>の右側にその引数を使った処理内容を書くのですね。 以前にラムダ式を勉強したつもりでしたが、使いこなせてませんでした。 追記して、コルーチンの中のxと見分けをつけるためにposxで書きました。 引数のUnityActionの位置も最初の引数より、最後の引数で書いたほうがいいような気がして、 引数の場所を変えました。 また、ご提示いただいたURLを参考に、ラムダ式じゃない記述方法も試してみました(こちらも追記しました)。 両方のコードとも、意図した通りに動くのですが、キューブが動き始めたとき、最初ちょっと「カクッ」とした 動きになりますが、動く処理でおかしい所はありますか? また、UnityActionのジェネリックがよくわかってなかったので、 自分なりにまとめました。 おかしな所があれば、ご指摘していただきたくお願い致します。
sakura_hana

2018/11/20 02:38

>カクッとした動きになる 思い当たる点としては、startはオブジェクトの元の位置になっていますか? 例えばオブジェクトの元の位置(position.x)が「0」でstart変数に「1」を渡した場合、 最初の1フレームで「0→1」に移動するので急激に移動した(ワープした)ように見えます。 あとは処理負荷でフレーム落ちしている場合が考えられます。 こちらはソースコードだけでは判断出来ないので(Unity全体の処理負荷が影響するので)、Profilerを見ながら検証してください。 私もジェネリックの詳細はよく分かってないんで(とりあえず型指定しないよりは、しておいた方が負荷減るんじゃね?ぐらいの認識)、そこの言及は避けます。
sakura_hana

2018/11/20 02:40

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

退会済みユーザー

2018/11/20 14:49

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問