概要
- SEが鳴り終わったときに処理をさせたいと思ったけれど、AudioSourceに終わったときのcallbackはなさそう…だった。
- ベストなやり方か分からないけれどcallbackを自分で作りました。
- 使い所は、SEがなり終わった後に、シーン遷移する、あるAという音が鳴ったら、すぐさまBという音を鳴らしたい、といった場合です。
実装
SEがなり終わったらコンソールに「END」と表示されます。
事前に、このスクリプトがアタッチされたゲームオブジェクトにAudioSourceをアタッチしてください。
CallbackTest.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CallbackTest : MonoBehaviour {
private AudioSource audio;
void Start () {
audio = GetComponent<AudioSource>();
audio.Play();
StartCoroutine(Checking( ()=>{
Debug.Log("END");
} ));
}
public delegate void functionType();
private IEnumerator Checking (functionType callback) {
while(true) {
yield return new WaitForFixedUpdate();
if (!audio.isPlaying) {
callback();
break;
}
}
}
}
解説
ラムダ式(無名関数の利用)
StartCoroutine(Checking( ()=>{
Debug.Log("END");
} ));
- Checkingというコルーチンをスタートさせます。
- 引数には整数などの変数を入れることができますが、関数も渡せます。
- 別途、関数を定義してもよいのですが、そこまでする必要のなさそうなときは、名前がない無名関数を利用します。
- 無名関数は、ラムダ式というものを使って下記のように書くことが出来ます。
() => {
処理;
}
引数として関数を受け取る
- intやboolなどの変数は基本的な機能として何もしなくても使えますが、自前の関数を引数として取る場合は、準備が必要です。
CallbackTest.cs
public delegate void "関数名"();
- ここで関数の型を宣言して…
CallbackTest.cs
private IEnumerator Checking (functionType callback) {
- コルーチンの引数として関数を受け取ります。
SE終了の確認方法
CallbackTest.cs
while(true) {
yield return new WaitForFixedUpdate();
if (!audio.isPlaying) {
callback();
break;
}
}
- 1フレーム待ってから、
- AudioSourceが鳴っているかどうか確認します。
- もしなり終わっていれば、引数でもらった関数を実行し、終了します。
追記2020/11/13: Eventsを使用する方法
コメント欄でアドバイスを頂いたので掲載します。
「わざわざdelegateメンバを作るのは面倒臭いので、Unityならdelegateを使うのではなく
UnityEngine.Events.UnityActionを引数にする方がスリムかなと思います。」
UnityEngine.Events.UnityActionを引数にする
using UnityEngine.Events;
private IEnumerator Checking(AudioSource audio,UnityAction callback) {
while(true) {
yield return new WaitForFixedUpdate();
if (!audio.isPlaying) {
callback();
break;
}
}
}
呼び出し
void Call(){
StartCoroutine(Checking( audiosource,()=>{
Debug.Log("END");
} ));
}
追記2020/11/25: callbackのまとめ記事
以下のnpakaさんのnoteの記事にUnityでのcallbackの方法がまとめてありました。
https://note.com/npaka/n/n988adf1ecdb4