Commit dbf019c8 authored by Gavin An's avatar Gavin An

유닛 격자에 고정되도록 변경

parent c675f866
......@@ -26,7 +26,7 @@ L-Defense 게임 개요
- 유닛 개념
* 유닛 생성시 마다 골드가 소모되며, 모두 무작위 확률로 생성
* 생성된 유닛은 스테이지의 격자에 각각 배치 가능. 고정되어 있으며 자동 공격함.
* 생성된 유닛은 스테이지의 격자(Tile)에 각각 배치 가능. 고정되어 있으며 자동 공격함.
* 체력 / 공격력 / 공격속도 / 이동속도
* 유닛의 등급은 일반 / 고급 / 희귀 / 전설 / 신화 / 유일 등급
* 일반 ~ 희귀까지는 고유 스킬이 없고 일반 공격만 가능(근거리 / 원거리 구분 존재)
......
......@@ -3,12 +3,15 @@ extends CharacterBody3D
const UnitHelper = preload("res://src/entities/units/unit_helper.gd")
const MELEE_HIT_CONFIRM_PADDING: float = 0.05
const INVALID_PLACEMENT_CELL: Vector3i = Vector3i(2147483647, 2147483647, 2147483647)
## 플레이어 유닛 기본 클래스 (RTS 식 이동, 몬스터 자동 감지 및 공격 수행)
@export var unit_data: UnitData
var is_selected: bool = false
var is_tile_bound: bool = false
var occupied_tile_cell: Vector3i = INVALID_PLACEMENT_CELL
# 전투 관련 상태
var _target_monster: Node3D = null
......@@ -160,6 +163,12 @@ func _process_attack_logic(_delta: float) -> void:
_try_attack()
else:
_is_currently_attacking = false
if is_tile_bound:
# 타일에 배치된 유닛은 자리를 이탈하지 않고, 사거리 밖 타겟만 놓습니다.
_target_monster = null
velocity.x = 0.0
velocity.z = 0.0
return
# 사거리 밖인 경우 추격 이동
_nav_agent.target_position = _target_monster.global_position
_navigate_to_target(_delta)
......@@ -167,7 +176,7 @@ func _process_attack_logic(_delta: float) -> void:
## 2. 일반 대기 및 이동 상태의 로직
func _process_normal_logic(_delta: float) -> void:
# 홀드 상태이거나 이동 명령이 끝난 경우 정지
if _is_holding or _nav_agent.is_navigation_finished():
if is_tile_bound or _is_holding or _nav_agent.is_navigation_finished():
velocity.x = 0.0
velocity.z = 0.0
else:
......@@ -213,8 +222,8 @@ func _look_at_target(target_pos: Vector3) -> void:
func _find_nearest_target() -> void:
var monsters: Array[Node] = get_tree().get_nodes_in_group("monsters")
var nearest_monster: Node3D = null
# 홀드 상태 시에는 자신의 무기 사거리 내만 탐색, 일반 상태 시에는 자동 탐색 범위(15m) 적용
var min_distance: float = unit_data.attack_range if _is_holding else detection_range
# 타일 배치/홀드 상태 시에는 자신의 무기 사거리 내만 탐색하여 제자리 방어 규칙을 유지합니다.
var min_distance: float = unit_data.attack_range if is_tile_bound or _is_holding else detection_range
for monster: Node in monsters:
if is_instance_valid(monster) and monster is Node3D:
......@@ -322,8 +331,28 @@ func hold_position() -> void:
_nav_agent.target_position = global_position
velocity = Vector3.ZERO
## 맵 타일 하나를 점유하며 해당 타일 중앙에 유닛을 고정 배치합니다.
## 배치된 유닛은 이동/추격 명령으로 자리를 벗어나지 않고, 사거리 안 적만 공격합니다.
func place_on_tile(tile_center: Vector3, tile_cell: Vector3i) -> void:
is_tile_bound = true
occupied_tile_cell = tile_cell
_is_holding = true
_is_moving = false
_target_monster = null
_is_currently_attacking = false
_attack_lock_timer = 0.0
_melee_move_lock_timer = 0.0
_has_queued_move_after_attack = false
_auto_target_cooldown = 0.0
global_position = tile_center
_nav_agent.target_position = tile_center
velocity = Vector3.ZERO
## 외부에서 호출하는 수동 이동 명령
func move_to(target_pos: Vector3) -> void:
if is_tile_bound:
return
# 근접 유닛은 타격 확정 전 이동 명령을 잠시 보관했다가, 판정 직후 바로 이동합니다.
# 원거리 유닛이나 근접 후딜 구간은 즉시 공격을 끊고 이동해 조작 반응성을 유지합니다.
if _is_melee_attack_locked():
......@@ -340,6 +369,9 @@ func move_to(target_pos: Vector3) -> void:
## 실제 수동 이동 상태 전환을 한곳에서 처리합니다.
## - 근접 공격의 후딜 캔슬과 원거리 카이팅 모두 이 경로를 공유합니다.
func _apply_move_command(target_pos: Vector3) -> void:
if is_tile_bound:
return
_is_moving = true
_is_holding = false # 수동 조작 시 홀드 해제
_target_monster = null # 이동 명령 시 강제 공격 해제
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment