Upgrade to Pro — share decks privately, control downloads, hide ads and more …

宴はいいぞ

いも
July 31, 2020

 宴はいいぞ

yokohama.unity #4 でのLT資料です

いも

July 31, 2020
Tweet

More Decks by いも

Other Decks in Programming

Transcript

  1. ━━━━━━━━━━━━━━━━━
    宴はいいぞ
    いも(@adarapata)
    ━━━━━━━━━━━━━━━━━
    2020/07/31 yokohama.unity #4 1

    View full-size slide

  2. ⾃⼰紹介
    いも (@adarapata)
    adarapata.com
    仕事でUnity触ってるエンジニア
    テスト、DIとかよく話すおじさん
    最近Godot Engineがアツい
    2020/07/31 yokohama.unity #4 2

    View full-size slide

  3. 宴とは
    「ビジュアルノベルをかんたん作成」できる有償アセット
    会話テキストの表⽰
    キャラ⽴ち絵の設定、表情変更
    ⼀枚絵、パーティクルによる演出強化
    選択肢による分岐、パラメータ機能
    ログ機能
    Excelによるシナリオ管理、およびデータ設定
    etc...
    2020/07/31 yokohama.unity #4 3

    View full-size slide

  4. 公式が最強
    https://madnesslabo.net/utage/
    2020/07/31 yokohama.unity #4 4

    View full-size slide

  5. 今⽇話すこと
    宴を⾃分のゲームに組み込むときのお話
    スクリプトでの実⾏⽅法
    アプリケーション -> 宴の連携
    宴 -> アプリケーションへの連携
    アセット管理の連携
    サウンド周りのカスタマイズ 時間⾜りなかった
    対象者
    ⾃作ゲームの会話パート周り作るのが⾯倒だなと思っている⼈
    2020/07/31 yokohama.unity #4 5

    View full-size slide

  6. 組み込みの話
    宴は単体でノベルゲームを作成できるが、⾃分のアプリケーションと
    組み合わせて使うこともできる。
    https://madnesslabo.net/utage/?page_id=402
    ゲーム内の会話シーンとして宴を使う
    チュートリアル部分だけ使う
    これを⾏うためにはいくつかスクリプトを書いて、連携処理を⾏う必
    要がある。
    2020/07/31 yokohama.unity #4 6

    View full-size slide

  7. 宴で主に登場するScriptableObject
    宴に使うシナリオやリソースの定義は全てExcelファイルで⾏う。
    Excelファイルが更新されるとImporterが⾛り、ScriptableObjectが⽣
    成or更新される
    Project: 宴のプロジェクトファイル全体の設定情報を持つ
    最上位のファイルなのでExcelから⽣成はされない
    Scenarios: Chapterファイルの情報を1:Nで持つ
    Chapter: 「章」に相当する。Bookを1:Nで持つ
    Book: Excelファイルをパースしたもの。xlsと1:1の関係
    Excelファイルは任意の粒度で分割できる
    2020/07/31 yokohama.unity #4 7

    View full-size slide

  8. AdvEngineの起動
    スクリプトからの最低限の⼿順は以下の感じ
    _advEngine = FindObjectOfType();
    // 初期化
    _advEngine.BootFromExportData(scenarioData, "directory/path");
    // シナリオ呼び出し
    _advEngine.JumpScenario("scenario_name");
    // シナリオを読み終えるまで待つ
    yield return new WaitUntil(_ => _advEngine.IsEndOrPauseScenario);
    Scenarios.assetをどこかから取ってくればOK
    2020/07/31 yokohama.unity #4 8

    View full-size slide

  9. アプリケーション -> 宴
    宴はシナリオ内部でパラメータを定義できる
    パラメータはシナリオ内で計算したり、タグを使って表⽰することも
    できる
    2020/07/31 yokohama.unity #4 9

    View full-size slide

  10. このパラメータはスクリプト側からget,setできる
    advEngine.Param.TrySetParameter("名前", "imo");
    advEngine.JumpScenario("test");
    プレイヤーの名前とか、レベルとかゲーム側の状況を渡して遊べる
    2020/07/31 yokohama.unity #4 10

    View full-size slide

  11. 宴 -> アプリケーション
    シナリオで打ち込めるコマンドは基本的には宴にしか影響を与えない
    が、アプリケーション側に影響を与えるようなコマンドを⾃分で作る
    こともできる
    GameOver というコマンドはデフォルトでは存在しないが、スクリプト
    側でこのコマンドをパースして独⾃の処理を⾏える。
    これをカスタムコマンドと呼ぶ。
    2020/07/31 yokohama.unity #4 11

    View full-size slide

  12. カスタムコマンドクラスは AdvCommand を継承させる
    public class GameOverCommand : AdvCommand
    {
    public GameOverCommand(StringGridRow row) : base(row) { }
    public override void DoCommand(AdvEngine engine)
    {
    // ゲームオーバーにさせる何某
    }
    }
    コンストラクタはシナリオ読み込みタイミングで呼び出され、実際の
    コマンド実⾏時に DoCommand が呼ばれる
    2020/07/31 yokohama.unity #4 12

    View full-size slide

  13. パース処理を担う AdvCommandParser にコールバックがある
    public class CustomCommandManager : MonoBehaviour {
    private void Awake() {
    Utage.AdvCommandParser.OnCreateCustomCommandFromID += OnCreateCustomCommand;
    }
    private void OnCreateCustomCommand(
    string id, StringGridRow row, AdvSettingDataManager datamanager, ref AdvCommand command)
    {
    switch (id)
    {
    case "GameOver":
    command = new GameOverCommand(row);
    break;
    }
    }
    }
    コマンド名(ID)が取得できるので、⽣成処理を書いていく。
    2020/07/31 yokohama.unity #4 13

    View full-size slide

  14. リソース管理
    基本的には3種類
    ビルドに含めて Resources.Load (ローカル)
    宴側が⽤意しているAssetBundleManagerでロードする
    Manifestファイル or ⾃前でリスト登録
    ⾃作のファイルマネージャーを組み合わせる
    宴だけで完結するなら宴側のAssetBundleManager使うと楽。
    いい感じのリソースコンバーターも⽤意している。
    今回は⾃作のファイルマネージャーを組み合わせる話
    2020/07/31 yokohama.unity #4 14

    View full-size slide

  15. Asset管理周りの登場⼈物
    覚えておくべきはこの⼆つ
    AssetFileBase
    AssetFileManager
    2020/07/31 yokohama.unity #4 15

    View full-size slide

  16. AssetFileBase
    ファイル名、種類などアセットの情報を持つ基底クラス
    アセットをどのようにロードするかを知っている。
    具体的には LoadAsync を実装させる
    1アセットごとに作られるクラス
    シートに10個の画像を定義したのなら10個のAssetFileBase
    デフォルトではこれを継承した AssetFileUtage のインスタンスが
    作られる
    2020/07/31 yokohama.unity #4 16

    View full-size slide

  17. AssetFileManager
    AssetFileBase を管理するクラス
    宴の初期化時にシナリオデータから⾃動でアセットのインスタンス
    を追加してくれる
    基本的にはクラスそのものを叩く必要はない
    AssetFileBase インスタンスを作る処理をフックできる
    AssetFileManager.GetCustomLoadManager().OnFindAsset += MyFindAsset
    CustomLoadManagerに噛ませることができる
    2020/07/31 yokohama.unity #4 17

    View full-size slide

  18. 噛ませる
    public class MyFileManager : MonoBehaviour {
    void Awake()
    {
    // 宴のアセット検索時に⾃前のコールバックを噛ませる
    AssetFileManager.GetCustomLoadManager().OnFindAsset += FindAsset;
    }
    void FindAsset(AssetFileManager mangager,
    AssetFileInfo fileInfo, IAssetFileSettingData settingData, ref AssetFileBase asset)
    {
    switch (fileInfo.FileType)
    {
    case AssetFileType.Texture:
    asset = new MyTexture2DFile(mangager, fileInfo, settingData);
    }
    }
    }
    2020/07/31 yokohama.unity #4 18

    View full-size slide

  19. ⾃前の AssetFileBase を継承したクラスを作る
    public class MyTexture2DFile : AssetFileBase {
    public override IEnumerator LoadAsync(System.Action onComplete, System.Action onFailed)
    {
    // ⾃前のManagerからアセットを取ってくる何某
    yield return InitFromAbManager();
    IsLoadEnd = true;
    onComplete();
    }
    public override bool CheckCacheOrLocal() { return false; }
    public override void Unload() => IsLoadEnd = false;
    IEnumerator InitFromAbManager()
    {
    // ⾃前のManagerから取ってきて渡す
    Texture = MyAssetBundleManager.LoadAssetBundle(FileInfo.FileName);
    }
    }
    2020/07/31 yokohama.unity #4 19

    View full-size slide

  20. AssetFileBaseのプロパティ
    Text : テキストアセット
    Texture : 画像リソース系(キャラクター・背景etc)
    Sound : ⾳声リソース(Unity Audio限定)
    UnityObject : その他シナリオファイルとかパーティクル、3Dモデ
    ル etc..
    最終的に FileType と⼀致するプロパティにデータが⼊っていれば問題
    なく動く・・と思う
    (FileType == AssetFileType.Texture) なら Texture プロパティがnull
    でないことを期待している
    2020/07/31 yokohama.unity #4 20

    View full-size slide

  21. そのほか組み込みのいいところ
    宴のコードが基本的に拡張前提に作られている
    コールバックでのフックを⽤意している箇所が多い
    継承できるような設計になっている
    コード⾒れるし最悪システムの差し替えやれないことはない
    情報が多い
    公式のフォーラムが活発、困ったら⼤体誰かが踏んでる
    ⾮エンジニアに対しての敷居が低い
    Excelという馴染みのある武器、構⽂エラーが丁寧に出る
    コンテンツを作り始めてからが本番だから・・
    2020/07/31 yokohama.unity #4 21

    View full-size slide

  22. まとめ
    宴は組み込みができるぞ
    スクリプトからの実⾏は簡単だよ
    宴 <-> アプリケーションの相互連携もできるよ
    リソース管理を⾃前のManagerと連携もできるよ
    宴はいいぞ
    2020/07/31 yokohama.unity #4 22

    View full-size slide