Files
2nd/10_Wiki/Topics/AI_and_ML/포탑 시스템(Turret Systems).md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

7.4 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-포탑-시스템-turret-systems 포탑 시스템(Turret Systems) 10_Wiki/Topics verified self
Turret Systems
Tower Defense
Auto-targeting
none A 0.85 applied
game-design
ai
gameplay
tower-defense
2026-05-10 pending
language framework
C# / GDScript Unity / Godot

포탑 시스템(Turret Systems)

매 한 줄

"매 stationary defender 의 자동 target 의 acquisition + tracking + firing.". 매 1980s arcade (Missile Command) 부터 매 modern tower defense (Bloons TD 6, PvZ), 매 RTS (StarCraft 의 turret), 매 FPS (Team Fortress 2 의 sentry) 의 universal mechanic. 매 target selection + range + cooldown + projectile 의 4-axis design.

매 핵심

매 component

  • Target acquisition: 매 range 내 enemy 의 detection — sphere/cone overlap.
  • Target selection: 매 closest / lowest HP / highest threat / first / last 의 priority.
  • Aim / tracking: 매 turret 의 rotation 의 slerp / lerp.
  • Firing: 매 cooldown + projectile spawn / hitscan.
  • Upgrade tree: 매 damage / range / fire rate / special 의 progression.

매 design axis

  • Range: 매 short (high DPS) vs long (low DPS) 의 tradeoff.
  • AoE: 매 splash damage — 매 group 의 효과적.
  • Status: 매 slow / burn / poison 의 debuff.
  • Projectile: 매 hitscan vs ballistic — 매 leading prediction 의 필요.
  • Cost / placement: 매 economic + spatial constraint.

매 응용

  1. Tower defense: 매 wave 의 incremental difficulty.
  2. RTS: 매 base defense 의 layer.
  3. FPS: 매 area denial 의 device.

💻 패턴

Unity 의 turret base

public class Turret : MonoBehaviour
{
    public float range = 10f;
    public float fireRate = 1f;
    public Transform muzzle;
    public GameObject projectile;

    private Transform target;
    private float cooldown;

    void Update()
    {
        if (target == null || Vector3.Distance(transform.position, target.position) > range)
            target = FindTarget();

        if (target != null)
        {
            AimAt(target);
            cooldown -= Time.deltaTime;
            if (cooldown <= 0f) { Fire(); cooldown = 1f / fireRate; }
        }
    }

    Transform FindTarget()
    {
        Collider[] hits = Physics.OverlapSphere(transform.position, range, LayerMask.GetMask("Enemy"));
        return hits.OrderBy(c => Vector3.Distance(transform.position, c.transform.position))
                   .FirstOrDefault()?.transform;
    }

    void AimAt(Transform t)
    {
        Vector3 dir = (t.position - transform.position).normalized;
        Quaternion target = Quaternion.LookRotation(dir);
        transform.rotation = Quaternion.Slerp(transform.rotation, target, Time.deltaTime * 8f);
    }

    void Fire()
    {
        Instantiate(projectile, muzzle.position, muzzle.rotation);
    }
}

Target priority strategy

public enum Priority { Closest, Lowest, Highest, First, Last }

Transform FindTarget(Priority p)
{
    var enemies = Physics.OverlapSphere(transform.position, range, enemyLayer)
        .Select(c => c.GetComponent<Enemy>()).Where(e => e != null);

    return p switch
    {
        Priority.Closest => enemies.OrderBy(e => Vector3.Distance(transform.position, e.transform.position)).FirstOrDefault()?.transform,
        Priority.Lowest => enemies.OrderBy(e => e.HP).FirstOrDefault()?.transform,
        Priority.Highest => enemies.OrderByDescending(e => e.HP).FirstOrDefault()?.transform,
        Priority.First => enemies.OrderByDescending(e => e.PathProgress).FirstOrDefault()?.transform,
        Priority.Last => enemies.OrderBy(e => e.PathProgress).FirstOrDefault()?.transform,
        _ => null,
    };
}

Ballistic leading

// 매 moving target 의 prediction
Vector3 PredictAimPoint(Vector3 targetPos, Vector3 targetVel, float projectileSpeed)
{
    Vector3 toTarget = targetPos - muzzle.position;
    float a = Vector3.Dot(targetVel, targetVel) - projectileSpeed * projectileSpeed;
    float b = 2f * Vector3.Dot(targetVel, toTarget);
    float c = Vector3.Dot(toTarget, toTarget);
    float disc = b * b - 4f * a * c;
    if (disc < 0f) return targetPos;
    float t = (-b - Mathf.Sqrt(disc)) / (2f * a);
    return targetPos + targetVel * t;
}

AoE projectile

public class ExplosiveProjectile : MonoBehaviour
{
    public float radius = 3f;
    public float damage = 50f;

    void OnCollisionEnter(Collision col)
    {
        foreach (var c in Physics.OverlapSphere(transform.position, radius, enemyLayer))
        {
            float dist = Vector3.Distance(transform.position, c.transform.position);
            float falloff = 1f - dist / radius;
            c.GetComponent<Enemy>()?.TakeDamage(damage * falloff);
        }
        Destroy(gameObject);
    }
}

Upgrade tree (ScriptableObject)

[CreateAssetMenu]
public class TurretUpgrade : ScriptableObject
{
    public string displayName;
    public int cost;
    public float damageMultiplier = 1f;
    public float rangeMultiplier = 1f;
    public float fireRateMultiplier = 1f;
    public TurretUpgrade[] nextChoices;
}

Godot 의 turret (GDScript)

extends Node3D

@export var range: float = 10.0
@export var fire_rate: float = 1.0
var cooldown := 0.0

func _physics_process(delta: float) -> void:
    var target := _find_target()
    if target:
        look_at(target.global_position, Vector3.UP)
        cooldown -= delta
        if cooldown <= 0:
            _fire()
            cooldown = 1.0 / fire_rate

func _find_target() -> Node3D:
    var space := get_world_3d().direct_space_state
    var query := PhysicsShapeQueryParameters3D.new()
    var shape := SphereShape3D.new()
    shape.radius = range
    query.shape = shape
    query.transform = global_transform
    query.collision_mask = 2 # enemy layer
    var hits := space.intersect_shape(query)
    return hits[0].collider if hits else null

매 결정 기준

상황 Approach
매 tower defense Closest / First priority + AoE
매 RTS base defense Highest HP / threat priority
매 boss arena Lowest HP focus fire
매 fast enemy Hitscan + slow status
매 swarm AoE + chain lightning
매 armored Pierce / true damage

기본값: 매 tower defense — Closest priority, ballistic projectile, 3-tier upgrade tree, $50-200 cost range.

🔗 Graph

🤖 LLM 활용

언제: 매 turret upgrade tree 의 brainstorm, 매 balance spreadsheet 의 generation, 매 priority logic 의 review. 언제 X: 매 production combat tuning — 매 playtest data + analytics 의 우선.

매 안티패턴

  • Single priority: 매 closest only — 매 player choice 의 부재.
  • No leading: 매 fast enemy 의 ballistic miss — 매 prediction 의 누락.
  • Linear upgrade: 매 X% damage 의 monotone — 매 build diversity 의 부재.
  • Cost imbalance: 매 best turret 의 always cheapest — 매 dominant strategy.
  • No counter: 매 single tower 의 모든 enemy 의 처치 — 매 strategic depth 의 부재.

🧪 검증 / 중복

  • Verified (Bloons TD 6 design retrospective, GDC talks, Unity / Godot docs).
  • 신뢰도 A-.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — turret components + Unity/Godot patterns