extends CharacterBody3D var id = -1 var world_entity var chunks_array: Array @onready var ray = $RayCast3D @onready var HighlightShader = preload("res://assets/shaders/highlight.tres") #func _init(entity): func _process(delta): var height = ray.get_collision_point().y if position.y != height: var tween = get_tree().create_tween() tween.tween_property(self, "position:y", height, 0.1) func set_entity(entity): var model = load("res://assets/entities/" + entity.model + "/" + entity.model + ".glb").instantiate() model.set_name("model") if $Pivot.get_children(): $Pivot.remove_child($Pivot.get_children()[0]) model.hide() $Pivot.add_child(model) for mesh in get_meshes($Pivot): mesh.mesh = mesh.mesh.duplicate() if model.find_child("AnimationPlayer"): $AnimationTree.anim_player = "../Pivot/model/AnimationPlayer" $AnimationTree.active = true model.show() func get_belonging_chunk(): return (world_entity.position / Global.world.chunk_size) func set_belonging_chunk(): pass func connect_to_world(id, chunks_array): world_entity = Global.world.entities[id] world_entity.moving.connect(_on_entity_moving) world_entity.changed_state.connect(_on_changed_state) self.chunks_array = chunks_array func _on_entity_moving(new_position, speed): var position2d = Vector2i(round(position.x), round(position.z)) var distance = Global.world.vec_distance(world_entity.position, new_position) var new_pawn_position = position2d + distance var tween = Engine.get_main_loop().create_tween() tween.set_parallel(true) tween.tween_property(self, "position:x", new_pawn_position.x, 1.0/speed) tween.tween_property(self, "position:z", new_pawn_position.y, 1.0/speed) tween.tween_callback(Callable(self, "update_chunk")).set_delay(1.0/speed) var vector = Vector2(new_pawn_position.y, new_pawn_position.x) - Vector2(self.position.z, self.position.x) var angle = vector.angle() var new_rotation = rotation.y + wrapf(angle - rotation.y, -PI, PI) tween.tween_property(self, "rotation:y", new_rotation, 0.1) func update_chunk(): if get_parent().location != get_belonging_chunk() and is_inside_tree(): var saved_global_position = global_position get_parent().remove_child(self) chunks_array[get_belonging_chunk().x][get_belonging_chunk().y].add_child(self) global_position = saved_global_position func highlight(): for mesh in get_meshes($Pivot): var material = mesh.get_active_material(0).duplicate() material.set_next_pass(HighlightShader) mesh.mesh.surface_set_material(0, material) func unhighlight(): for mesh in get_meshes($Pivot): var material = mesh.get_active_material(0).duplicate() material.set_next_pass(null) mesh.mesh.surface_set_material(0, material) func get_meshes(parent_node): var meshes = [] if parent_node.get_child_count(): for child_node in parent_node.get_children(): if child_node is MeshInstance3D: meshes.append(child_node) else: meshes.append_array(get_meshes(child_node)) return meshes func _on_changed_state(state): if state == 0: $AnimationTree["parameters/playback"].travel("Idle") if state == 1: $AnimationTree["parameters/playback"].travel("Run")