Quick Reference
strategy는 actor의 현재 mode가 아니라, 같은 목표를 수행하는 교체 가능한 알고리즘을 분리합니다. melee와 ranged attack, path selection, target scoring처럼 contract는 같고 방법이 다른 경우에 맞습니다. 숫자만 다른 balance variation은 대개 같은 algorithm의 config입니다.
| 변화 종류 | 먼저 선택 | state owner |
|---|---|---|
| 같은 목표, 다른 계산·행동 순서 | strategy | strategy 또는 context contract |
| 현재 가능한 행동 자체가 달라짐 | state / FSM | current mode와 transition |
| damage·range만 다른 tuning | config data | ScriptableObject definition |
| actor별 target·cooldown·task가 다름 | runtime instance | actor/context |
| team·mode에 따라 선택함 | factory/registry + strategy | composition root |
public abstract class AttackRule : ScriptableObject
{
public abstract void Execute(AttackContext context);
}
public sealed class AttackController : MonoBehaviour
{
[SerializeField] AttackRule rule;
[SerializeField] AttackContext context;
public void Attack() => rule.Execute(context);
}definition과 instance를 분리하기
ScriptableObject strategy는 designer가 선택하는 range, cooldown policy, prefab reference 같은 shared authoring definition에 적합합니다. asset field를 actor별 current target, remaining timer, cancellation token처럼 runtime mutable state로 쓰면 같은 asset을 참조하는 모든 actor가 서로 영향을 줄 수 있습니다. runtime state는 AttackContext, actor component, 또는 strategy instance에 둡니다.
AttackRule.Execute의 contract에는 damage 적용 대상, resource 소비 시점, success/failure, animation·VFX request, cancel 방법을 포함합니다. strategy가 FindObjectOfType, static singleton, UI를 직접 찾으면 교체 가능성은 남아도 숨은 dependency가 커집니다. 필요한 physics query·random source·effect emitter는 context 또는 narrow interface로 전달합니다.
선택과 교체의 책임
누가 current strategy를 고르는지 정합니다. weapon equip은 controller가 rule을 바꾸고, mode entry는 composition root가 config로 주입하며, adaptive AI는 decision system이 선택 결과를 전달하는 식입니다. strategy가 자기 자신을 다른 strategy로 바꾸기 시작하면 selection policy가 algorithm에 섞이므로 state 또는 coordinator를 검토합니다.
running strategy를 교체할 때는 이전 strategy의 task, animation event, reservation, listener가 정리된 뒤 새 strategy가 시작되어야 합니다. asynchronous targeting·Addressables asset·network confirmation이 있다면 cancel과 late callback을 처리합니다. Execute가 한 frame에 끝나는 policy와 여러 tick을 소유하는 behavior를 같은 contract로 뭉개지 않습니다.
타입을 늘리지 않는 기준
WalkSpeed5Rule, WalkSpeed6Rule처럼 수치만 다른 type은 ScriptableObject data 또는 serialized field로 다룹니다. algorithm·side effect·failure rule이 달라질 때만 strategy를 추가하고, 새 rule을 추가했을 때 controller와 existing rule을 수정하지 않아도 되는지 test합니다. branch가 하나뿐이고 변하지 않는다면 enum/switch가 더 명확할 수 있습니다.
ScriptableObject asset은 definition을 공유합니다. 각 actor의 target·timer·진행 상태까지 asset에 기록하면 strategy를 교체한 것이 아니라 shared global state를 만든 셈입니다.
참고 링크
2 sources