asset vibe

This commit is contained in:
Marek Lenczewski
2026-04-16 18:02:03 +02:00
parent f21e30eb55
commit 4b0f82c1de
28 changed files with 713 additions and 60 deletions

View File

@@ -3,17 +3,12 @@
[ext_resource type="Script" uid="uid://vy6hyqok0p8b" path="res://scenes/enemy/init.gd" id="1"]
[ext_resource type="Script" uid="uid://b07aajhufqvb3" path="res://scenes/enemy/detection.gd" id="2"]
[ext_resource type="Resource" uid="uid://cj1shmjwf0xeo" path="res://scenes/enemy/enemy_stats.tres" id="8"]
[ext_resource type="PackedScene" path="res://assets/models/characters/Skeleton_Minion.glb" id="9"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1"]
radius = 0.4
height = 1.5
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.8, 0.1, 0.1, 1)
[sub_resource type="SphereMesh" id="SphereMesh_1"]
material = SubResource("StandardMaterial3D_1")
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_2"]
radius = 0.4
height = 1.5
@@ -40,8 +35,10 @@ stats = ExtResource("8")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1011138038]
shape = SubResource("CapsuleShape3D_1")
[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1598094615]
mesh = SubResource("SphereMesh_1")
[node name="Mesh" type="Node3D" parent="." unique_id=1598094615]
[node name="Model" parent="Mesh" instance=ExtResource("9")]
transform = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, -0.75, 0)
[node name="HitArea" type="Area3D" parent="." unique_id=893463784]
collision_layer = 4
@@ -62,7 +59,7 @@ collision_layer = 0
shape = SubResource("SphereShape3D_1")
[node name="Healthbar" type="Sprite3D" parent="." unique_id=1008728031]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0)
billboard = 1
[node name="SubViewport" type="SubViewport" parent="Healthbar" unique_id=1219060718]

View File

@@ -1,25 +1,56 @@
extends CharacterBody3D
const SKELETON_WARRIOR: PackedScene = preload("res://assets/models/characters/Skeleton_Warrior.glb")
const SKELETON_MAGE: PackedScene = preload("res://assets/models/characters/Skeleton_Mage.glb")
@export var stats: EnemyStats
var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")
var spawn_scale: float = 1.0
var hover_t: float = 0.0
var mesh_base_y: float = 0.0
var anim_player: AnimationPlayer = null
var current_anim: String = ""
var attack_lock_until: float = 0.0
var is_dying: bool = false
func _ready() -> void:
add_to_group("enemies")
if is_in_group("boss"):
BossData.register(self, stats, spawn_scale)
BossData.set_stat(self, "spawn_position", global_position)
_swap_model(SKELETON_MAGE, 1.3)
else:
EnemyData.register(self, stats, spawn_scale)
EnemyData.set_stat(self, "spawn_position", global_position)
EventBus.entity_died.connect(_on_entity_died)
EventBus.attack_executed.connect(_on_attack_executed)
call_deferred("_check_variant")
call_deferred("_init_anim")
func _init_anim() -> void:
anim_player = get_node_or_null("Mesh/Model/AnimationPlayer")
_play_anim("Idle")
func _check_variant() -> void:
if is_in_group("boss"):
return
if is_in_group("red_enemies") or is_in_group("invasion"):
_swap_model(SKELETON_WARRIOR, 1.0)
anim_player = get_node_or_null("Mesh/Model/AnimationPlayer")
_play_anim("Idle")
func _swap_model(new_scene: PackedScene, scale_factor: float = 1.0) -> void:
var mesh: Node3D = get_node_or_null("Mesh")
if mesh:
mesh_base_y = mesh.position.y
_apply_appearance(mesh)
if not mesh:
return
var old: Node = mesh.get_node_or_null("Model")
if old:
old.queue_free()
var new_model: Node3D = new_scene.instantiate()
new_model.name = "Model"
new_model.scale = Vector3(scale_factor, scale_factor, scale_factor)
new_model.position = Vector3(0, -0.75, 0)
new_model.rotation.y = PI
mesh.add_child(new_model)
func _exit_tree() -> void:
if is_in_group("boss"):
@@ -28,29 +59,41 @@ func _exit_tree() -> void:
EnemyData.deregister(self)
func _on_entity_died(entity: Node) -> void:
if entity == self:
queue_free()
if entity != self:
return
is_dying = true
_play_anim("Death_A", false)
get_tree().create_timer(1.0).timeout.connect(queue_free)
func _process(delta: float) -> void:
hover_t += delta
var mesh: Node3D = get_node_or_null("Mesh")
if mesh:
mesh.position.y = mesh_base_y + sin(hover_t * 3.0) * 0.08
func _on_attack_executed(attacker: Node, _pos: Vector3, _dir: Vector3, _damage: float) -> void:
if attacker != self:
return
_play_anim("1H_Melee_Attack_Chop", false)
attack_lock_until = Time.get_ticks_msec() / 1000.0 + 0.5
func _apply_appearance(mesh: Node3D) -> void:
if mesh is MeshInstance3D:
var mat := StandardMaterial3D.new()
if is_in_group("boss"):
mat.albedo_color = Color(0.6, 0.15, 0.7, 1)
mat.emission_enabled = true
mat.emission = Color(0.8, 0.2, 0.9, 1)
mat.emission_energy_multiplier = 0.4
else:
mat.albedo_color = Color(0.7, 0.25, 0.25, 1)
mat.emission_enabled = true
mat.emission = Color(0.9, 0.3, 0.2, 1)
mat.emission_energy_multiplier = 0.25
(mesh as MeshInstance3D).material_override = mat
func _process(_delta: float) -> void:
if is_dying:
return
var now: float = Time.get_ticks_msec() / 1000.0
if now < attack_lock_until:
return
if velocity.length() > 0.1:
_play_anim("Running_A")
else:
_play_anim("Idle")
func _play_anim(anim_name: String, loop: bool = true) -> void:
if not anim_player:
return
if current_anim == anim_name:
return
if not anim_player.has_animation(anim_name):
return
var anim: Animation = anim_player.get_animation(anim_name)
if anim:
anim.loop_mode = Animation.LOOP_LINEAR if loop else Animation.LOOP_NONE
anim_player.play(anim_name)
current_anim = anim_name
func _physics_process(delta: float) -> void:
if not is_on_floor():

View File

@@ -2,6 +2,10 @@ extends CharacterBody3D
@export var stats: PlayerStats
var anim_player: AnimationPlayer = null
var current_anim: String = ""
var attack_lock_until: float = 0.0
func _ready() -> void:
add_to_group("player")
PlayerData.init_from_resource(stats)
@@ -10,3 +14,46 @@ func _ready() -> void:
PlayerData.returning_from_dungeon = false
elif PlayerData.dungeon_cleared:
PlayerData.clear_cache()
anim_player = get_node_or_null("Mesh/Model/AnimationPlayer")
_play_anim("Idle")
EventBus.attack_executed.connect(_on_attack_executed)
EventBus.entity_died.connect(_on_entity_died)
EventBus.player_respawned.connect(_on_player_respawned)
func _process(_delta: float) -> void:
if not PlayerData.alive:
return
var now: float = Time.get_ticks_msec() / 1000.0
if now < attack_lock_until:
return
if velocity.length() > 0.1:
_play_anim("Running_A")
else:
_play_anim("Idle")
func _play_anim(anim_name: String, loop: bool = true) -> void:
if not anim_player:
return
if current_anim == anim_name:
return
if not anim_player.has_animation(anim_name):
return
var anim: Animation = anim_player.get_animation(anim_name)
if anim:
anim.loop_mode = Animation.LOOP_LINEAR if loop else Animation.LOOP_NONE
anim_player.play(anim_name)
current_anim = anim_name
func _on_attack_executed(attacker: Node, _pos: Vector3, _dir: Vector3, _damage: float) -> void:
if attacker != self:
return
_play_anim("1H_Melee_Attack_Chop", false)
attack_lock_until = Time.get_ticks_msec() / 1000.0 + 0.5
func _on_entity_died(entity: Node) -> void:
if entity != PlayerData:
return
_play_anim("Death_A", false)
func _on_player_respawned(_player: Node) -> void:
_play_anim("Idle")

View File

@@ -25,6 +25,11 @@ func _physics_process(delta: float) -> void:
if direction:
player.velocity.x = direction.x * PlayerData.speed
player.velocity.z = direction.z * PlayerData.speed
var world_yaw: float = atan2(-direction.x, -direction.z)
var local_yaw: float = world_yaw - player.rotation.y
var mesh: Node3D = player.get_node_or_null("Mesh") as Node3D
if mesh:
mesh.rotation.y = lerp_angle(mesh.rotation.y, local_yaw, 10.0 * delta)
else:
player.velocity.x = move_toward(player.velocity.x, 0, PlayerData.speed)
player.velocity.z = move_toward(player.velocity.z, 0, PlayerData.speed)

View File

@@ -7,15 +7,12 @@
[ext_resource type="Script" uid="uid://b05nkuryipwny" path="res://scenes/player/targeting.gd" id="8"]
[ext_resource type="Script" uid="uid://dhomrampxola4" path="res://scenes/player/role/role.gd" id="10"]
[ext_resource type="Resource" uid="uid://btd0g0oiulssq" path="res://scenes/player/player_stats.tres" id="14"]
[ext_resource type="PackedScene" path="res://assets/models/characters/Knight.glb" id="15"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1"]
radius = 0.3
height = 1.8
[sub_resource type="CapsuleMesh" id="CapsuleMesh_1"]
radius = 0.3
height = 1.8
[node name="Player" type="CharacterBody3D" unique_id=197716516]
script = ExtResource("1")
stats = ExtResource("14")
@@ -23,8 +20,10 @@ stats = ExtResource("14")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=311205642]
shape = SubResource("CapsuleShape3D_1")
[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1514179122]
mesh = SubResource("CapsuleMesh_1")
[node name="Mesh" type="Node3D" parent="." unique_id=1514179122]
[node name="Model" parent="Mesh" instance=ExtResource("15")]
transform = Transform3D(-1, 0, 0, 0, 1, 0, 0, 0, -1, 0, -0.9, 0)
[node name="CameraPivot" type="Node3D" parent="." unique_id=1881685457]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)

View File

@@ -2,24 +2,11 @@
[ext_resource type="Script" path="res://scenes/tavern/init.gd" id="1"]
[ext_resource type="Resource" path="res://scenes/tavern/tavern_stats.tres" id="2"]
[ext_resource type="PackedScene" path="res://assets/models/buildings/building_home_A_blue.gltf" id="3"]
[sub_resource type="BoxShape3D" id="BoxShape3D_tavern"]
size = Vector3(5, 3, 5)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_tavern"]
albedo_color = Color(0.45, 0.3, 0.15, 1)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_roof"]
albedo_color = Color(0.3, 0.15, 0.08, 1)
[sub_resource type="BoxMesh" id="BoxMesh_tavern"]
size = Vector3(5, 3, 5)
material = SubResource("StandardMaterial3D_tavern")
[sub_resource type="PrismMesh" id="PrismMesh_roof"]
size = Vector3(5.4, 2, 5.4)
material = SubResource("StandardMaterial3D_roof")
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_health_bg"]
bg_color = Color(0.3, 0.1, 0.1, 1)
@@ -33,12 +20,10 @@ stats = ExtResource("2")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("BoxShape3D_tavern")
[node name="Mesh" type="MeshInstance3D" parent="."]
mesh = SubResource("BoxMesh_tavern")
[node name="Mesh" type="Node3D" parent="."]
[node name="Roof" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 0)
mesh = SubResource("PrismMesh_roof")
[node name="Model" parent="Mesh" instance=ExtResource("3")]
transform = Transform3D(2.5, 0, 0, 0, 2.5, 0, 0, 0, 2.5, 0, -1.5, 0)
[node name="Healthbar" type="Sprite3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4, 0)