Commit 9af0b9d6 authored by Gavin An's avatar Gavin An

원거리 유닛 발사체 구현

parent fdaa3517
......@@ -137,14 +137,26 @@ func _try_attack() -> void:
if _attack_timer > 0.0 or not _target_monster:
return
# 공격 데미지 적용
if unit_data.is_ranged:
# 원거리 유닛: 유도 발사체(Projectile) 생성하여 발사
var projectile_script = preload("res://src/entities/units/projectile.gd")
var proj: Node3D = projectile_script.new() as Node3D
proj.set("damage", unit_data.damage)
proj.set("target", _target_monster)
proj.set("color", unit_data.unit_color)
# 유닛 중심보다 높은 곳(어깨 높이)에서 발사 처리
proj.global_position = global_position + Vector3(0.0, 0.7, 0.0)
get_tree().current_scene.add_child(proj)
else:
# 근접 유닛: 즉발 공격 및 피해 적용
if _target_monster.has_method("take_damage"):
_target_monster.call("take_damage", unit_data.damage)
# 쿨타임 타이머 작동
_attack_timer = unit_data.cooldown
# 공격 이펙트 처리 (원거리용 레이 트레이스 혹은 무작위 시각 반응)
# 공격 비주얼 연출
_show_attack_visual()
## 공격 관련 비주얼 이펙트 연출
......
[gd_scene load_steps=7 format=3]
[gd_scene format=3 uid="uid://b2tecpr0sbqct"]
[ext_resource type="Script" path="res://src/entities/units/base_unit.gd" id="1_base_unit"]
[ext_resource type="Script" uid="uid://daq4ko8ryry3w" path="res://src/entities/units/base_unit.gd" id="1_base_unit"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_body"]
radius = 0.4
......@@ -21,19 +21,19 @@ material = SubResource("StandardMaterial3D_ring")
inner_radius = 0.65
outer_radius = 0.7
[node name="BaseUnit" type="CharacterBody3D"]
[node name="BaseUnit" type="CharacterBody3D" unique_id=346158962]
script = ExtResource("1_base_unit")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1651817390]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.6, 0)
shape = SubResource("CapsuleShape3D_body")
[node name="VisualMesh" type="MeshInstance3D" parent="."]
[node name="VisualMesh" type="MeshInstance3D" parent="." unique_id=1141960859]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.6, 0)
mesh = SubResource("CapsuleMesh_unit")
[node name="SelectionRing" type="MeshInstance3D" parent="."]
[node name="SelectionRing" type="MeshInstance3D" parent="." unique_id=489098498]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.02, 0)
mesh = SubResource("TorusMesh_selection")
[node name="NavigationAgent3D" type="NavigationAgent3D" parent="."]
[node name="NavigationAgent3D" type="NavigationAgent3D" parent="." unique_id=1562195301]
class_name Projectile
extends Node3D
## 원거리 유닛이 발사하는 3D 발사체 개체
## 지정된 대상을 향해 날아가며, 충돌 시 데미지를 가하고 소멸합니다.
var speed: float = 24.0
var damage: float = 0.0
var target: Node3D = null
var color: Color = Color(1.0, 0.9, 0.2, 1.0) # 기본 노란색 발사체
func _ready() -> void:
# 동적 비주얼 메쉬 생성 (구체 형태의 길쭉한 빛 구슬 표현)
var mesh_instance: MeshInstance3D = MeshInstance3D.new()
var sphere_mesh: SphereMesh = SphereMesh.new()
sphere_mesh.radius = 0.15
sphere_mesh.height = 0.4
var mat: StandardMaterial3D = StandardMaterial3D.new()
mat.albedo_color = color
mat.emission_enabled = true
mat.emission = color
mat.emission_energy_multiplier = 3.0
sphere_mesh.material = mat
mesh_instance.mesh = sphere_mesh
add_child(mesh_instance)
func _physics_process(delta: float) -> void:
if GameManager.is_game_over:
queue_free()
return
# 타겟이 도중에 사라지거나 사망 시 소멸
if not is_instance_valid(target) or target.get("is_dead") == true:
queue_free()
return
# 타겟 높이 오프셋 보정 (몬스터 중심부 y ~= 0.5를 향하도록)
var target_center: Vector3 = target.global_position
if target.has_node("VisualMesh"):
var vm: Node3D = target.get_node("VisualMesh") as Node3D
target_center.y = vm.global_position.y
# 방향 계산 및 이동
var dir: Vector3 = (target_center - global_position).normalized()
global_position += dir * speed * delta
# 비행 방향 바라보기
if global_position.distance_to(target_center) > 0.1:
look_at(target_center, Vector3.UP)
# 타겟 근접 도달 판정 (0.6m 이내)
if global_position.distance_to(target_center) < 0.6:
_impact()
## 적에게 충돌하여 데미지 가함
func _impact() -> void:
if is_instance_valid(target) and target.has_method("take_damage"):
target.call("take_damage", damage)
# 충돌 이펙트 (필요 시 연출)
queue_free()
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