メインコンテンツまでスキップ

「Tutorial」タグの記事が5件件あります

Step-by-step tutorials

全てのタグを見る

時間ベースイベント:なぜコルーチンは遅延と繰り返しに向かないのか

TinyGiants
GES Creator & Unity Games & Tools Developer

グレネードが着弾してから2秒後に爆発を遅延させたい。シンプルだ。コルーチンを書く。IEnumerator DelayedExplosion()、yield return new WaitForSeconds(2f)、爆発ロジックを呼ぶ。丁寧に書いて10行くらい。気分がいい。

次にデザイナーが「プレイヤーが爆弾を解除できるようにしたい」と言う。オーケー、StopCoroutine()を呼べるようにCoroutine参照を保存する必要がある。でも待って——コルーチンが開始する前にプレイヤーが解除したら?nullチェックが必要。待機中にゲームオブジェクトが破壊されたら?もう一つnullチェック。コルーチンが完了したまさにそのフレームでプレイヤーが解除したら?レースコンディション。10行が25行になり、まだ「解除メッセージを表示 vs. 爆発を表示」の分岐すら処理していない。

これがUnityのすべての時間ベースイベントの物語だ。最初の実装はクリーン。2番目の要件でコード量が倍増。3番目で転職を考え始める。

デザイナーがコードなしでイベントを設定:デザイナーとプログラマーの連携問題

TinyGiants
GES Creator & Unity Games & Tools Developer

火曜の午後3時。デザイナーが横から声をかけてくる。「ねえ、プレイヤーが50以上のダメージを受けた時の画面シェイク、もう少し強くできない?あと、ヒットサウンドの前に0.5秒のディレイ入れたいんだけど。あ、毒エフェクトのティック間隔も2秒じゃなくて1.5秒にしたい。」

3つの変更。デザイナーの視点からすれば実質15秒の判断。でも実際に起きることはこうだ:Sceneビューを閉じる。IDEを開く。読み込みを待つ。ダメージハンドラーを検索する。メソッド内に埋もれた画面シェイクの強度値を見つける。変更する。次にオーディオのディレイを探す——これは別のクラスにある。変更する。次に毒のコルーチンを探す——これはさらに別のクラスで、ティックレートはWaitForSecondsの中にある。変更する。3つのファイルをすべて保存。Unityに戻る。再コンパイルを待つ。テスト。

8分後、デザイナーが言う。「やっぱりシェイクは前の方が良かったかも、あと毒は1.8秒で試せる?」

5分で始める:ゼロから作る初めてのイベント駆動システム

TinyGiants
GES Creator & Unity Games & Tools Developer

「5分しかないんだけど、イベントシステムの動かし方だけ教えてくれない?」

了解。理論もアーキテクチャの深掘りも他のアプローチとの比較もなし。Unityプロジェクトでゼロから動くイベント駆動のインタラクションを作りたい、そしてそれを速くやりたい。いこう。

このガイドはUnityプロジェクトが開いている(2021.3 LTS以降)前提で、所要時間は約5分。終わるころには、ゲーム内で何かが起きたときに発火し、完全に別のGameObjectでレスポンスをトリガーするイベントが手に入る——両者の間に直接参照はゼロで。

イベント200個超え:なぜイベント管理は破綻するのか

TinyGiants
GES Creator & Unity Games & Tools Developer

新しいUnityプロジェクトを始める。イベントを10個作る。OnPlayerDeathOnScoreChangedOnLevelComplete。分かりやすい名前を付けて、フォルダに入れて、次に進む。快適。イベント構造全体が頭に入る。

半年後。イベントが200個ある。Projectウィンドウはもう、ScriptableObjectファイルの壁だ。OnPlayerHealthDepletedが必要。いやOnPlayerHPLowだったっけ?それともOnPlayerHealthZero?全部OnPlayerで始まる名前のリストをスクロールしながら目を凝らす。3分後、欲しいイベントが既にあるかすら分からないので諦めて新しいのを作る。

これがイベント駆動のUnityプロジェクトが最終的に行き着く場所だ。イベントパターンが間違っているからじゃない。スケールでのイベント管理ツーリングを誰も作っていないからだ。Unityにはアニメーションウィンドウ、Shader Graph、Timeline、Input Systemデバッガがある。イベントが使えるのは...Projectウィンドウ。

Unityジェネリクスシリアライゼーションの壁:型安全なイベントにボイラープレート税は不要

TinyGiants
GES Creator & Unity Games & Tools Developer

GameEvent<T>を作った。クリーンで、型安全で、エレガント。ヘルス更新用にGameEvent<float>フィールドを作って[SerializeField]を付けた。Inspectorに切り替える。フィールドがない。ただ...消えている。Unityがゼロ除算を頼まれたかのように、空白のパネルでこっちを見つめている。

これはUnity最古のアーキテクチャ的な頭痛の種だ。シリアライゼーションシステムはジェネリクスを理解しない。今までずっとそうだった。型安全でデータ駆動のイベントシステムを作ろうとしたすべての開発者が、この壁に正面からぶつかっている。

些細な不便じゃない。アーキテクチャ全体を蝕む種類の制約だ。型安全性を諦めるか、ボイラープレートの海に溺れるか、美しいジェネリック設計がInspectorに触れることはないと受け入れるか。何年もの間、コミュニティの答えは「具象クラスを手書きしろ」だった。でも考えてみてほしい。ボイラープレートが100%予測可能なら、なぜ人間が書いているんだ?