Initial commit.

This commit is contained in:
2026-09-19 10:06:28 -04:00
commit df09395018
653 changed files with 102225 additions and 0 deletions
@@ -0,0 +1,133 @@
@tool
class_name ProtoFirstPersonCharacter
extends CharacterBody3D
@export_tool_button("Generate Nodes") var initialize_nodes := func() -> void:
if not Engine.is_editor_hint(): return
for c in get_children(): c.free()
camera_3d = Camera3D.new()
camera_3d.position = Vector3(0,0.726,-0.12)
Proto.add_node(self, camera_3d)
if interactable_raycast:
raycast = RayCast3D.new()
raycast.target_position = Vector3(0,0,-raycast_length)
raycast.collide_with_areas = true
raycast.collide_with_bodies = false
Proto.add_node(camera_3d, raycast)
var collision_shape_3d := CollisionShape3D.new()
var shape := CapsuleShape3D.new()
shape.radius = 0.4
shape.height = 1.8
collision_shape_3d.shape = shape
Proto.add_node(self, collision_shape_3d)
position.y = 0.9
Proto.proto_print("First person character controller nodes configured")
@export_category("Config")
@export var load_on_ready := true
@export var capture_mouse := true
## Interactable Raycasts requiire the ProtoSignalHub component
@export var interactable_raycast := true:
set(value):
interactable_raycast = value
initialize_nodes.call()
get:
return interactable_raycast
@export var raycast_length := 2.0:
set(value):
raycast_length = value
initialize_nodes.call()
get:
return raycast_length
@export_category("Character Settings")
@export var speed := 5.0
@export var jump_velocity := 4.5
@export var sens_x := -0.07
@export var sens_y := -0.07
@export var joypad_sens_x := -0.07
@export var joypad_sens_y := -0.07
@export_category("Node References")
@export var camera_3d: Camera3D
@export var raycast: RayCast3D
var proto_game: Node
var wasd_controls := false
var joystick_look_controls := false
var jump_controls := false
var last_is_colliding := false
var interact_controls := false
func _ready() -> void:
if Engine.is_editor_hint():
if load_on_ready:
if get_child_count() == 0: initialize_nodes.call()
set_process(false)
set_process_input(false)
set_physics_process(false)
else:
wasd_controls = InputMap.has_action(&"left") and InputMap.has_action(&"right") and InputMap.has_action(&"forward") and InputMap.has_action(&"back")
joystick_look_controls = InputMap.has_action(&"look_left") and InputMap.has_action(&"look_right") \
and InputMap.has_action(&"look_up") and InputMap.has_action(&"look_down")
jump_controls = InputMap.has_action(&"jump")
interact_controls = InputMap.has_action(&"interact")
if capture_mouse: Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
proto_game = Proto.get_autoload(self, "ProtoGame")
func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
pivot_camera(event.relative.x, event.relative.y, sens_x, sens_y)
func _process(_delta: float) -> void:
if proto_game and interactable_raycast and interact_controls:
Proto.process_interact_raycast(self, proto_game.signal_hub, raycast)
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity += get_gravity() * delta
var jump_action := Input.is_action_just_pressed(&"ui_accept") or (jump_controls and Input.is_action_just_pressed(&"jump"))
if jump_action and is_on_floor():
velocity.y = jump_velocity
var input_dir := Vector2.ZERO
if camera_3d.current:
if wasd_controls:
input_dir = Input.get_vector(&"left", &"right", &"forward", &"back")
else:
input_dir = Input.get_vector(&"ui_left", &"ui_right", &"ui_up", &"ui_down")
if joystick_look_controls:
var look_right := Input.get_axis(&"look_left", &"look_right")
var look_up := Input.get_axis(&"look_down", &"look_up")
# fyi the last factor is a fudge factor to make the joypad feel similar to mouse at the same sens
pivot_camera(look_right, look_up, joypad_sens_x, joypad_sens_y, 2.0)
var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y))
if direction:
velocity.x = direction.x * speed
velocity.z = direction.z * speed
else:
velocity.x = move_toward(velocity.x, 0, speed)
velocity.z = move_toward(velocity.z, 0, speed)
move_and_slide()
func pivot_camera(relative_x: float, relative_y: float, _sens_x: float, _sens_y: float, factor := 100.0) -> void:
rotation.y += _sens_x * relative_x / factor
camera_3d.rotation.x += _sens_y * relative_y / factor
@@ -0,0 +1 @@
uid://b4t5of6xdp0eu
@@ -0,0 +1,162 @@
@tool
class_name ProtoThirdPersonCharacter
extends CharacterBody3D
@export_tool_button("Generate Nodes") var initialize_nodes := func() -> void:
if not Engine.is_editor_hint(): return
for c in get_children(): c.free()
pivot = Node3D.new()
pivot.position.y = 1.0
Proto.add_node(self, pivot)
spring_arm = SpringArm3D.new()
spring_arm.position.x = 0.6
spring_arm.spring_length = 2.0
spring_arm.rotation_degrees.x = -20.0
Proto.add_node(pivot, spring_arm)
camera_3d = Camera3D.new()
Proto.add_node(spring_arm, camera_3d)
if interactable_raycast:
raycast = RayCast3D.new()
raycast.target_position = Vector3(0,0,-raycast_length)
raycast.collide_with_areas = true
raycast.collide_with_bodies = false
Proto.add_node(camera_3d, raycast)
var collision_shape_3d := CollisionShape3D.new()
var shape := CapsuleShape3D.new()
shape.radius = 0.4
shape.height = 1.8
collision_shape_3d.shape = shape
Proto.add_node(self, collision_shape_3d)
mesh_instance = MeshInstance3D.new()
var capsule := CapsuleMesh.new()
capsule.radius = 0.4
capsule.height = 1.8
mesh_instance.mesh = capsule
var mat := StandardMaterial3D.new()
mat.albedo_color = Color.BLUE_VIOLET
mesh_instance.set_surface_override_material(0, mat)
Proto.add_node(self, mesh_instance)
var mesh_instance_2 := mesh_instance.duplicate()
mesh_instance_2.scale = Vector3.ONE * 0.3
mesh_instance_2.rotation_degrees.z = 90.0
mesh_instance_2.position = Vector3(0,0.4,-0.4)
var mat_2 := StandardMaterial3D.new()
mat_2.albedo_color = Color.GREEN
mesh_instance_2.set_surface_override_material(0, mat_2)
Proto.add_node(mesh_instance, mesh_instance_2, "MeshInstance3D2")
position.y = 0.9
Proto.proto_print("Third person character controller nodes configured")
@export_category("Config")
@export var capture_mouse := true
@export var load_on_ready := true
@export var interactable_raycast := true:
set(value):
interactable_raycast = value
initialize_nodes.call()
get:
return interactable_raycast
@export var raycast_length := 4.0:
set(value):
raycast_length = value
initialize_nodes.call()
get:
return raycast_length
@export_category("Character Settings")
@export var speed := 5.0
@export var jump_velocity := 4.5
@export var sens_x := -0.07
@export var sens_y := -0.07
@export var joypad_sens_x := -0.07
@export var joypad_sens_y := -0.07
@export_category("Node References")
@export var camera_3d: Camera3D
@export var spring_arm: SpringArm3D
@export var mesh_instance: MeshInstance3D
@export var raycast: RayCast3D
@export var pivot: Node3D
var proto_game: Node
var wasd_controls := false
var joystick_look_controls := false
var jump_controls := false
var interact_controls := false
func _ready() -> void:
if Engine.is_editor_hint():
if load_on_ready:
if get_child_count() == 0: initialize_nodes.call()
set_process_input(false)
set_physics_process(false)
else:
wasd_controls = InputMap.has_action(&"left") and InputMap.has_action(&"right") and InputMap.has_action(&"forward") and InputMap.has_action(&"back")
joystick_look_controls = InputMap.has_action(&"look_left") and InputMap.has_action(&"look_right") \
and InputMap.has_action(&"look_up") and InputMap.has_action(&"look_down")
jump_controls = InputMap.has_action(&"jump")
interact_controls = InputMap.has_action(&"interact")
if capture_mouse: Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
proto_game = Proto.get_autoload(self, "ProtoGame")
func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
pivot_camera(event.relative.x, event.relative.y, sens_x, sens_y)
func _process(_delta: float) -> void:
if proto_game and interactable_raycast and interact_controls:
Proto.process_interact_raycast(self, proto_game.signal_hub, raycast)
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity += get_gravity() * delta
var jump_action := Input.is_action_just_pressed(&"ui_accept") or (jump_controls and Input.is_action_just_pressed(&"jump"))
if jump_action and is_on_floor():
velocity.y = jump_velocity
var input_dir := Vector2.ZERO
if camera_3d.current:
if wasd_controls:
input_dir = Input.get_vector(&"left", &"right", &"forward", &"back")
else:
input_dir = Input.get_vector(&"ui_left", &"ui_right", &"ui_up", &"ui_down")
if joystick_look_controls:
var look_right := Input.get_axis(&"look_left", &"look_right")
var look_up := Input.get_axis(&"look_down", &"look_up")
# fyi the last factor is a fudge factor to make the joypad feel similar to mouse at the same sens
pivot_camera(look_right, look_up, joypad_sens_x, joypad_sens_y, 2.0)
var b := Basis(Vector3.UP, camera_3d.global_rotation.y)
var direction := (b * Vector3(input_dir.x, 0, input_dir.y))
if direction:
mesh_instance.global_rotation.y = lerp_angle(mesh_instance.global_rotation.y, atan2(direction.x, direction.z) + PI, 0.15)
velocity.x = direction.x * speed
velocity.z = direction.z * speed
else:
velocity.x = move_toward(velocity.x, 0, speed)
velocity.z = move_toward(velocity.z, 0, speed)
move_and_slide()
func pivot_camera(relative_x: float, relative_y: float, _sens_x: float, _sens_y: float, factor := 100.0) -> void:
spring_arm.rotation.x += _sens_y * relative_y / factor
pivot.rotation.y += _sens_x * relative_x / factor
@@ -0,0 +1 @@
uid://ug2t64m1nmhx