feat: add npc simulation, instancing and visual scene
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
extends Node3D
|
||||
|
||||
@export var target: Node3D
|
||||
@export var follow_offset := Vector3(0, 10, 8)
|
||||
@export var follow_speed := 12.0
|
||||
@export var mouse_sensitivity := 0.002
|
||||
|
||||
@export var deadzone_right := 3.0
|
||||
@export var deadzone_forward := 3.0
|
||||
|
||||
var yaw := 0.0
|
||||
var focus_position := Vector3.ZERO
|
||||
|
||||
func _ready() -> void:
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||
|
||||
if target:
|
||||
focus_position = target.global_position
|
||||
global_position = focus_position + follow_offset
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseMotion:
|
||||
yaw -= event.relative.x * mouse_sensitivity
|
||||
|
||||
if event.is_action_pressed("ui_cancel"):
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if target == null:
|
||||
return
|
||||
|
||||
rotation = Vector3(deg_to_rad(-55), yaw, 0)
|
||||
|
||||
var target_pos := target.global_position
|
||||
var diff := target_pos - focus_position
|
||||
|
||||
# Camera-relative horizontal axes
|
||||
var cam_right := Vector3.RIGHT.rotated(Vector3.UP, yaw).normalized()
|
||||
var cam_forward := Vector3.FORWARD.rotated(Vector3.UP, yaw).normalized()
|
||||
|
||||
var diff_right := diff.dot(cam_right)
|
||||
var diff_forward := diff.dot(cam_forward)
|
||||
|
||||
if abs(diff_right) > deadzone_right:
|
||||
focus_position += cam_right * (diff_right - sign(diff_right) * deadzone_right)
|
||||
|
||||
if abs(diff_forward) > deadzone_forward:
|
||||
focus_position += cam_forward * (diff_forward - sign(diff_forward) * deadzone_forward)
|
||||
|
||||
var rotated_offset := follow_offset.rotated(Vector3.UP, yaw)
|
||||
var desired_position := focus_position + rotated_offset
|
||||
|
||||
global_position = global_position.lerp(
|
||||
desired_position,
|
||||
1.0 - exp(-follow_speed * delta)
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
uid://ii8ai801jur2
|
||||
@@ -0,0 +1,11 @@
|
||||
extends CharacterBody3D
|
||||
|
||||
var sim_id: int = -1
|
||||
var npc_name: String = ""
|
||||
var profession: String = ""
|
||||
|
||||
func setup_from_sim(npc: SimNPC) -> void:
|
||||
sim_id = npc.id
|
||||
npc_name = npc.npc_name
|
||||
profession = npc.profession
|
||||
name = "NPC_%s_%s" % [sim_id, npc_name]
|
||||
@@ -0,0 +1 @@
|
||||
uid://bha8uf40p3sa0
|
||||
@@ -0,0 +1,28 @@
|
||||
[gd_scene load_steps=6 format=3 uid="uid://dhxxyprqflotq"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bha8uf40p3sa0" path="res://player/npc/NpcVisual.gd" id="1_ixfoq"]
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_d844k"]
|
||||
|
||||
[sub_resource type="CapsuleMesh" id="CapsuleMesh_d844k"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_d844k"]
|
||||
albedo_color = Color(1, 0.22352941, 1, 1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_d844k"]
|
||||
material = SubResource("StandardMaterial3D_d844k")
|
||||
|
||||
[node name="NpcVisual" type="CharacterBody3D"]
|
||||
script = ExtResource("1_ixfoq")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.85, 0)
|
||||
shape = SubResource("CapsuleShape3D_d844k")
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.85, 0)
|
||||
mesh = SubResource("CapsuleMesh_d844k")
|
||||
|
||||
[node name="FaceMarker" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(0.15, 0, 0, 0, 0.15, 0, 0, 0, 0.35, 0, 1.2, -0.5)
|
||||
mesh = SubResource("BoxMesh_d844k")
|
||||
@@ -0,0 +1,37 @@
|
||||
extends CharacterBody3D
|
||||
|
||||
@export var move_speed := 7.0
|
||||
@export var acceleration := 18.0
|
||||
@export var rotation_speed := 12.0
|
||||
@export var camera_rig: Node3D
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
var input := Input.get_vector(
|
||||
"move_left",
|
||||
"move_right",
|
||||
"move_forward",
|
||||
"move_backward"
|
||||
)
|
||||
|
||||
var forward := -camera_rig.global_transform.basis.z
|
||||
var right := camera_rig.global_transform.basis.x
|
||||
|
||||
forward.y = 0
|
||||
right.y = 0
|
||||
|
||||
forward = forward.normalized()
|
||||
right = right.normalized()
|
||||
|
||||
var direction := (right * input.x + forward * -input.y).normalized()
|
||||
|
||||
var target_velocity := direction * move_speed
|
||||
|
||||
velocity.x = move_toward(velocity.x, target_velocity.x, acceleration * delta)
|
||||
velocity.z = move_toward(velocity.z, target_velocity.z, acceleration * delta)
|
||||
velocity.y = 0.0
|
||||
|
||||
move_and_slide()
|
||||
|
||||
if direction.length() > 0.01:
|
||||
var target_angle := atan2(direction.x, direction.z)
|
||||
rotation.y = lerp_angle(rotation.y, target_angle, rotation_speed * delta)
|
||||
@@ -0,0 +1 @@
|
||||
uid://4mg67crlim53
|
||||
Reference in New Issue
Block a user