본문으로 건너뛰기

포뮬러 시스템

수식을 ScriptableObject 문자열로 정의해 기획자가 코드 없이 스킬 데미지, 경험치, 밸런스 수치를 직접 수정합니다.

개요

FormulaAsset (ScriptableObject)
Expression: "Attack * SkillMultiplier - Defense + Random(0, 10)"

FormulaContext — 변수 컨테이너 (key → float)
FormulaEvaluator — 재귀 하강 파서, 런타임 계산

빠른 시작

1. FormulaAsset 만들기

Create → AchUtils/Formula/Formula Asset

인스펙터 Expression 필드에 수식을 입력합니다.

Attack * SkillMultiplier - Defense + Random(0, 10)

2. 런타임에서 계산

using AchUtils.Formula;

// 컨텍스트에 변수 설정
var ctx = new FormulaContext();
ctx.Set("Attack", sheet.GetFinal("Attack"));
ctx.Set("SkillMultiplier", skill.Multiplier);
ctx.Set("Defense", target.GetFinal("Defense"));

// 평가
float damage = damageFormula.Evaluate(ctx);
target.TakeDamage(damage);

지원 문법

연산자

연산자설명예시
+ -덧셈/뺄셈Attack + 50
* /곱셈/나눗셈Attack * 1.5
( )우선순위 그룹(Attack + Defense) * 0.5
- (단항)부호 반전-Defense

내장 함수

함수설명
Random(min, max)랜덤 float
Min(a, b)최솟값
Max(a, b)최댓값
Abs(x)절댓값
Clamp(x, min, max)범위 제한
Floor(x)내림
Ceil(x)올림
Round(x)반올림
Sqrt(x)제곱근
Pow(x, exp)거듭제곱
Sign(x)부호 (-1, 0, 1)

수식 예시

# 스킬 데미지
Attack * SkillMultiplier - Max(Defense - Penetration, 0)

# 힐 량
HealPower * 0.3 + Max(0, TargetMissingHP * 0.1)

# 방치형 골드 계산
BaseGold * Pow(1.15, Floor(Level / 10)) + Random(0, 50)

# 크리티컬 데미지
Attack * Clamp(CritMultiplier, 1.5, 3.0)

API

FormulaContext

void Set(string key, float value)
float Get(string key) // 없으면 Exception
bool Has(string key)
void Clear()

FormulaAsset

// ScriptableObject 필드
[TextArea] string Expression

// 계산
float Evaluate(FormulaContext context)

FormulaEvaluator (직접 사용 시)

var evaluator = new FormulaEvaluator();
float result = evaluator.Evaluate("Attack * 2 + 10", ctx);

에러 처리

변수가 없거나 구문 오류가 있으면 System.Exception이 발생합니다.

try
{
float damage = formula.Evaluate(ctx);
}
catch (Exception e)
{
Debug.LogError($"[Formula] {formula.name}: {e.Message}");
damage = 0f;
}

::: warning 스레드 안전성 FormulaEvaluator는 파서 상태를 인스턴스 필드로 보유하므로 동시에 여러 스레드에서 같은 인스턴스를 사용하지 마세요. FormulaAsset은 내부에 단일 evaluator를 캐싱합니다. :::