104 lines
2.9 KiB
GDScript
104 lines
2.9 KiB
GDScript
|
extends CharacterBody3D
|
||
|
|
||
|
@export var SPEED: float = 5.0
|
||
|
@export var JUMP_VELOCITY: float = 4.5
|
||
|
@export var enable_gravity = true
|
||
|
|
||
|
@onready var _camera: Camera3D
|
||
|
|
||
|
@onready var _player_visual: Node3D = %PlayerVisual
|
||
|
|
||
|
# Get the gravity from the project settings to be synced with RigidBody nodes.
|
||
|
var gravity: float = 9.8
|
||
|
|
||
|
var movement_enabled: bool = true
|
||
|
|
||
|
var _physics_body_trans_last: Transform3D
|
||
|
var _physics_body_trans_current: Transform3D
|
||
|
|
||
|
const KEY_STRINGNAME: StringName = "Key"
|
||
|
const ACTION_STRINGNAME: StringName = "Action"
|
||
|
|
||
|
const INPUT_MOVE_UP_STRINGNAME: StringName = "move_up"
|
||
|
const INPUT_MOVE_DOWM_STRINGNAME: StringName = "move_down"
|
||
|
const INPUT_MOVE_LEFT_STRINGNAME: StringName = "move_left"
|
||
|
const INPUT_MOVE_RIGHT_STRINGNAME: StringName = "move_right"
|
||
|
|
||
|
var InputMovementDic: Dictionary = {
|
||
|
INPUT_MOVE_UP_STRINGNAME: {
|
||
|
KEY_STRINGNAME: KEY_W,
|
||
|
ACTION_STRINGNAME: INPUT_MOVE_UP_STRINGNAME
|
||
|
},
|
||
|
INPUT_MOVE_DOWM_STRINGNAME: {
|
||
|
KEY_STRINGNAME: KEY_S,
|
||
|
ACTION_STRINGNAME: INPUT_MOVE_DOWM_STRINGNAME
|
||
|
},
|
||
|
INPUT_MOVE_LEFT_STRINGNAME: {
|
||
|
KEY_STRINGNAME: KEY_A,
|
||
|
ACTION_STRINGNAME: INPUT_MOVE_LEFT_STRINGNAME
|
||
|
},
|
||
|
INPUT_MOVE_RIGHT_STRINGNAME: {
|
||
|
KEY_STRINGNAME: KEY_D,
|
||
|
ACTION_STRINGNAME: INPUT_MOVE_RIGHT_STRINGNAME
|
||
|
},
|
||
|
}
|
||
|
|
||
|
|
||
|
func _ready() -> void:
|
||
|
for input in InputMovementDic:
|
||
|
var key_val = InputMovementDic[input].get(KEY_STRINGNAME)
|
||
|
var action_val = InputMovementDic[input].get(ACTION_STRINGNAME)
|
||
|
|
||
|
_camera = owner.get_node("%MainCamera3D")
|
||
|
|
||
|
var movement_input = InputEventKey.new()
|
||
|
movement_input.physical_keycode = key_val
|
||
|
InputMap.add_action(action_val)
|
||
|
InputMap.action_add_event(action_val, movement_input)
|
||
|
|
||
|
_player_visual.top_level = true
|
||
|
|
||
|
|
||
|
func _physics_process(delta: float) -> void:
|
||
|
_physics_body_trans_last = _physics_body_trans_current
|
||
|
_physics_body_trans_current = global_transform
|
||
|
|
||
|
# Add the gravity.
|
||
|
if enable_gravity and not is_on_floor():
|
||
|
velocity.y -= gravity * delta
|
||
|
|
||
|
if not movement_enabled: return
|
||
|
|
||
|
# Get the input direction and handle the movement/deceleration.
|
||
|
# As good practice, you should replace UI actions with custom gameplay actions.
|
||
|
var input_dir: Vector2 = Input.get_vector(
|
||
|
INPUT_MOVE_LEFT_STRINGNAME,
|
||
|
INPUT_MOVE_RIGHT_STRINGNAME,
|
||
|
INPUT_MOVE_UP_STRINGNAME,
|
||
|
INPUT_MOVE_DOWM_STRINGNAME
|
||
|
)
|
||
|
|
||
|
var cam_dir: Vector3 = -_camera.global_transform.basis.z
|
||
|
|
||
|
var direction: Vector3 = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
|
||
|
if direction:
|
||
|
var move_dir: Vector3 = Vector3.ZERO
|
||
|
move_dir.x = direction.x
|
||
|
move_dir.z = direction.z
|
||
|
|
||
|
move_dir = move_dir.rotated(Vector3.UP, _camera.rotation.y).normalized()
|
||
|
velocity.x = move_dir.x * SPEED
|
||
|
velocity.z = move_dir.z * SPEED
|
||
|
else:
|
||
|
velocity.x = move_toward(velocity.x, 0, SPEED)
|
||
|
velocity.z = move_toward(velocity.z, 0, SPEED)
|
||
|
|
||
|
move_and_slide()
|
||
|
|
||
|
|
||
|
func _process(_delta: float) -> void:
|
||
|
_player_visual.global_transform = _physics_body_trans_last.interpolate_with(
|
||
|
_physics_body_trans_current,
|
||
|
Engine.get_physics_interpolation_fraction()
|
||
|
)
|