--- id: wiki-2026-0508-포탑-시스템-turret-systems title: 포탑 시스템(Turret Systems) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Turret Systems, Tower Defense, Auto-targeting] duplicate_of: none source_trust_level: A confidence_score: 0.85 verification_status: applied tags: [game-design, ai, gameplay, tower-defense] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: C# / GDScript framework: 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 ```csharp 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 ```csharp public enum Priority { Closest, Lowest, Highest, First, Last } Transform FindTarget(Priority p) { var enemies = Physics.OverlapSphere(transform.position, range, enemyLayer) .Select(c => c.GetComponent()).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 ```csharp // 매 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 ```csharp 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()?.TakeDamage(damage * falloff); } Destroy(gameObject); } } ``` ### Upgrade tree (ScriptableObject) ```csharp [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) ```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 - 부모: [[Game Mechanics]] · [[AI Behaviors]] - 변형: [[Tower Defense]] · [[Sentry Gun]] · [[Auto-aim]] - 응용: [[Bloons TD]] · [[Plants vs Zombies]] · [[Team Fortress 2]] - Adjacent: [[Wave System]] · [[Pathfinding]] · [[Projectile Physics]] ## 🤖 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 |