198 Views
December 24, 24
スライド概要
ADX / ADX LE勉強会 vol.1 資料
ADX for Unityの機能を拡張する 様々なスクリプトのご紹介 株式会社ヘッドハイ 一條貴彰
自己紹介:一條貴彰 ● ● ● ● インディーゲーム開発者 (2014~ ゲーム産業特化のツールエヴァンジェリスト事業 ○ ADXアンバサダー インディーゲーム開発者向け支援事業 ○ iGi indie Game incubator ○ 経済産業省「創風」 ○ Indie Developer Conference ○ IndieGamesJp.dev 著著 ○ ○ 「インディーゲーム・サバイバルガイド」技術評論社 「Unityサウンド エキスパート養成講座」ボーンデジタル 2
過去作『Back in 1995』 • Steam(PC): 2016年4月発売 • 後に3DS/PS4/PS Vita/Switch/Xbox Oneで発売 • 「3D黎明期のゲーム」が題材 • • • • レトロ3Dという絵作り 不自由な操作 理不尽なストーリー メタ要素 • レトロ3D表現は(たぶん当時)世界初 • 2015年発表 • 現在、PS1っぽいゲームは沢山!
開発中「デモリッション ロボッツ プランB」 ● 4人マルチプレイロボットアクションゲーム ○ 4年ほど作っていた別作品を最近再スタート ○ Unity Netcode for GameObjects + ADX2 ■ VContainerのDI環境でCriAtomどうするといい感じかな…
クラフトビール大好き!!
もくじ ● Unity Editor全般 ○ ○ GameViewのミュートボタンをADX対応にする カテゴリごとのミュートボタンを作る ● AtomBrowser拡張 ○ ○ データのインポート先パスを指定可能にする キュー一覧の任意情報を出す ● 他のプラグインとの連携 ○ ○ ノードエディタ(Dozzy UI) R3
GameビューのミュートボタンをADX対応にする
EditorUtility.audioMasterMuteをフックしてSetBusVolume
using CriWare;
using UnityEditor;
[InitializeOnLoadAttribute]
public class CriWareGameViewMuteButton
{
private static bool isAudioMute = false;
static CriWareGameViewMuteButton()
{
EditorApplication.update += () =>
{
if (isAudioMute == EditorUtility.audioMasterMute) return;
isAudioMute = EditorUtility.audioMasterMute;
}
}
};
CriAtomExAsr.SetBusVolume(0, isAudioMute ? 0f : 1f);
https://gist.github.com/TakaakiIchijo/6d2f8573ac92e877a621e5aa679c7a18
カテゴリごとのミュート サウンドのカテゴリ(BGMや効果音)ごとにミュートするボタンを表示
カテゴリごとのミュート ● Gameビューの参照をリフレクションで取得して上にボタンを描画 ○ ● https://qiita.com/Takaaki_Ichijo/items/e3c95ab7ab27af211b2d 今ならCustom Editor tools / Overlaysで シーンビュー内にも出せる
AtomBrowser拡張:データのインポート先パスを指定可能にする https://qiita.com/Takaaki_Ichijo/items/e39793805637a1bc576c
AtomBrowser拡張:データのインポート先パスを指定可能にする
private void GUIImportAssetsFromAtomCraft()
{
//(略)
GUILayout.EndHorizontal();
if (criAtomWindowPrefs != null) {
criAtomWindowPrefs.outputAssetsRoot = GUILayout.TextArea(criAtomWindowPrefs.outputAssetsRoot);
}
//GUILayout.Label(Application.dataPath);
//(略)
//以降を新規追加
GUILayout.BeginHorizontal();
GUILayout.Label("Import Folder Path:");
if (GUILayout.Button("Select Folder Path")) {
string tmpStr = String.Empty;
tmpStr = EditorUtility.OpenFolderPanel("Select import folder", tmpStr, criAtomWindowPrefs.outputAssetsRoot);
if (tmpStr != String.Empty)
{
criAtomWindowPrefs.importFolderPath = tmpStr;
criAtomWindowPrefs.Save();
}
}
GUILayout.EndHorizontal();
if (criAtomWindowPrefs != null) {
criAtomWindowPrefs.importFolderPath = GUILayout.TextArea(criAtomWindowPrefs.importFolderPath);
}
//(略)
//以上を新規追加
}
AtomBrowser拡張:キュー情報を出す改造 ● ● エディタ拡張のデータ読み出し時の処理と、ウィンドウの表示エリアを改造 今回は「ユーザーデータ」を読み出して、一覧表示させる デフォルトでは 「キュー名」 「キューID」 が確認できる。
例:追加情報の表示 ・キューリミット ・カテゴリ ・ユーザーデータ
実装:CriAtomWindowPrefs.csのCueInfoクラスを改造
AtomBrowserで見たい情報を格納するフィールドを追加
public class CueInfo : InfoBase {
public bool isPublic;
public short numLimits; //追加
public List<string> categoryNames; //追加
}
public CueInfo(string name, int id, string comment, bool isPublic, short numLimits, List<string> categoryNames) {
this.name = name;
this.id = id;
this.comment = comment;
this.isPublic = isPublic;
this.numLimits = numLimits; //追加
this.categoryNames = categoryNames; //追加
}
CriAtomWindowPrefs.csでカテゴリ名の取り出し
キューの中にはカテゴリの「ID」が入っているため、実際のカテゴリ名を
GetCategoryInfoByIndexで取り出す
List<string> categoryNames = new List<string>();
foreach (var category in cueInfo.categories)
{
CriAtomExAcf.CategoryInfo categoryInfo = new CriAtomExAcf.CategoryInfo();
CriAtomExAcf.GetCategoryInfoByIndex(category, out categoryInfo);
categoryNames.Add(categoryInfo.name);
}
acbInfo.cueInfoList.Add(new CueInfo(cueInfo.name, cueInfo.id, cueInfo.userData,
Convert.ToBoolean(cueInfo.headerVisibility),cueInfo.numLimits, categoryNames));
CriAtomWindow.csのGUICueListに追記 private void GUICueList() { //(略) using (var cueListTitleScope = new EditorGUILayout.HorizontalScope()) { if (GUILayout.Button("Cue Name", toolBarButtonStyle)) { if (isCueSheetAvailable) { acbInfoList[selectedCueSheetId].SortCueInfo(CriAtomWindowInfo.CueSortType.Name); this.selectedCueInfoIndex = 0; } } //以下を追加 if (GUILayout.Button("Category", toolBarButtonStyle, GUILayout.Width(200))) { if (isCueSheetAvailable) { acbInfoList[selectedCueSheetId].SortCueInfo(CriAtomWindowInfo.CueSortType.Id); this.selectedCueInfoIndex = 0; } } if (GUILayout.Button("Cue Limit", toolBarButtonStyle, GUILayout.Width(70))) { if (isCueSheetAvailable) { acbInfoList[selectedCueSheetId].SortCueInfo(CriAtomWindowInfo.CueSortType.Id); this.selectedCueInfoIndex = 0; } } //以上を追加
注意:AtomBrowserをいじると SDKアップデート時に消える ● SDK同梱のスクリプトに手を入れているので、アプデ時に消える!!
ノードエディタ(Dozzy UI)連携 ●
ノードエディタ系に必要な機能 ● イニシャライズ ○ ● キューシートの読み込み ○ ○ ● ● CriAtomの初期化を待つ LoadCueSheetを実行・完了待ち ACB,AWBファイルを指定できるようにする キュー再生・停止 Aisac操作
R3連携
例
シーケンスコールバックを購読するやつ
using CriWare;
namespace R3.Triggers
{
public static class CriAtomExSequencerObservable
{
public static Observable<CriAtomExSequencer.CriAtomExSequenceEventInfo> OnCallbackObservable()
{
return Observable.FromEvent<CriAtomExSequencer.EventCallback,
CriAtomExSequencer.CriAtomExSequenceEventInfo>
(h => (ref CriAtomExSequencer.CriAtomExSequenceEventInfo info) => h(info),
h => CriAtomExSequencer.OnCallback += h,
h => CriAtomExSequencer.OnCallback -= h);
}
}
}
R3連携
こう書ける!!便利
public void SetCallbackToCueSequenceCallback(string tag)
{
CriAtomExSequencerObservable.OnCallbackObservable()
.Where(info => info.tag == tag)
.Subscribe(info =>
{
Debug.Log("playId: " + info.playbackId);
});
}
他のプラグインとの連携 ● 現在アンバサダーが開発中 ○ ○ ● RPG Maker Unite 宴4 今後やりたい ○ NaniNovel
ご清聴ありがとうございました