MusicEngineの話もありますが・・・
何に使ったかというと
GGJ2018参加してきました
CRI渋谷会場で、Interstellar Radio Starを作りました。
動画:
https://www.youtube.com/watch?time_continue=3&v=VU3AS9ewDao
Webサイト:
https://globalgamejam.org/2018/games/interstellar-radio-star
今回はすごくスムーズでした
なんとgithubで共有してたけど 一度もトラブルがなかった。
だいたい同じソースを同時に編集したりとか、マージできなかったりとかよくあるのですが。
今回初めて使ったのですが、C#のActionの機能がすごかった。
Actionってなに?
詳しくは c# event Action などで検索してもらったら良いかと。
これ、サウンドの組み込みではとてもありがたくて、
Actionが 例えば、 onEndGame (ゲーム終了時のイベント(コールバック))
といった感じなので、
Action onStartGame = () => {};
Action onSelectStage = () => {};
Action onEndGame = () => {};
Action onRestartGame = () => {};
こんな感じで、ゲームで起こりそうなものがアクションイベントになってて
onEndGame += () => {
SoundManager.instance.Play("ClearSound");
};
みたいに、他のソースコードを汚さずにとてもシンプルにサウンド機能の追加が書けるのです。
これ、多人数でやっているとき、ゲームのロジックと、サウンド処理が混在してカオスになるコードが、
とてもすっきりかけて、しかもマージもしやすい。
(裏で、どれだけスレッドとか処理が走るのかとか処理順番はとかはよくわからないですが、少なくともゲームジャムでは便利)
Actionが定義されていれば、サウンドの組み込み担当は、ゲームのソースコードをほぼ理解せずとも、この +=で付け足すだけで良いし、
サウンドのためのコードとかでソースが縦に長くなったりするのがないので、とってもありがたいことだと思われます。
実際のコード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
public class StageSelectView : MonoBehaviour {
public Image[] item;
public Image cursor;
public int selectedItemIndex = 0;
public Action<int> onSelectItem = _ => {};
public Action<int> onDecideItem = _ => {};
void Start()
{
onDecideItem += _ => {
switch(_)
{
case 0:
SoundManager.Instance.PlayBGM (SoundManager.enum_bgm.gymnopediIntro);
break;
case 1:
SoundManager.Instance.PlayBGM (SoundManager.enum_bgm.bachIntro);
break;
case 2:
SoundManager.Instance.PlayBGM (SoundManager.enum_bgm.kiraIntro);
break;
default:
SoundManager.Instance.PlayBGM (SoundManager.enum_bgm.kiraIntro);
break;
}
};
SoundManager.Instance.PlaySE (SoundManager.enum_se.noteSound);
}
/// <summary>
/// 項目選択
/// </summary>
/// <param name="index">Index.</param>
public void OnSelectItem(int index) {
if (selectedItemIndex == index) {
onDecideItem (index);
SoundManager.Instance.PlaySE (SoundManager.enum_se.BD);
} else {
onSelectItem (index);
selectedItemIndex = index;
SoundManager.Instance.PlaySE (SoundManager.enum_se.puls);
}
}
void Update() {
// cursor移動
cursor.transform.position = Vector3.Lerp(cursor.transform.position, item[selectedItemIndex].transform.position, 0.8f);
if (Input.GetKeyDown (KeyCode.LeftArrow) && selectedItemIndex != 0) {
OnSelectItem (Mathf.Clamp (selectedItemIndex - 1, 0, 2));
}
if (Input.GetKeyDown (KeyCode.RightArrow) && selectedItemIndex != 2) {
OnSelectItem (Mathf.Clamp (selectedItemIndex + 1, 0, 2));
}
if (Input.GetKeyDown (KeyCode.Space)) {
onDecideItem (selectedItemIndex);
}
}
}
publicだとどこからでも呼ばれてしまうので
public event Action onStartGame = () => {};
public event Action onSelectStage = () => {};
public event Action onEndGame = () => {};
public event Action onRestartGame = () => {};
たとえば、こんな感じにすると、クラス内でこのActionを呼ぶと
外から関連する処理を拡張したりできるようになるのかな・・・
#ADX2LEを使う
修正点
小文字にする
このエラー
musicSource_.player
ADX2LEの最新版ではplayerでアクセスできる!
よし。
ちょっとはまったところ
MusicEngineのPlay関数の引数の名前って、ゲームオブジェクトの名前なのですね。
最初キュー名指定していて、うまくいかなくて、なんでだろう・・・ってなってた。
おまけ
OSCのやりとりで、ちゃんとポートに飛んでいるか
sudo tcpdump -i lo0 port 12001
といった感じで、自身の12001にメッセージがきているか調べられる。