generated from krampus/template-godot4
	Basic character movement controls
This commit is contained in:
		
							parent
							
								
									589922d6b8
								
							
						
					
					
						commit
						7e998e76dc
					
				| @ -59,8 +59,57 @@ config/input/mouse_sensitivity_y=0.3 | |||||||
| config/input/camera_acceleration=40.0 | config/input/camera_acceleration=40.0 | ||||||
| config/input/invert_pitch=false | config/input/invert_pitch=false | ||||||
| 
 | 
 | ||||||
|  | [input] | ||||||
|  | 
 | ||||||
|  | move_forward={ | ||||||
|  | "deadzone": 0.2, | ||||||
|  | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) | ||||||
|  | ] | ||||||
|  | } | ||||||
|  | move_left={ | ||||||
|  | "deadzone": 0.2, | ||||||
|  | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) | ||||||
|  | ] | ||||||
|  | } | ||||||
|  | move_back={ | ||||||
|  | "deadzone": 0.2, | ||||||
|  | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) | ||||||
|  | ] | ||||||
|  | } | ||||||
|  | move_right={ | ||||||
|  | "deadzone": 0.2, | ||||||
|  | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) | ||||||
|  | ] | ||||||
|  | } | ||||||
|  | jump={ | ||||||
|  | "deadzone": 0.2, | ||||||
|  | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) | ||||||
|  | ] | ||||||
|  | } | ||||||
|  | sprint={ | ||||||
|  | "deadzone": 0.2, | ||||||
|  | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) | ||||||
|  | ] | ||||||
|  | } | ||||||
|  | interact={ | ||||||
|  | "deadzone": 0.2, | ||||||
|  | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null) | ||||||
|  | ] | ||||||
|  | } | ||||||
|  | fire={ | ||||||
|  | "deadzone": 0.2, | ||||||
|  | "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(147, 21),"global_position":Vector2(156, 67),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null) | ||||||
|  | ] | ||||||
|  | } | ||||||
|  | pause={ | ||||||
|  | "deadzone": 0.2, | ||||||
|  | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) | ||||||
|  | ] | ||||||
|  | } | ||||||
|  | 
 | ||||||
| [layer_names] | [layer_names] | ||||||
| 
 | 
 | ||||||
| 3d_render/layer_1="Global Noise Layer" | 3d_render/layer_1="Global Noise Layer" | ||||||
| 3d_physics/layer_1="World Geometry" | 3d_physics/layer_1="World Geometry" | ||||||
| 3d_physics/layer_2="Player" | 3d_physics/layer_2="Player" | ||||||
|  | 3d_physics/layer_3="Layer 3" | ||||||
|  | |||||||
| @ -3,6 +3,8 @@ class_name CameraController extends Node3D | |||||||
| 
 | 
 | ||||||
| const PITCH_LIMIT := deg_to_rad(85.0) | const PITCH_LIMIT := deg_to_rad(85.0) | ||||||
| 
 | 
 | ||||||
|  | @export var yaw_root: Node3D | ||||||
|  | 
 | ||||||
| @onready var _target := Vector2(rotation.x, rotation.y) | @onready var _target := Vector2(rotation.x, rotation.y) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -17,5 +19,5 @@ func camera_motion(motion: Vector2) -> void: | |||||||
| func _physics_process(delta: float) -> void: | func _physics_process(delta: float) -> void: | ||||||
| 	var accel: float = ProjectSettings.get_setting("game/config/input/camera_acceleration") | 	var accel: float = ProjectSettings.get_setting("game/config/input/camera_acceleration") | ||||||
| 	var weight := 1.0 - exp(-accel * delta) | 	var weight := 1.0 - exp(-accel * delta) | ||||||
| 	rotation.y = lerp_angle(rotation.y, _target.y, weight) | 	yaw_root.rotation.y = lerp_angle(yaw_root.rotation.y, _target.y, weight) | ||||||
| 	rotation.x = lerp_angle(rotation.x, _target.x, weight) | 	rotation.x = lerp_angle(rotation.x, _target.x, weight) | ||||||
|  | |||||||
							
								
								
									
										61
									
								
								src/player/movement_controller.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/player/movement_controller.gd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | |||||||
|  | class_name MovementController extends Node | ||||||
|  | ## Character movement controller | ||||||
|  | 
 | ||||||
|  | @export var movement_enabled := true | ||||||
|  | 
 | ||||||
|  | @export_group("Speed") | ||||||
|  | @export var run_speed := 80.0 | ||||||
|  | @export var sprint_speed := 160.0 | ||||||
|  | @export var air_speed_factor := 0.1 | ||||||
|  | 
 | ||||||
|  | @export_group("Jump") | ||||||
|  | @export var jump_force := 4.0 | ||||||
|  | 
 | ||||||
|  | @export_group("Friction") | ||||||
|  | @export var ground_friction := 0.3 | ||||||
|  | @export var air_friction := 0.04 | ||||||
|  | 
 | ||||||
|  | var sprinting := false | ||||||
|  | var movement := Vector2.ZERO | ||||||
|  | 
 | ||||||
|  | @onready var character: CharacterBody3D = get_parent() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | func get_speed() -> float: | ||||||
|  | 	var speed := run_speed | ||||||
|  | 	if sprinting: | ||||||
|  | 		speed = sprint_speed | ||||||
|  | 	if not character.is_on_floor(): | ||||||
|  | 		speed *= air_speed_factor | ||||||
|  | 	return speed | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | func get_friction() -> float: | ||||||
|  | 	return ground_friction if character.is_on_floor() else air_friction | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## Make the character jump. | ||||||
|  | func jump() -> void: | ||||||
|  | 	if movement_enabled and character.is_on_floor(): | ||||||
|  | 		character.velocity.y = jump_force | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | func _physics_process(delta: float) -> void: | ||||||
|  | 	if not character.is_on_floor(): | ||||||
|  | 		# Apply gravity | ||||||
|  | 		character.velocity += character.get_gravity() * delta | ||||||
|  | 
 | ||||||
|  | 	if movement_enabled: | ||||||
|  | 		# Apply movement input | ||||||
|  | 		var rel_movement := movement.rotated(-character.global_rotation.y) | ||||||
|  | 		var direction := Vector3(rel_movement.x, 0, rel_movement.y).normalized() | ||||||
|  | 		var motion := direction * get_speed() * delta | ||||||
|  | 		character.velocity.x += motion.x | ||||||
|  | 		character.velocity.z += motion.z | ||||||
|  | 
 | ||||||
|  | 	# Apply friction | ||||||
|  | 	var weight := 1.0 - exp(-get_friction() * 60 * delta) | ||||||
|  | 	character.velocity.x = lerpf(character.velocity.x, 0, weight) | ||||||
|  | 	character.velocity.z = lerpf(character.velocity.z, 0, weight) | ||||||
|  | 
 | ||||||
|  | 	character.move_and_slide() | ||||||
							
								
								
									
										1
									
								
								src/player/movement_controller.gd.uid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/player/movement_controller.gd.uid
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | uid://c0nxcunx0fo4r | ||||||
							
								
								
									
										9
									
								
								src/player/player.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/player/player.gd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | |||||||
|  | class_name Player extends CharacterBody3D | ||||||
|  | ## The instance of the current player in the game world. | ||||||
|  | 
 | ||||||
|  | ## Global singleton accessor | ||||||
|  | static var instance: Player | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | func _init() -> void: | ||||||
|  | 	Player.instance = self | ||||||
							
								
								
									
										1
									
								
								src/player/player.gd.uid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/player/player.gd.uid
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | uid://bihaf1xlwpkdo | ||||||
| @ -1,9 +1,12 @@ | |||||||
| [gd_scene load_steps=8 format=3 uid="uid://dtbulshrxetes"] | [gd_scene load_steps=12 format=3 uid="uid://dtbulshrxetes"] | ||||||
| 
 | 
 | ||||||
|  | [ext_resource type="Script" uid="uid://bihaf1xlwpkdo" path="res://src/player/player.gd" id="1_5f2sf"] | ||||||
| [ext_resource type="Script" uid="uid://f3kssctvn2bo" path="res://src/player/camera_controller.gd" id="1_mf2ua"] | [ext_resource type="Script" uid="uid://f3kssctvn2bo" path="res://src/player/camera_controller.gd" id="1_mf2ua"] | ||||||
| [ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="1_rxibo"] | [ext_resource type="Script" uid="uid://csjccrhj5wnx7" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_3d.gd" id="1_rxibo"] | ||||||
| [ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_mf2ua"] | [ext_resource type="Script" uid="uid://8umksf8e80fw" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="2_mf2ua"] | ||||||
| [ext_resource type="Script" uid="uid://032jyhgkb2rv" path="res://src/player/mouselook_controller.gd" id="4_244u8"] | [ext_resource type="Script" uid="uid://032jyhgkb2rv" path="res://src/player/mouselook_controller.gd" id="4_244u8"] | ||||||
|  | [ext_resource type="Script" uid="uid://c0nxcunx0fo4r" path="res://src/player/movement_controller.gd" id="6_jiejy"] | ||||||
|  | [ext_resource type="Script" uid="uid://d11erhxna68vd" path="res://src/player/player_input_controller.gd" id="7_o822w"] | ||||||
| 
 | 
 | ||||||
| [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_qnmj6"] | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_qnmj6"] | ||||||
| 
 | 
 | ||||||
| @ -15,20 +18,27 @@ duration = 0.4 | |||||||
| transition = 7 | transition = 7 | ||||||
| ease = 0 | ease = 0 | ||||||
| 
 | 
 | ||||||
|  | [sub_resource type="CapsuleMesh" id="CapsuleMesh_o822w"] | ||||||
|  | radius = 0.1 | ||||||
|  | height = 1.0 | ||||||
|  | 
 | ||||||
| [node name="Player" type="CharacterBody3D"] | [node name="Player" type="CharacterBody3D"] | ||||||
| collision_layer = 3 | collision_layer = 3 | ||||||
|  | script = ExtResource("1_5f2sf") | ||||||
| 
 | 
 | ||||||
| [node name="CollisionShape3D" type="CollisionShape3D" parent="."] | [node name="CollisionShape3D" type="CollisionShape3D" parent="."] | ||||||
| shape = SubResource("CapsuleShape3D_qnmj6") | shape = SubResource("CapsuleShape3D_qnmj6") | ||||||
| 
 | 
 | ||||||
| [node name="MeshInstance3D" type="MeshInstance3D" parent="."] | [node name="MeshInstance3D" type="MeshInstance3D" parent="."] | ||||||
|  | gi_mode = 0 | ||||||
| mesh = SubResource("CapsuleMesh_4anbu") | mesh = SubResource("CapsuleMesh_4anbu") | ||||||
| 
 | 
 | ||||||
| [node name="CameraOffset" type="Node3D" parent="."] | [node name="CameraOffset" type="Node3D" parent="."] | ||||||
| transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) | ||||||
| 
 | 
 | ||||||
| [node name="CameraController" type="Node3D" parent="CameraOffset"] | [node name="CameraController" type="Node3D" parent="CameraOffset" node_paths=PackedStringArray("yaw_root")] | ||||||
| script = ExtResource("1_mf2ua") | script = ExtResource("1_mf2ua") | ||||||
|  | yaw_root = NodePath("../..") | ||||||
| 
 | 
 | ||||||
| [node name="PhantomCamera3D" type="Node3D" parent="CameraOffset/CameraController"] | [node name="PhantomCamera3D" type="Node3D" parent="CameraOffset/CameraController"] | ||||||
| script = ExtResource("1_rxibo") | script = ExtResource("1_rxibo") | ||||||
| @ -37,6 +47,19 @@ tween_resource = SubResource("Resource_244u8") | |||||||
| noise_emitter_layer = 1 | noise_emitter_layer = 1 | ||||||
| metadata/_custom_type_script = "uid://csjccrhj5wnx7" | metadata/_custom_type_script = "uid://csjccrhj5wnx7" | ||||||
| 
 | 
 | ||||||
|  | [node name="MeshInstance3D" type="MeshInstance3D" parent="CameraOffset/CameraController/PhantomCamera3D"] | ||||||
|  | transform = Transform3D(1, 0, 0, 0, -4.371139e-08, -1, 0, 1, -4.371139e-08, 0, 0, -0.45) | ||||||
|  | gi_mode = 0 | ||||||
|  | mesh = SubResource("CapsuleMesh_o822w") | ||||||
|  | 
 | ||||||
| [node name="MouselookController" type="Node" parent="CameraOffset/CameraController"] | [node name="MouselookController" type="Node" parent="CameraOffset/CameraController"] | ||||||
| script = ExtResource("4_244u8") | script = ExtResource("4_244u8") | ||||||
| metadata/_custom_type_script = "uid://032jyhgkb2rv" | metadata/_custom_type_script = "uid://032jyhgkb2rv" | ||||||
|  | 
 | ||||||
|  | [node name="MovementController" type="Node" parent="."] | ||||||
|  | script = ExtResource("6_jiejy") | ||||||
|  | metadata/_custom_type_script = "uid://c0nxcunx0fo4r" | ||||||
|  | 
 | ||||||
|  | [node name="PlayerInputController" type="Node" parent="MovementController"] | ||||||
|  | script = ExtResource("7_o822w") | ||||||
|  | metadata/_custom_type_script = "uid://d11erhxna68vd" | ||||||
|  | |||||||
							
								
								
									
										13
									
								
								src/player/player_input_controller.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/player/player_input_controller.gd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | class_name PlayerInputController extends Node | ||||||
|  | ## Player controller component using project-defined player inputs. | ||||||
|  | 
 | ||||||
|  | @onready var movement_controller: MovementController = get_parent() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | func _physics_process(_delta: float) -> void: | ||||||
|  | 	if Input.is_action_just_pressed("jump"): | ||||||
|  | 		movement_controller.jump() | ||||||
|  | 	movement_controller.movement = Input.get_vector( | ||||||
|  | 		"move_left", "move_right", "move_forward", "move_back" | ||||||
|  | 	) | ||||||
|  | 	movement_controller.sprinting = Input.is_action_pressed("sprint") | ||||||
							
								
								
									
										1
									
								
								src/player/player_input_controller.gd.uid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/player/player_input_controller.gd.uid
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | uid://d11erhxna68vd | ||||||
| @ -1,4 +1,4 @@ | |||||||
| [gd_scene load_steps=9 format=3 uid="uid://daxngklaqlyba"] | [gd_scene load_steps=11 format=3 uid="uid://daxngklaqlyba"] | ||||||
| 
 | 
 | ||||||
| [ext_resource type="PackedScene" uid="uid://dtbulshrxetes" path="res://src/player/player.tscn" id="1_1k4gi"] | [ext_resource type="PackedScene" uid="uid://dtbulshrxetes" path="res://src/player/player.tscn" id="1_1k4gi"] | ||||||
| [ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="2_6fy3g"] | [ext_resource type="Script" uid="uid://bd046eokvcnu2" path="res://addons/phantom_camera/scripts/phantom_camera_host/phantom_camera_host.gd" id="2_6fy3g"] | ||||||
| @ -28,6 +28,11 @@ size = Vector2(16, 16) | |||||||
| 
 | 
 | ||||||
| [sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_1k4gi"] | [sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_1k4gi"] | ||||||
| 
 | 
 | ||||||
|  | [sub_resource type="BoxMesh" id="BoxMesh_6fy3g"] | ||||||
|  | 
 | ||||||
|  | [sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_6fy3g"] | ||||||
|  | data = PackedVector3Array(-0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5) | ||||||
|  | 
 | ||||||
| [node name="World" type="Node3D"] | [node name="World" type="Node3D"] | ||||||
| 
 | 
 | ||||||
| [node name="WorldEnvironment" type="WorldEnvironment" parent="."] | [node name="WorldEnvironment" type="WorldEnvironment" parent="."] | ||||||
| @ -56,3 +61,12 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0) | |||||||
| process_priority = 300 | process_priority = 300 | ||||||
| process_physics_priority = 300 | process_physics_priority = 300 | ||||||
| script = ExtResource("2_6fy3g") | script = ExtResource("2_6fy3g") | ||||||
|  | 
 | ||||||
|  | [node name="MeshInstance3D" type="MeshInstance3D" parent="."] | ||||||
|  | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.5, 0.5, 4.5) | ||||||
|  | mesh = SubResource("BoxMesh_6fy3g") | ||||||
|  | 
 | ||||||
|  | [node name="StaticBody3D" type="StaticBody3D" parent="MeshInstance3D"] | ||||||
|  | 
 | ||||||
|  | [node name="CollisionShape3D" type="CollisionShape3D" parent="MeshInstance3D/StaticBody3D"] | ||||||
|  | shape = SubResource("ConcavePolygonShape3D_6fy3g") | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user