基本的な使い方
目的
このページでは、プロジェクトでReactive Entity Setsをセットアップして使用する手順を説明します。state構造体、entity setアセット、entityコンポーネントを作成します。
ステップ1 state構造体を定義する
エンティティデータを保持する構造体を作成します。[System.Serializable]を付与してください。
using System;
[Serializable]
public struct EnemyState
{
public int Health;
public int MaxHealth;
public bool IsStunned;
public float HealthPercent => MaxHealth > 0 ? (float)Health / MaxHealth : 0f;
public bool IsDead => Health <= 0;
}
ステップ2 reactive entity setアセットを作成する
ReactiveEntitySetSO<T>を継承するクラスを作成します。
using Tang3cko.ReactiveSO;
using UnityEngine;
[CreateAssetMenu(
fileName = "EnemyEntitySet",
menuName = "Reactive SO/Entity Sets/Enemy"
)]
public class EnemyEntitySetSO : ReactiveEntitySetSO<EnemyState>
{
// ベースクラスがすべての機能を提供
}
Projectウィンドウで以下のメニューパスを選択してアセットを作成します。
Create > Reactive SO > Entity Sets > Enemy
ステップ3 イベントチャンネルを作成する(オプション)
セットレベルの変更通知が必要な場合、イベントチャンネルを作成します。
Create > Reactive SO > Channels > Int Event
entity setのフィールドに割り当てます。
| フィールド | 発火タイミング |
|---|---|
| On Item Added | エンティティが登録されたとき |
| On Item Removed | エンティティが登録解除されたとき |
| On Data Changed | いずれかのエンティティのデータが変更されたとき |
| On Set Changed | 任意の変更時 |
ステップ4 entityコンポーネントを作成する
自動ライフサイクル管理のためにReactiveEntity<T>ベースクラスを使用します。
using Tang3cko.ReactiveSO;
using UnityEngine;
public class Enemy : ReactiveEntity<EnemyState>
{
[SerializeField] private EnemyEntitySetSO entitySet;
[SerializeField] private int maxHealth = 100;
// 必須: 使用するセットを指定
protected override ReactiveEntitySetSO<EnemyState> Set => entitySet;
// 必須: 初期状態を指定
protected override EnemyState InitialState => new EnemyState
{
Health = maxHealth,
MaxHealth = maxHealth,
IsStunned = false
};
public void TakeDamage(int damage)
{
var state = State;
state.Health = Mathf.Max(0, state.Health - damage);
State = state; // 自動的にイベントをトリガー
if (state.IsDead)
{
Destroy(gameObject); // OnDisableで自動的に登録解除
}
}
}
ステップ5 エンティティデータをクエリする
任意のスクリプトからエンティティデータにアクセスします。
public class EnemyManager : MonoBehaviour
{
[SerializeField] private EnemyEntitySetSO entitySet;
public int GetTotalEnemyHealth()
{
int total = 0;
entitySet.ForEach((id, state) => {
total += state.Health;
});
return total;
}
}
APIリファレンス
プロパティ
| プロパティ | 型 | 説明 |
|---|---|---|
Count | int | 登録されたエンティティ数 |
EntityIds | NativeSlice<int> | すべての登録エンティティID |
Data | NativeSlice<TData> | すべてのエンティティデータ |
メソッド
| メソッド | 説明 |
|---|---|
Register(owner, data) | 初期状態でエンティティを登録 |
Unregister(owner) | セットからエンティティを削除 |
GetData(owner) | エンティティの現在の状態を取得 |
TryGetData(owner, out data) | エンティティの状態を安全に取得 |
SetData(owner, data) | エンティティの状態を更新 |
UpdateData(owner, func) | 関数で状態を更新 |
NotifyDataChanged(owner) | データ変更を手動で通知 |
Contains(owner) | エンティティが存在するか確認 |
Clear() | すべてのエンティティを削除 |
ForEach(action) | すべてのエンティティを反復 |
SubscribeToEntity(id, callback) | エンティティの変更をサブスクライブ |
UnsubscribeFromEntity(id, callback) | エンティティからサブスクライブ解除 |
パフォーマンス特性
Reactive Entity SetsはNativeArrayとNativeHashMapに基づくSparse Setデータ構造を使用します。
| 操作 | 時間計算量 |
|---|---|
| Register | O(1) |
| Unregister | O(1) |
| GetData | O(1) |
| SetData | O(1) |
| イテレーション | O(n) |
データはキャッシュ効率とJob System互換性のためにNativeArrayに連続して格納されます。NativeHashMapがIDからインデックスへO(1)で変換します。