AchReactive
가이드

확장하기

새 동작, 새 도메인, 크로스 도메인 연결.

새 동작 추가

길 A — Attribute (권장)

[Effect]/[Condition]/[Trigger] 를 붙인 정적 메서드를 작성하면 AutoRegister() 가 모든 어셈블리에서 자동 수집합니다. 배선 코드가 없습니다.

using AchReactive;

public static class MyEffects
{
    [Effect("teleport")]
    public static void Teleport(ReactionContext c) =>
        c.Source.Position = c.World != null ? /* ... */ c.Source.Position;
}

시그니처는 고정입니다.

[Effect("name")]    static void M(ReactionContext ctx)
[Condition("name")] static bool M(ReactionContext ctx)
[Trigger("name")]   static bool M(ReactionContext ctx, ParamBag triggerParams)

길 B — 수동등록

DI, 런타임 상태, 클로저가 필요할 때 사용합니다.

EffectRegistry.Register("teleport", c => myTeleporter.Move(c.Source));

새 도메인 추가

새 도메인은 데이터 클래스 1개 면 충분합니다. 시스템 코드는 없습니다.

[Serializable]
public class MonsterData : EntityData   // id / stats / reactions 상속
{
    public int expReward;               // 도메인 고유 필드
}
var monsters = new DataBase<MonsterData>();
monsters.Load(new JsonDataLoader<MonsterData>(() => json));

engine.Run("on_hp_below", monsters.Get("goblin_boss"), ctx);

damage/add_modifier 등은 스킬이 이미 등록한 것을 그대로 재사용합니다 → 코드 0줄. 데이터 클래스와 CSV 매퍼는 Type Designer 로 생성할 수 있습니다.

크로스 도메인

effect 가 다른 도메인 데이터를 참조해야 하면, 자동등록 대신 수동등록 + 클로저 캡처로 해당 DataBase<T> 를 잡습니다. 타입 키(typeof)를 쓰지 않습니다.

var items = new DataBase<ItemData>();

EffectRegistry.Register("drop_item", c =>
{
    var item = items.Get(c.Params.Get<string>("itemId")); // items 를 클로저로 캡처
    c.World.Spawn(item.id, c.Source.Position);
});

권장: 자동등록 effect 는 도메인을 모르는 순수 동작만, 도메인 결합이 필요한 effect 만 수동등록.

AOT (IL2CPP) 주의

AutoRegister() 는 리플렉션 기반이라 IL2CPP 빌드에서 메서드가 스트리핑될 수 있습니다. 동작 메서드가 포함된 어셈블리를 link.xml 로 보존하세요.

<linker>
  <assembly fullname="YourGameAssembly" preserve="all" />
</linker>

리플렉션을 피하고 싶으면 길 B(수동등록) 만 사용해도 됩니다.

목차