├── .gitignore
├── LICENSE
├── Physics
└── player.tres
├── README.md
├── Scenes
├── cuberb.gd
└── scene1.tscn
├── Scripts
├── Draw3D.gd
├── DrawLine3D.gd
└── draw.gd
├── Textures
├── TexturesCom_Pavement_CobblestoneMossy01_2x2_1K_albedo.png
├── TexturesCom_Pavement_CobblestoneMossy01_2x2_1K_albedo.png.import
├── TexturesCom_RoughWoodPlanks_2x2_1K_albedo.png
└── TexturesCom_RoughWoodPlanks_2x2_1K_albedo.png.import
├── addons
└── godot-jolt
│ ├── LICENSE.txt
│ ├── THIRDPARTY.txt
│ ├── godot-jolt.gdextension
│ ├── linux
│ ├── godot-jolt_linux-x64.so
│ ├── godot-jolt_linux-x64_editor.so
│ ├── godot-jolt_linux-x86.so
│ └── godot-jolt_linux-x86_editor.so
│ ├── macos
│ ├── godot-jolt_macos.framework
│ │ ├── Resources
│ │ │ └── Info.plist
│ │ ├── _CodeSignature
│ │ │ └── CodeResources
│ │ └── godot-jolt_macos
│ └── godot-jolt_macos_editor.framework
│ │ ├── Resources
│ │ └── Info.plist
│ │ ├── _CodeSignature
│ │ └── CodeResources
│ │ └── godot-jolt_macos_editor
│ └── windows
│ ├── godot-jolt_windows-x64.dll
│ ├── godot-jolt_windows-x64_editor.dll
│ ├── godot-jolt_windows-x86.dll
│ └── godot-jolt_windows-x86_editor.dll
├── default_env.tres
├── icon.png
├── icon.png.import
├── move.gd
└── project.godot
/.gitignore:
--------------------------------------------------------------------------------
1 | # Godot-specific ignores
2 | .import/
3 | export.cfg
4 | export_presets.cfg
5 | *.tmp
6 |
7 | # Imported translations (automatically generated from CSV files)
8 | *.translation
9 |
10 | # Mono-specific ignores
11 | .mono/
12 | data_*/
13 | # Godot 4+ specific ignores
14 | .godot/
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 FreeFly
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Physics/player.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="PhysicsMaterial" load_steps=2 format=3 uid="uid://u55tuef0hp46"]
2 |
3 | [sub_resource type="GDScript" id="1"]
4 |
5 | [resource]
6 | script = SubResource("1")
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Code of interest in [move.gd](https://github.com/FreeFlyFall/RigidBodyController/blob/master/move.gd)
2 |
3 | # RigidBodyController
4 | The beginnings of a first person rigidbody character controller in Godot. Some of the benefits:
5 | - Pushing, being pushed by, and riding other objects with no extra code
6 | - Shotgun jumping and air controls
7 | - Movement acceleration and velocity limits
8 | - Velocity limits only apply to movement input. Outside forces, such as pushes or shotgun jumping can force the player above the velocity limit.
9 | The player can oppose these forces and slow down or move sideways, but can't add to the speed in the direction which is over the velocity limit.
10 | - Smooth movement transitions - inherent friction and inertia
11 | - Easy walking on slopes
12 |
13 | [Reddit Video](https://www.reddit.com/r/godot/comments/grxg1e/physics_based_character_controller/)
14 |
--------------------------------------------------------------------------------
/Scenes/cuberb.gd:
--------------------------------------------------------------------------------
1 | extends RigidBody3D
2 |
3 | # Called when the node enters the scene tree for the first time.
4 | func _ready():
5 | pass # Replace with function body.
6 |
7 | var once = false
8 | func _integrate_forces(state):
9 | if (once == false):
10 | once = true
11 | var direction = Vector3(0,0,1)
12 | #if state.get_linear_velocity().z < 5:
13 | state.apply_central_impulse(-direction*3000)
14 |
--------------------------------------------------------------------------------
/Scenes/scene1.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=17 format=3 uid="uid://cwn6jw887nywo"]
2 |
3 | [ext_resource type="Script" path="res://move.gd" id="1"]
4 | [ext_resource type="PhysicsMaterial" uid="uid://u55tuef0hp46" path="res://Physics/player.tres" id="2"]
5 | [ext_resource type="Texture2D" uid="uid://c0lwdk68m5mt2" path="res://Textures/TexturesCom_Pavement_CobblestoneMossy01_2x2_1K_albedo.png" id="3_bxssy"]
6 | [ext_resource type="Texture2D" uid="uid://bjix76sl4cdwa" path="res://Textures/TexturesCom_RoughWoodPlanks_2x2_1K_albedo.png" id="6"]
7 |
8 | [sub_resource type="CapsuleShape3D" id="1"]
9 |
10 | [sub_resource type="CapsuleMesh" id="2"]
11 |
12 | [sub_resource type="VoxelGIData" id="20"]
13 | dynamic_range = 4.0
14 | propagation = 0.7
15 |
16 | [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_pc00p"]
17 | albedo_texture = ExtResource("6")
18 | uv1_scale = Vector3(2.595, 1.27, 0.67)
19 |
20 | [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_n2yvt"]
21 | albedo_texture = ExtResource("3_bxssy")
22 | uv1_triplanar = true
23 | uv1_world_triplanar = true
24 |
25 | [sub_resource type="BoxMesh" id="BoxMesh_hwgry"]
26 | material = SubResource("StandardMaterial3D_n2yvt")
27 |
28 | [sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_o3rtm"]
29 | 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)
30 |
31 | [sub_resource type="PhysicsMaterial" id="PhysicsMaterial_en2a0"]
32 | friction = 0.0
33 |
34 | [sub_resource type="BoxMesh" id="BoxMesh_01c47"]
35 |
36 | [sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_ay55d"]
37 | points = 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)
38 |
39 | [sub_resource type="CapsuleMesh" id="CapsuleMesh_8wokw"]
40 |
41 | [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_wk1cy"]
42 |
43 | [node name="Node3D" type="Node3D"]
44 |
45 | [node name="Player" type="RigidBody3D" parent="."]
46 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.158582, 1.78085, 1.62877)
47 | axis_lock_angular_x = true
48 | axis_lock_angular_z = true
49 | mass = 0.939597
50 | physics_material_override = ExtResource("2")
51 | can_sleep = false
52 | continuous_cd = true
53 | contact_monitor = true
54 | max_contacts_reported = 5
55 | linear_damp = 0.01
56 | angular_damp = 10.0
57 | script = ExtResource("1")
58 | debug_lines = true
59 | accel = 100
60 | jump = 10
61 | air_control = 5
62 | turning_scale = 45.0
63 | walkable_normal = 0.5
64 | speed_to_crouch = 8
65 | friction_divider = 4
66 |
67 | [node name="CollisionShape3D" type="CollisionShape3D" parent="Player"]
68 | transform = Transform3D(1, -4.93969e-11, 1.16415e-10, 9.09495e-12, 1, -1.16415e-10, 0, 3.49246e-10, 1, 0, 0, 0)
69 | shape = SubResource("1")
70 |
71 | [node name="MeshInstance3D" type="MeshInstance3D" parent="Player"]
72 | transform = Transform3D(1, -1.07605e-10, 1.16415e-10, -4.87717e-11, 1, -3.49246e-10, 0, 1.04774e-09, 1, 0, 0, 0)
73 | layers = 2
74 | cast_shadow = 0
75 | mesh = SubResource("2")
76 |
77 | [node name="Head" type="Node3D" parent="."]
78 | transform = Transform3D(1, -0.000456549, 0.00051408, 0.000455753, 0.999999, 0.00154718, -0.000514786, -0.00154695, 0.999999, -7.25033, 3.80638, 5.18283)
79 |
80 | [node name="Pitch" type="Node3D" parent="Head"]
81 |
82 | [node name="Camera3D" type="Camera3D" parent="Head/Pitch"]
83 | transform = Transform3D(1, 1.82695e-10, 2.32831e-10, -8.13998e-11, 1, 4.88944e-09, 1.74623e-10, 0, 1, 0, 0, 0)
84 | cull_mask = 1048573
85 | fov = 101.1
86 | far = 500.0
87 |
88 | [node name="Camera3D2" type="Camera3D" parent="Head/Pitch/Camera3D"]
89 | transform = Transform3D(1, -1.66096e-10, 1.16415e-10, 1.83263e-10, 1, 0, -5.82077e-11, 0, 1, 7.05381, -2.53933, -1.41326)
90 | cull_mask = 1048573
91 |
92 | [node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
93 | transform = Transform3D(0.251867, 0.967762, 8.93903e-09, 0.0660924, -0.017201, 0.997665, 0.965503, -0.251279, -0.068294, 0.0889626, 16.6875, -0.00400639)
94 | light_color = Color(1, 0.988235, 0.878431, 1)
95 | light_energy = 3.923
96 | light_indirect_energy = 1.813
97 | light_volumetric_fog_energy = 0.36
98 | shadow_enabled = true
99 |
100 | [node name="VoxelGI" type="VoxelGI" parent="."]
101 | transform = Transform3D(1, 0, -8.74228e-08, 0, -1, 0, 8.74228e-08, 0, 1, 12.6872, 0.932631, -19.8859)
102 | size = Vector3(458.879, 50.0623, 207.626)
103 | data = SubResource("20")
104 |
105 | [node name="CSGBox3D2" type="CSGBox3D" parent="."]
106 | transform = Transform3D(20, 0, 0, 0, 0.0861957, 10.1396, 0, -0.0506982, 17.2391, 0, 1.70045, 16.5526)
107 | material_override = SubResource("StandardMaterial3D_pc00p")
108 | use_collision = true
109 |
110 | [node name="CSGBox3D3" type="CSGBox3D" parent="."]
111 | transform = Transform3D(-8.67993e-07, 0.0866026, -9.99998, 0.161603, 0.0499983, 17.3199, 19.9993, -0.000404004, -0.139953, -16.8382, 1.51522, 21.4435)
112 | material_override = SubResource("StandardMaterial3D_pc00p")
113 | use_collision = true
114 |
115 | [node name="CSGBox3D6" type="CSGBox3D" parent="."]
116 | transform = Transform3D(-8.64267e-07, 0.1, -3.92087e-06, 0.161603, -8.71491e-08, 19.9993, 19.9993, 5.18048e-09, -0.161603, -15.6913, 1.82469, 31.9274)
117 | material_override = SubResource("StandardMaterial3D_pc00p")
118 | use_collision = true
119 |
120 | [node name="CSGBox3D4" type="CSGBox3D" parent="."]
121 | transform = Transform3D(-8.64267e-07, 0.0707108, -14.1421, 0.161603, 0.0707083, 14.1416, 19.9993, -0.000571351, -0.114271, -16.4489, 1.57503, 1.03087)
122 | material_override = SubResource("StandardMaterial3D_pc00p")
123 | use_collision = true
124 |
125 | [node name="CSGBox3D5" type="CSGBox3D" parent="."]
126 | transform = Transform3D(-8.56817e-07, 0.0965926, -5.17637, 0.161603, 0.025881, 19.3178, 19.9993, -0.000209125, -0.156097, -16.4489, 1.79964, 28.8271)
127 | material_override = SubResource("StandardMaterial3D_pc00p")
128 | use_collision = true
129 |
130 | [node name="MeshInstance3D" type="MeshInstance3D" parent="."]
131 | transform = Transform3D(265.35, -0.000913893, 0.409863, 0.241657, 0.999995, 1.23447, -0.273384, -0.00309366, 398.909, -0.639654, -0.0624347, -3.05023)
132 | mesh = SubResource("BoxMesh_hwgry")
133 | skeleton = NodePath("")
134 |
135 | [node name="StaticBody3D" type="StaticBody3D" parent="MeshInstance3D"]
136 |
137 | [node name="CollisionShape3D" type="CollisionShape3D" parent="MeshInstance3D/StaticBody3D"]
138 | shape = SubResource("ConcavePolygonShape3D_o3rtm")
139 |
140 | [node name="RigidBody3D3" type="RigidBody3D" parent="."]
141 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.96149, 1.59805, 10.04)
142 | mass = 1.119
143 | physics_material_override = SubResource("PhysicsMaterial_en2a0")
144 |
145 | [node name="MeshInstance3D" type="MeshInstance3D" parent="RigidBody3D3"]
146 | transform = Transform3D(4.89632, 0, 0, 0, 0.420798, 0, 0, 0, 6.16068, 0, 0, 0)
147 | mesh = SubResource("BoxMesh_01c47")
148 |
149 | [node name="CollisionShape3D" type="CollisionShape3D" parent="RigidBody3D3"]
150 | transform = Transform3D(4.89632, 0, 0, 0, 0.420798, 0, 0, 0, 6.16068, 0, 0, 0)
151 | shape = SubResource("ConvexPolygonShape3D_ay55d")
152 |
153 | [node name="StaticBodyRect" type="StaticBody3D" parent="."]
154 | transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.27041, 0.692766, 3.0415)
155 | physics_material_override = SubResource("PhysicsMaterial_en2a0")
156 |
157 | [node name="MeshInstance3D" type="MeshInstance3D" parent="StaticBodyRect"]
158 | transform = Transform3D(4.89632, 0, 0, 0, 0.189687, 0, 0, 0, 6.16068, 0, 0, 0)
159 | mesh = SubResource("BoxMesh_01c47")
160 |
161 | [node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBodyRect"]
162 | transform = Transform3D(4.89632, 0, 0, 0, 0.189687, 0, 0, 0, 6.16068, 0, 0, 0)
163 | shape = SubResource("ConvexPolygonShape3D_ay55d")
164 |
165 | [node name="RigidBody3D" type="RigidBody3D" parent="."]
166 | transform = Transform3D(1, -0.000456549, 0.00051408, 0.000455753, 0.999999, 0.00154718, -0.000514786, -0.00154695, 0.999999, -0.32015, 1.47502, -0.495072)
167 |
168 | [node name="MeshInstance3D" type="MeshInstance3D" parent="RigidBody3D"]
169 | mesh = SubResource("CapsuleMesh_8wokw")
170 |
171 | [node name="CollisionShape3D" type="CollisionShape3D" parent="RigidBody3D"]
172 | shape = SubResource("CapsuleShape3D_wk1cy")
173 |
--------------------------------------------------------------------------------
/Scripts/Draw3D.gd:
--------------------------------------------------------------------------------
1 | extends Node
2 |
3 | func line(start: Vector3, end: Vector3, color = Color.MAGENTA, persist_seconds: float = 0):
4 | var mesh_instance := MeshInstance3D.new()
5 | var immediate_mesh := ImmediateMesh.new()
6 | var material := ORMMaterial3D.new()
7 |
8 | mesh_instance.mesh = immediate_mesh
9 | mesh_instance.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
10 |
11 | immediate_mesh.surface_begin(Mesh.PRIMITIVE_LINES, material)
12 | immediate_mesh.surface_add_vertex(start)
13 | immediate_mesh.surface_add_vertex(end)
14 | immediate_mesh.surface_end()
15 |
16 | material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
17 | material.albedo_color = color
18 |
19 | get_tree().get_root().add_child(mesh_instance)
20 |
21 | if persist_seconds:
22 | await get_tree().create_timer(persist_seconds).timeout
23 | mesh_instance.queue_free()
24 | else:
25 | return mesh_instance
26 |
--------------------------------------------------------------------------------
/Scripts/DrawLine3D.gd:
--------------------------------------------------------------------------------
1 | extends Node
2 |
3 | func line(pos1: Vector3, pos2: Vector3, color = Color.WHITE_SMOKE, persist_seconds = 0):
4 | var mesh_instance := MeshInstance3D.new()
5 | var immediate_mesh := ImmediateMesh.new()
6 | var material := ORMMaterial3D.new()
7 |
8 | mesh_instance.mesh = immediate_mesh
9 | mesh_instance.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
10 |
11 | immediate_mesh.surface_begin(Mesh.PRIMITIVE_LINES, material)
12 | immediate_mesh.surface_add_vertex(pos1)
13 | immediate_mesh.surface_add_vertex(pos2)
14 | immediate_mesh.surface_end()
15 |
16 | material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
17 | material.albedo_color = color
18 |
19 | return await final_cleanup(mesh_instance, persist_seconds)
20 |
21 | func point(pos: Vector3, radius = 0.05, color = Color.WHITE_SMOKE, persist_seconds = 0):
22 | var mesh_instance := MeshInstance3D.new()
23 | var sphere_mesh := SphereMesh.new()
24 | var material := ORMMaterial3D.new()
25 |
26 | mesh_instance.mesh = sphere_mesh
27 | mesh_instance.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
28 | mesh_instance.position = pos
29 |
30 | sphere_mesh.radius = radius
31 | sphere_mesh.height = radius*2
32 | sphere_mesh.material = material
33 |
34 | material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
35 | material.albedo_color = color
36 |
37 | return await final_cleanup(mesh_instance, persist_seconds)
38 |
39 | func final_cleanup(mesh_instance: MeshInstance3D, persist_seconds: float):
40 | get_tree().get_root().add_child(mesh_instance)
41 | if persist_seconds == 0:
42 | await get_tree().physics_frame
43 | mesh_instance.queue_free()
44 | elif persist_seconds > 0:
45 | await get_tree().create_timer(persist_seconds).timeout
46 | mesh_instance.queue_free()
47 | else:
48 | return mesh_instance
49 |
--------------------------------------------------------------------------------
/Scripts/draw.gd:
--------------------------------------------------------------------------------
1 | @tool
2 | extends Node3D
3 |
4 | # Test tool to draw lines
5 | # Note: Drawing at translation draws at top of capsule, not player origin
6 |
7 | var raycast_list = Array()
8 | var start = 1.2
9 | var bottom = 0.26
10 | # Cardinal vector distance
11 | var cv_dist = 0.5
12 | # Secondary vector distance
13 | # Added to 2 cardinal vectors to result in a diagonal with the same maginitude of a cardinal vector
14 | var sv_dist= cv_dist/sqrt(2)
15 |
16 | # Called when the node enters the scene tree for the first time.
17 | func _ready():
18 | pass # Replace with function body.
19 |
20 | func _process(_delta):
21 | raycast_list.clear()
22 |
23 | for i in 8:
24 | var loc = get_node('Player').position
25 | loc.y -= start
26 | match i:
27 | # Cardinal vectors
28 | 0:
29 | loc.z -= cv_dist
30 | 1:
31 | loc.z += cv_dist
32 | 2:
33 | loc.x += cv_dist
34 | 3:
35 | loc.x -= cv_dist
36 | # Secondary vectors
37 | 4:
38 | loc.z -= sv_dist
39 | loc.x += sv_dist
40 | 5:
41 | loc.z += sv_dist
42 | loc.x += sv_dist
43 | 6:
44 | loc.z -= sv_dist
45 | loc.x -= sv_dist
46 | 7:
47 | loc.z += sv_dist
48 | loc.x -= sv_dist
49 | var loc2 = loc
50 | loc2.y -= bottom
51 | raycast_list.append([loc,loc2])
52 | var draw = get_node("draw")
53 | draw.clear()
54 | for array in raycast_list:
55 | draw.begin(Mesh.PRIMITIVE_LINE_STRIP)
56 | draw.add_vertex(array[0])
57 | draw.add_vertex(array[1])
58 | draw.end()
59 |
--------------------------------------------------------------------------------
/Textures/TexturesCom_Pavement_CobblestoneMossy01_2x2_1K_albedo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeFlyFall/RigidBodyController/53ac733a40e90fe00ef3ade050dea703e2c96f2c/Textures/TexturesCom_Pavement_CobblestoneMossy01_2x2_1K_albedo.png
--------------------------------------------------------------------------------
/Textures/TexturesCom_Pavement_CobblestoneMossy01_2x2_1K_albedo.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://c0lwdk68m5mt2"
6 | path.s3tc="res://.godot/imported/TexturesCom_Pavement_CobblestoneMossy01_2x2_1K_albedo.png-9f3810e8e6b4572cdcd221b5dd6cbf0c.s3tc.ctex"
7 | metadata={
8 | "imported_formats": ["s3tc_bptc"],
9 | "vram_texture": true
10 | }
11 |
12 | [deps]
13 |
14 | source_file="res://Textures/TexturesCom_Pavement_CobblestoneMossy01_2x2_1K_albedo.png"
15 | dest_files=["res://.godot/imported/TexturesCom_Pavement_CobblestoneMossy01_2x2_1K_albedo.png-9f3810e8e6b4572cdcd221b5dd6cbf0c.s3tc.ctex"]
16 |
17 | [params]
18 |
19 | compress/mode=2
20 | compress/high_quality=false
21 | compress/lossy_quality=0.7
22 | compress/hdr_compression=1
23 | compress/normal_map=0
24 | compress/channel_pack=0
25 | mipmaps/generate=true
26 | mipmaps/limit=-1
27 | roughness/mode=0
28 | roughness/src_normal=""
29 | process/fix_alpha_border=true
30 | process/premult_alpha=false
31 | process/normal_map_invert_y=false
32 | process/hdr_as_srgb=false
33 | process/hdr_clamp_exposure=false
34 | process/size_limit=0
35 | detect_3d/compress_to=0
36 |
--------------------------------------------------------------------------------
/Textures/TexturesCom_RoughWoodPlanks_2x2_1K_albedo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeFlyFall/RigidBodyController/53ac733a40e90fe00ef3ade050dea703e2c96f2c/Textures/TexturesCom_RoughWoodPlanks_2x2_1K_albedo.png
--------------------------------------------------------------------------------
/Textures/TexturesCom_RoughWoodPlanks_2x2_1K_albedo.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://bjix76sl4cdwa"
6 | path.s3tc="res://.godot/imported/TexturesCom_RoughWoodPlanks_2x2_1K_albedo.png-2f8d888284d62b34a8ec4351f5015aa8.s3tc.ctex"
7 | metadata={
8 | "imported_formats": ["s3tc_bptc"],
9 | "vram_texture": true
10 | }
11 |
12 | [deps]
13 |
14 | source_file="res://Textures/TexturesCom_RoughWoodPlanks_2x2_1K_albedo.png"
15 | dest_files=["res://.godot/imported/TexturesCom_RoughWoodPlanks_2x2_1K_albedo.png-2f8d888284d62b34a8ec4351f5015aa8.s3tc.ctex"]
16 |
17 | [params]
18 |
19 | compress/mode=2
20 | compress/high_quality=false
21 | compress/lossy_quality=0.7
22 | compress/hdr_compression=1
23 | compress/normal_map=0
24 | compress/channel_pack=0
25 | mipmaps/generate=true
26 | mipmaps/limit=-1
27 | roughness/mode=0
28 | roughness/src_normal=""
29 | process/fix_alpha_border=true
30 | process/premult_alpha=false
31 | process/normal_map_invert_y=false
32 | process/hdr_as_srgb=false
33 | process/hdr_clamp_exposure=false
34 | process/size_limit=0
35 | detect_3d/compress_to=0
36 |
--------------------------------------------------------------------------------
/addons/godot-jolt/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) Mikael Hermansson and Godot Jolt contributors.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 | the Software, and to permit persons to whom the Software is furnished to do so,
8 | subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 |
--------------------------------------------------------------------------------
/addons/godot-jolt/THIRDPARTY.txt:
--------------------------------------------------------------------------------
1 | Godot Jolt incorporates third-party material from the projects listed below.
2 |
3 | Godot Engine (https://github.com/godotengine/godot)
4 |
5 | Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md).
6 | Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to
10 | deal in the Software without restriction, including without limitation the
11 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12 | sell copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 | IN THE SOFTWARE.
25 |
26 | godot-cpp (https://github.com/godot-jolt/godot-cpp)
27 |
28 | Copyright (c) 2017-present Godot Engine contributors.
29 | Copyright (c) 2022-present Mikael Hermansson.
30 |
31 | Permission is hereby granted, free of charge, to any person obtaining a copy
32 | of this software and associated documentation files (the "Software"), to
33 | deal in the Software without restriction, including without limitation the
34 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
35 | sell copies of the Software, and to permit persons to whom the Software is
36 | furnished to do so, subject to the following conditions:
37 |
38 | The above copyright notice and this permission notice shall be included in
39 | all copies or substantial portions of the Software.
40 |
41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
46 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
47 | IN THE SOFTWARE.
48 |
49 | Jolt Physics (https://github.com/godot-jolt/jolt)
50 |
51 | Copyright (c) 2021 Jorrit Rouwe.
52 |
53 | Permission is hereby granted, free of charge, to any person obtaining a copy
54 | of this software and associated documentation files (the "Software"), to
55 | deal in the Software without restriction, including without limitation the
56 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
57 | sell copies of the Software, and to permit persons to whom the Software is
58 | furnished to do so, subject to the following conditions:
59 |
60 | The above copyright notice and this permission notice shall be included in
61 | all copies or substantial portions of the Software.
62 |
63 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
65 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
66 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
67 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
68 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
69 | IN THE SOFTWARE.
70 |
71 | mimalloc (https://github.com/godot-jolt/mimalloc)
72 |
73 | Copyright (c) 2018-2021 Microsoft Corporation, Daan Leijen.
74 |
75 | Permission is hereby granted, free of charge, to any person obtaining a copy
76 | of this software and associated documentation files (the "Software"), to
77 | deal in the Software without restriction, including without limitation the
78 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
79 | sell copies of the Software, and to permit persons to whom the Software is
80 | furnished to do so, subject to the following conditions:
81 |
82 | The above copyright notice and this permission notice shall be included in
83 | all copies or substantial portions of the Software.
84 |
85 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
86 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
87 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
88 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
89 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
90 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
91 | IN THE SOFTWARE.
92 |
--------------------------------------------------------------------------------
/addons/godot-jolt/godot-jolt.gdextension:
--------------------------------------------------------------------------------
1 | [configuration]
2 |
3 | entry_symbol = "godot_jolt_main"
4 | compatibility_minimum = "4.1"
5 |
6 | [libraries]
7 |
8 | windows.release.x86_64 = "windows/godot-jolt_windows-x64.dll"
9 | windows.debug.x86_64 = "windows/godot-jolt_windows-x64_editor.dll"
10 |
11 | windows.release.x86_32 = "windows/godot-jolt_windows-x86.dll"
12 | windows.debug.x86_32 = "windows/godot-jolt_windows-x86_editor.dll"
13 |
14 | linux.release.x86_64 = "linux/godot-jolt_linux-x64.so"
15 | linux.debug.x86_64 = "linux/godot-jolt_linux-x64_editor.so"
16 |
17 | linux.release.x86_32 = "linux/godot-jolt_linux-x86.so"
18 | linux.debug.x86_32 = "linux/godot-jolt_linux-x86_editor.so"
19 |
20 | macos.release = "macos/godot-jolt_macos.framework"
21 | macos.debug = "macos/godot-jolt_macos_editor.framework"
22 |
--------------------------------------------------------------------------------
/addons/godot-jolt/linux/godot-jolt_linux-x64.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeFlyFall/RigidBodyController/53ac733a40e90fe00ef3ade050dea703e2c96f2c/addons/godot-jolt/linux/godot-jolt_linux-x64.so
--------------------------------------------------------------------------------
/addons/godot-jolt/linux/godot-jolt_linux-x64_editor.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeFlyFall/RigidBodyController/53ac733a40e90fe00ef3ade050dea703e2c96f2c/addons/godot-jolt/linux/godot-jolt_linux-x64_editor.so
--------------------------------------------------------------------------------
/addons/godot-jolt/linux/godot-jolt_linux-x86.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeFlyFall/RigidBodyController/53ac733a40e90fe00ef3ade050dea703e2c96f2c/addons/godot-jolt/linux/godot-jolt_linux-x86.so
--------------------------------------------------------------------------------
/addons/godot-jolt/linux/godot-jolt_linux-x86_editor.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeFlyFall/RigidBodyController/53ac733a40e90fe00ef3ade050dea703e2c96f2c/addons/godot-jolt/linux/godot-jolt_linux-x86_editor.so
--------------------------------------------------------------------------------
/addons/godot-jolt/macos/godot-jolt_macos.framework/Resources/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleInfoDictionaryVersion
6 | 6.0
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleExecutable
10 | godot-jolt_macos
11 | CFBundleName
12 | Godot Jolt
13 | CFBundleDisplayName
14 | Godot Jolt
15 | CFBundleIdentifier
16 | org.godot-jolt.godot-jolt
17 | NSHumanReadableCopyright
18 | Copyright (c) Mikael Hermansson and Godot Jolt contributors.
19 | CFBundleVersion
20 | 0.9.0
21 | CFBundleShortVersionString
22 | 0.9.0
23 | CFBundlePackageType
24 | FMWK
25 | CSResourcesFileMapped
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/addons/godot-jolt/macos/godot-jolt_macos.framework/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | Resources/Info.plist
8 |
9 | YuYYY8jBb0arCbHUJAYnYXN9Bl4=
10 |
11 |
12 | files2
13 |
14 | Resources/Info.plist
15 |
16 | hash2
17 |
18 | mUhdhGCxAeqGTDJQas4Ic9bzBCzZ6+vQ9lFDcNV630o=
19 |
20 |
21 |
22 | rules
23 |
24 | ^Resources/
25 |
26 | ^Resources/.*\.lproj/
27 |
28 | optional
29 |
30 | weight
31 | 1000
32 |
33 | ^Resources/.*\.lproj/locversion.plist$
34 |
35 | omit
36 |
37 | weight
38 | 1100
39 |
40 | ^Resources/Base\.lproj/
41 |
42 | weight
43 | 1010
44 |
45 | ^version.plist$
46 |
47 |
48 | rules2
49 |
50 | .*\.dSYM($|/)
51 |
52 | weight
53 | 11
54 |
55 | ^(.*/)?\.DS_Store$
56 |
57 | omit
58 |
59 | weight
60 | 2000
61 |
62 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/
63 |
64 | nested
65 |
66 | weight
67 | 10
68 |
69 | ^.*
70 |
71 | ^Info\.plist$
72 |
73 | omit
74 |
75 | weight
76 | 20
77 |
78 | ^PkgInfo$
79 |
80 | omit
81 |
82 | weight
83 | 20
84 |
85 | ^Resources/
86 |
87 | weight
88 | 20
89 |
90 | ^Resources/.*\.lproj/
91 |
92 | optional
93 |
94 | weight
95 | 1000
96 |
97 | ^Resources/.*\.lproj/locversion.plist$
98 |
99 | omit
100 |
101 | weight
102 | 1100
103 |
104 | ^Resources/Base\.lproj/
105 |
106 | weight
107 | 1010
108 |
109 | ^[^/]+$
110 |
111 | nested
112 |
113 | weight
114 | 10
115 |
116 | ^embedded\.provisionprofile$
117 |
118 | weight
119 | 20
120 |
121 | ^version\.plist$
122 |
123 | weight
124 | 20
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/addons/godot-jolt/macos/godot-jolt_macos.framework/godot-jolt_macos:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeFlyFall/RigidBodyController/53ac733a40e90fe00ef3ade050dea703e2c96f2c/addons/godot-jolt/macos/godot-jolt_macos.framework/godot-jolt_macos
--------------------------------------------------------------------------------
/addons/godot-jolt/macos/godot-jolt_macos_editor.framework/Resources/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleInfoDictionaryVersion
6 | 6.0
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleExecutable
10 | godot-jolt_macos_editor
11 | CFBundleName
12 | Godot Jolt
13 | CFBundleDisplayName
14 | Godot Jolt
15 | CFBundleIdentifier
16 | org.godot-jolt.godot-jolt
17 | NSHumanReadableCopyright
18 | Copyright (c) Mikael Hermansson and Godot Jolt contributors.
19 | CFBundleVersion
20 | 0.9.0
21 | CFBundleShortVersionString
22 | 0.9.0
23 | CFBundlePackageType
24 | FMWK
25 | CSResourcesFileMapped
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/addons/godot-jolt/macos/godot-jolt_macos_editor.framework/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | Resources/Info.plist
8 |
9 | g2kDFUAKlkXWSjx4ILQBttcmXe8=
10 |
11 |
12 | files2
13 |
14 | Resources/Info.plist
15 |
16 | hash2
17 |
18 | 8VcK9urwJzy+lEmTjkhZhwvnKsewbfJyRy25JLd26h0=
19 |
20 |
21 |
22 | rules
23 |
24 | ^Resources/
25 |
26 | ^Resources/.*\.lproj/
27 |
28 | optional
29 |
30 | weight
31 | 1000
32 |
33 | ^Resources/.*\.lproj/locversion.plist$
34 |
35 | omit
36 |
37 | weight
38 | 1100
39 |
40 | ^Resources/Base\.lproj/
41 |
42 | weight
43 | 1010
44 |
45 | ^version.plist$
46 |
47 |
48 | rules2
49 |
50 | .*\.dSYM($|/)
51 |
52 | weight
53 | 11
54 |
55 | ^(.*/)?\.DS_Store$
56 |
57 | omit
58 |
59 | weight
60 | 2000
61 |
62 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/
63 |
64 | nested
65 |
66 | weight
67 | 10
68 |
69 | ^.*
70 |
71 | ^Info\.plist$
72 |
73 | omit
74 |
75 | weight
76 | 20
77 |
78 | ^PkgInfo$
79 |
80 | omit
81 |
82 | weight
83 | 20
84 |
85 | ^Resources/
86 |
87 | weight
88 | 20
89 |
90 | ^Resources/.*\.lproj/
91 |
92 | optional
93 |
94 | weight
95 | 1000
96 |
97 | ^Resources/.*\.lproj/locversion.plist$
98 |
99 | omit
100 |
101 | weight
102 | 1100
103 |
104 | ^Resources/Base\.lproj/
105 |
106 | weight
107 | 1010
108 |
109 | ^[^/]+$
110 |
111 | nested
112 |
113 | weight
114 | 10
115 |
116 | ^embedded\.provisionprofile$
117 |
118 | weight
119 | 20
120 |
121 | ^version\.plist$
122 |
123 | weight
124 | 20
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/addons/godot-jolt/macos/godot-jolt_macos_editor.framework/godot-jolt_macos_editor:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeFlyFall/RigidBodyController/53ac733a40e90fe00ef3ade050dea703e2c96f2c/addons/godot-jolt/macos/godot-jolt_macos_editor.framework/godot-jolt_macos_editor
--------------------------------------------------------------------------------
/addons/godot-jolt/windows/godot-jolt_windows-x64.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeFlyFall/RigidBodyController/53ac733a40e90fe00ef3ade050dea703e2c96f2c/addons/godot-jolt/windows/godot-jolt_windows-x64.dll
--------------------------------------------------------------------------------
/addons/godot-jolt/windows/godot-jolt_windows-x64_editor.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeFlyFall/RigidBodyController/53ac733a40e90fe00ef3ade050dea703e2c96f2c/addons/godot-jolt/windows/godot-jolt_windows-x64_editor.dll
--------------------------------------------------------------------------------
/addons/godot-jolt/windows/godot-jolt_windows-x86.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeFlyFall/RigidBodyController/53ac733a40e90fe00ef3ade050dea703e2c96f2c/addons/godot-jolt/windows/godot-jolt_windows-x86.dll
--------------------------------------------------------------------------------
/addons/godot-jolt/windows/godot-jolt_windows-x86_editor.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeFlyFall/RigidBodyController/53ac733a40e90fe00ef3ade050dea703e2c96f2c/addons/godot-jolt/windows/godot-jolt_windows-x86_editor.dll
--------------------------------------------------------------------------------
/default_env.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="Environment" load_steps=2 format=3 uid="uid://b7euq6q2t2jiy"]
2 |
3 | [sub_resource type="Sky" id="1"]
4 |
5 | [resource]
6 | background_mode = 2
7 | sky = SubResource("1")
8 |
--------------------------------------------------------------------------------
/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FreeFlyFall/RigidBodyController/53ac733a40e90fe00ef3ade050dea703e2c96f2c/icon.png
--------------------------------------------------------------------------------
/icon.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="CompressedTexture2D"
5 | uid="uid://bx7v0us21yvnr"
6 | path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"
7 | metadata={
8 | "vram_texture": false
9 | }
10 |
11 | [deps]
12 |
13 | source_file="res://icon.png"
14 | dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"]
15 |
16 | [params]
17 |
18 | compress/mode=0
19 | compress/high_quality=false
20 | compress/lossy_quality=0.7
21 | compress/hdr_compression=1
22 | compress/normal_map=0
23 | compress/channel_pack=0
24 | mipmaps/generate=false
25 | mipmaps/limit=-1
26 | roughness/mode=0
27 | roughness/src_normal=""
28 | process/fix_alpha_border=true
29 | process/premult_alpha=false
30 | process/normal_map_invert_y=false
31 | process/hdr_as_srgb=false
32 | process/hdr_clamp_exposure=false
33 | process/size_limit=0
34 | detect_3d/compress_to=1
35 |
--------------------------------------------------------------------------------
/move.gd:
--------------------------------------------------------------------------------
1 | extends RigidBody3D
2 |
3 | ### Use the Jolt physics engine
4 |
5 | #DevNotes to-do:
6 | # Separate concerns for mouse and movement input handling, collider and mesh resizing
7 | # Add dash with set velocity?
8 | # Newton's third law eventually breaks. Wondering whether it's a physics engine bug.
9 |
10 | ### Global
11 |
12 | ## Whether to draw the debug lines for forces
13 | @export var debug_lines: bool
14 | ## Whether to print normals at the points of contact with the player capsule
15 | @export var debug_contact_normals: bool
16 | ## Whether to print details for groundedness checks
17 | @export var debug_groundedness: bool
18 | var is_grounded: bool # Whether the player is considered to be touching a walkable slope
19 | @onready var capsule = $CollisionShape3D.shape # Capsule collision shape of the player
20 | @onready var capsule_mesh = $MeshInstance3D.mesh # Capsule mesh shape
21 | @onready var camera = $"../Head/Pitch/Camera3D" # Camera3D node
22 | @onready var head = $"../Head" # y-axis rotation node (look left and right)
23 |
24 | ### Input vars
25 | @onready var pitch = $"../Head/Pitch" # x-axis rotation node (look up and down)
26 |
27 | ### Integrate forces vars
28 |
29 | ## Player acceleration force.
30 | @export var accel: int
31 | ## Jump force multiplier.
32 | @export var jump: int
33 | ## Air control multiplier.
34 | @export var air_control: int
35 | ## How quickly to scale movement toward a turning direction. Lower is more.
36 | @export_range(15, 120, 1) var turning_scale: float
37 | ## Mouse sensetivity. Default: 0.05.
38 | @export var mouse_sensitivity: float = 0.05
39 | ## Defines the steepest walkable slope. Lower is steeper. Default: 0.5.
40 | @export_range(0, 1, 0.01) var walkable_normal: float
41 | ## The rate at which the player moves in or out of the crouching position. High values may cause physics glitches.
42 | @export_range(2, 20) var speed_to_crouch: int
43 | ## Default speed limit of the player. Default: 8.
44 | @export var speed_limit: float = 8
45 | ## Speed to move at while crouching. Default: 4.
46 | @export var crouching_speed_limit: float = 4
47 | ## Speed to move at while sprinting. Default: 12.
48 | @export var sprinting_speed_limit: float = 12
49 | ## Amount to divide the friction by when not grounded (prevents sticking to walls that may come from air control). Default: 3.
50 | @export var friction_divider = 3
51 | var steepest_slope_normal: Vector3 # Stores the lowest (steepest) normal of the contact with the player collider
52 | var shallowest_slope_normal: Vector3 # Stores the highest (flattest) normal of the contact with the player collider
53 | var slope_normal: Vector3 # Stores normals of contact points for iteration
54 | var contacted_body: RigidBody3D # Rigid body the player is currently contacting, if there is one
55 | var player_physics_material = load("res://Physics/player.tres")
56 | var local_friction = player_physics_material.friction # Editor friction value
57 | var is_landing: bool = true # Whether the player has jumped and let go of jump
58 | var is_jumping: bool = false # Whether the player has jumped
59 | ## Stores preference for the delta time before the player can jump again. Default: 0.1.
60 | @export_range(0.01,1,0.01) var JUMP_THROTTLE: float = 0.1
61 | var jump_throttle: float # Variable used with jump throttling calculations
62 | ## Downward force multiplier to apply when letting go of space while jumping, in order to assist with landing. Default: 1.5.
63 | @export var landing_assist: float = 1.5
64 | ## Amount of force to stop sliding with (alternative to friction). Default: 3.
65 | @export_range(0.1,100,0.1) var anti_slide_force: float = 3
66 | ## Number of hitscans to use around the base of the player capsule to detect groundedness.
67 | @export var groundedness_hitscan_count: int = 12
68 |
69 | ### Physics process vars
70 | var original_height: float
71 | var crouching_height: float
72 | var current_speed_limit: float # Current speed limit to use. For standing or crouching.
73 | var posture # Current posture state
74 | enum { WALKING, CROUCHING, SPRINTING } # Possible values for posture
75 |
76 | ### Misc
77 | var ld = preload("res://Scripts//DrawLine3D.gd").new()
78 |
79 | func draw_arrow(pos1: Vector3, pos2: Vector3, color = Color.WHITE_SMOKE, persist_seconds = 0):
80 | ld.line(pos1, pos2, color, persist_seconds)
81 | ld.point(pos1, 0.0075, color, persist_seconds)
82 |
83 | ### Godot notification functions ###
84 | func _ready():
85 | # Get capsule variables
86 | original_height = capsule.height
87 | crouching_height = capsule.height / 2
88 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) # Capture and hide mouse
89 | add_child(ld) # Add line drawer
90 |
91 |
92 | func _input(event):
93 | # Player look
94 | if event is InputEventMouseMotion:
95 | head.rotate_y(deg_to_rad(-event.relative.x * mouse_sensitivity))
96 | pitch.rotate_x(deg_to_rad(-event.relative.y * mouse_sensitivity))
97 | pitch.rotation.x = clamp(pitch.rotation.x, deg_to_rad(-90), deg_to_rad(90))
98 | # Capture and release mouse
99 | if event.is_action_pressed("ui_cancel"):
100 | if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
101 | Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) # Free the mouse
102 | else:
103 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
104 |
105 |
106 | var is_done_shrinking: bool # temporary # Whether the player is currently shrinking towards being crouched
107 | func _physics_process(delta):
108 | # Keep camera with player
109 | head.position = self.position + Vector3.UP * capsule.height / 2
110 |
111 | ### Player posture FSM
112 | if Input.is_action_pressed("crouch"):
113 | posture = CROUCHING
114 | elif Input.is_action_pressed("sprint"):
115 | posture = SPRINTING
116 | else:
117 | posture = WALKING
118 |
119 | ### Groundedness raycasts
120 | is_grounded = false
121 | # Define raycast info used with detecting groundedness
122 | var raycast_list = Array() # List of raycasts used with detecting groundedness
123 | var bottom = Vector3(0, 0.2, 0) # Distance down from start to fire the raycast to
124 | var start = (capsule.height / 2) - 0.2 # Start point down from the center of the player to start the raycast
125 | var edge_vector = Vector3(0, 0, capsule.radius - 0.1) # Initial vector toward the edge of the capsule
126 | # Get world state for collisions
127 | var direct_state = get_world_3d().direct_space_state
128 | raycast_list.clear()
129 |
130 | ## Create raycasts around the player capsule. They begin towards the edge of the radius, and shoot from just
131 | ## below the capsule to just below the bottom bounds of the capsule, with one raycast down from the center.
132 | # Get the starting location for the hitscans
133 | var location: Vector3 = self.position
134 | location.y -= start
135 | # Create the center raycast
136 | raycast_list.append([location, location - bottom])
137 | # Create the raycasts out from the center of the capsule
138 | for i in groundedness_hitscan_count:
139 | var working_location = location
140 | # The vector is rotated around the y-axis before applying to the edge vector to the centered point
141 | working_location += edge_vector.rotated(Vector3(0, 1, 0), deg_to_rad((i + 1) * 360.0 / groundedness_hitscan_count))
142 | # Subtract from the working location's vertical axis to get the ending point
143 | var end_point = working_location - bottom
144 | # Add an array, containing the two points for this iteration, to the list of raycasts
145 | raycast_list.append([working_location, end_point])
146 | # Check each raycast for collision, ignoring the capsule itself
147 | for array in raycast_list:
148 | var params = PhysicsRayQueryParameters3D.new()
149 | params.from = array[0]
150 | params.to = array[1]
151 | params.exclude = [self]
152 | if debug_lines: ld.line(array[0], array[1], Color.CHARTREUSE, 0)
153 | var collision = direct_state.intersect_ray(params)
154 | # The player is grounded if any of the raycasts hit
155 | if collision and is_walkable(collision.normal.y):
156 | is_grounded = true
157 | if debug_groundedness: print("Grounded Hitscans: "+str(is_grounded))
158 |
159 |
160 | ### Sprinting & Crouching
161 | var capsule_scale = delta * speed_to_crouch # Amount to change capsule height up or down
162 | var move_camera = delta / 2 * speed_to_crouch # Amount to move camera while crouching
163 | match posture:
164 | SPRINTING:
165 | current_speed_limit = sprinting_speed_limit
166 | grow_capsule(is_done_shrinking, capsule_scale, move_camera)
167 | CROUCHING: # Shrink
168 | current_speed_limit = crouching_speed_limit
169 | if capsule.height > crouching_height:
170 | capsule.height -= capsule_scale
171 | capsule_mesh.height -= capsule_scale
172 | elif is_done_shrinking == false:
173 | ## Adding a force to work around some physics glitches for the moment
174 | #var look_direction = head.transform.basis.z
175 | #self.apply_central_force(look_direction * mass * 100)
176 | is_done_shrinking = true
177 | WALKING: # Grow
178 | current_speed_limit = speed_limit
179 | grow_capsule(is_done_shrinking, capsule_scale, move_camera)
180 |
181 | # Setup jump throttle for integrate_forces
182 | if is_jumping or is_landing:
183 | jump_throttle -= delta
184 | else:
185 | jump_throttle = JUMP_THROTTLE
186 |
187 |
188 | func _integrate_forces(state):
189 | steepest_slope_normal = Vector3(0, 1, 0)
190 | shallowest_slope_normal = Vector3(0, -1, 0)
191 | contacted_body = null # Rigidbody
192 | # Velocity of the Rigidbody the player is contacting
193 | var contacted_body_vel_at_point = Vector3()
194 |
195 | ### Grounding, slopes, & rigidbody contact point
196 | # If the player body is contacting something
197 | var shallowest_contact_index: int = -1
198 |
199 | if state.get_contact_count() > 0:
200 | # Iterate over the capsule contact points and get the steepest/shallowest slopes
201 | for i in state.get_contact_count():
202 | slope_normal = state.get_contact_local_normal(i)
203 | if slope_normal.y < steepest_slope_normal.y: # Lower normal means steeper slope
204 | steepest_slope_normal = slope_normal
205 | if slope_normal.y > shallowest_slope_normal.y:
206 | shallowest_slope_normal = slope_normal
207 | shallowest_contact_index = i
208 | if debug_contact_normals: print("Steepest normal: "+str(steepest_slope_normal))
209 | if debug_contact_normals: print("Shallowest normal: "+str(shallowest_slope_normal))
210 | #### If the steepest slope contacted is more shallow than the walkable_normal, the player is grounded
211 | ####if is_walkable(steepest_slope_normal.y):
212 | ####is_grounded = true
213 | # If the shallowest slope normal is walkabe, the player is grounded #### Else if the shallowest slope normal is not walkable, the player is not grounded
214 | if is_walkable(shallowest_slope_normal.y):
215 | is_grounded = true
216 | if debug_groundedness: print("Grounded Contacts: "+str(is_grounded))
217 | # If a rigidbody is contacted, get the velocity at contact to be used with relative velocity calculations
218 | if shallowest_contact_index >= 0:
219 | var contact_position = state.get_contact_collider_position(0) # coords of the contact point from center of contacted body
220 | var collisions = get_colliding_bodies()
221 | var rb_collision_idx = null # rigidbody collision index
222 | if collisions.size() > 0:
223 | for collision_idx in collisions.size():
224 | if collisions[collision_idx].get_class() == "RigidBody3D":
225 | rb_collision_idx = collision_idx
226 | # Only use the relative velocity of the contacted body if it's considered walkable
227 | ## This prevents the relative velocity calculations from adding continual sideways force to an object
228 | if (rb_collision_idx != null and is_walkable(steepest_slope_normal.y)):
229 | contacted_body = collisions[rb_collision_idx]
230 | contacted_body_vel_at_point = state.get_contact_collider_velocity_at_position(rb_collision_idx)
231 | #contacted_body_vel_at_point = get_contacted_body_velocity_at_point(
232 | # contacted_body, contact_position
233 | #)
234 |
235 | ### Jumping: Should allow the player to jump, and hold jump to jump again if they become grounded after a throttling period
236 | var has_walkable_contact: bool = (
237 | state.get_contact_count() > 0 and is_walkable(shallowest_slope_normal.y)
238 | ) # Different from is_grounded
239 | # If the player is trying to jump, the throttle expired, the player is grounded, and they're not already jumping, jump
240 | # Check for is_jumping is because contact still exists at the beginning of a jump for more than one physics frame
241 | if (
242 | Input.is_action_pressed("jump")
243 | and jump_throttle < 0
244 | and has_walkable_contact
245 | and not is_jumping
246 | ):
247 | state.apply_central_impulse(Vector3(0, 1, 0) * jump)
248 | is_jumping = true
249 | is_landing = false
250 | # Apply a downward force once if the player lets go of jump to assist with landing
251 | if Input.is_action_just_released("jump"):
252 | if is_landing == false: # Only apply the landing assist force once
253 | is_landing = true
254 | if not has_walkable_contact:
255 | state.apply_central_impulse(Vector3(0, -1, 0) * landing_assist)
256 | # If the player becomes grounded, they're no longer considered to be jumping
257 | if has_walkable_contact:
258 | is_jumping = false
259 |
260 | ### Movement
261 | var move = relative_input() # Get movement vector relative to player orientation
262 | var move2 = Vector2(move.x, move.z) # Convert movement for Vector2 methods
263 |
264 | set_friction()
265 |
266 | # Get the player velocity, relative to the contacting body if there is one
267 | var vel = Vector3()
268 | if is_grounded:
269 | ## Keep vertical velocity if grounded. vel will be normalized below
270 | ## accounting for the y value, preventing faster movement on slopes.
271 | vel = state.get_linear_velocity()
272 | vel -= contacted_body_vel_at_point
273 | else:
274 | ## Remove y value of velocity so only horizontal speed is checked in the air.
275 | ## Without this, the normalized vel causes the speed limit check to
276 | ## progressively limit the player from moving horizontally in relation to vertical speed.
277 | vel = Vector3(state.get_linear_velocity().x, 0, state.get_linear_velocity().z)
278 | vel -= Vector3(contacted_body_vel_at_point.x, 0, contacted_body_vel_at_point.z)
279 | # Get a normalized player velocity
280 | var nvel = vel.normalized()
281 | var nvel2 = Vector2(nvel.x, nvel.z) # 2D velocity vector to use with angle_to and dot methods
282 |
283 | ## If below the speed limit, or above the limit but facing away from the velocity,
284 | ## move the player, adding an assisting force if turning. If above the speed limit,
285 | ## and facing the velocity, add a force perpendicular to the velocity and scale
286 | ## it based on where the player is moving in relation to the velocity.
287 | # Get the angle between the velocity and current movement vector and convert it to degrees
288 | var angle = nvel2.angle_to(move2)
289 | var theta = rad_to_deg(angle) # Angle between 2D look and velocity vectors
290 | var is_below_speed_limit: bool = is_below_speed_limit(vel)
291 | var is_facing_velocity: bool = nvel2.dot(move2) >= 0
292 | var direction: Vector3 # vector to be set 90 degrees either to the left or right of the velocity
293 | var scale: float # Scaled from 0 to 1. Used for both turn assist interpolation and vector scaling
294 | # If the angle is to the right of the velocity
295 | if theta > 0 and theta < 90:
296 | direction = nvel.cross(head.transform.basis.y) # Vecor 90 degrees to the right of velocity
297 | scale = clamp(theta / turning_scale, 0, 1) # Turn assist scale
298 | # If the angle is to the left of the velocity
299 | elif theta < 0 and theta > -90:
300 | direction = head.transform.basis.y.cross(nvel) # Vecor 90 degrees to the left of velocity
301 | scale = clamp(-theta / turning_scale, 0, 1)
302 | # Prevent continuous sliding down steep walkable slopes when the player isn't moving. Could be made better with
303 | # debouncing because too high of a force also affects stopping distance noticeably when not on a slope.
304 | if move == Vector3(0, 0, 0) and is_grounded:
305 | move = -vel / (mass * 100 / anti_slide_force)
306 | move(move, state)
307 | # If not pushing into an unwalkable slope
308 | elif steepest_slope_normal.y > walkable_normal:
309 | # If the player is below the speed limit, or is above it, but facing away from the velocity
310 | if is_below_speed_limit or not is_facing_velocity:
311 | # Interpolate between the movement and velocity vectors, scaling with turn assist sensitivity
312 | move = move.lerp(direction, scale)
313 | # If the player is above the speed limit, and looking within 90 degrees of the velocity
314 | else:
315 | move = direction # Set the move vector 90 to the right or left of the velocity vector
316 | move *= scale # Scale the vector. 0 if looking at velocity, up to full magnitude if looking 90 degrees to the side.
317 | move(move, state)
318 | # If pushing into an unwalkable slope, move with unscaled movement vector. Prevents turn assist from pushing the player into the wall.
319 | elif is_below_speed_limit:
320 | move(move, state)
321 | ### End movement
322 |
323 | # Shotgun jump test
324 | if Input.is_action_just_pressed("fire"):
325 | var dir: Vector3 = camera.global_transform.basis.z # Opposite of look direction
326 | state.apply_central_force(dir * 700)
327 |
328 |
329 | ### Functions ###
330 | # Gets the velocity of a contacted rigidbody at the point of contact with the player capsule
331 | '''
332 | func get_contacted_body_velocity_at_point(contacted_body: RigidBody3D, contact_position: Vector3):
333 | # Global coordinates of contacted body
334 | var body_position = contacted_body.transform.origin
335 | # Global coordinates of the point of contact between the player and contacted body
336 | var global_contact_position = body_position + contact_position
337 | # Calculate local velocity at point (cross product of angular velocity and contact position vectors)
338 | #print(contacted_body.get_angular_velocity())
339 | var local_vel_at_point = contacted_body.get_angular_velocity().cross(
340 | global_contact_position - body_position - body_position
341 | )
342 | # Add the current velocity of the contacted body to the velocity at the contacted point
343 | return contacted_body.get_linear_velocity() + local_vel_at_point
344 | '''
345 |
346 |
347 | # Return 4 cross products of b with a
348 | func cross4(a, b):
349 | return a.cross(b).cross(b).cross(b).cross(b)
350 |
351 |
352 | # Whether a slope is walkable
353 | func is_walkable(normal: float):
354 | return normal >= walkable_normal # Lower normal means steeper slope
355 |
356 |
357 | # Whether the player is below the speed limit in the direction they're traveling
358 | func is_below_speed_limit(vel):
359 | return vel.length() < current_speed_limit
360 |
361 |
362 | # Move the player
363 | func move(move, state):
364 | var draw_start = self.position - Vector3(0, capsule.height / 4, 0) + move # debug
365 | if is_grounded:
366 | var use_normal = Vector3(0,1,0) # For no slope
367 | var closest_contact_idx = null # The index of the contact point closest to the players intended movement vector
368 | # If a contact or contacts exist(s), use the normal at the contact point closest to the player's intended movement vector (for slope detection)
369 | if state.get_contact_count() > 0:
370 | var smallest_angle = null
371 | for i in state.get_contact_count():
372 | var origin_to_contact: Vector3 = state.get_contact_local_position(i) - self.transform.origin
373 | var angle = origin_to_contact.angle_to(relative_input())
374 | if closest_contact_idx == null or smallest_angle == null or angle < smallest_angle:
375 | closest_contact_idx = i
376 | smallest_angle = angle
377 | if closest_contact_idx != null:
378 | use_normal = state.get_contact_local_normal(closest_contact_idx)
379 |
380 | move = cross4(move, use_normal) # Get slope to move along based on contact
381 | if debug_lines:
382 | draw_arrow(draw_start, draw_start + move * capsule.radius, Color(1, 0, 0), 3) # debug
383 | state.apply_central_force(move * accel)
384 | # Account for equal and opposite reaction when contacting a RigidBody
385 | if contacted_body != null:
386 | pass #contacted_body.apply_force(state.get_contact_collider_position(0), move * -accel)
387 | else:
388 | if debug_lines:
389 | draw_arrow(draw_start, draw_start + move * capsule.radius, Color(0, 0, 1), 3) # debug
390 | state.apply_central_force(move * air_control)
391 |
392 |
393 | # Set player friction
394 | func set_friction():
395 | player_physics_material.friction = local_friction
396 | # If moving or not grounded, reduce friction
397 | if not is_grounded:
398 | player_physics_material.friction = local_friction / friction_divider
399 |
400 |
401 | # Get movement vector based on input, relative to the player's head transform
402 | func relative_input():
403 | # Initialize the movement vector
404 | var move = Vector3()
405 | # Get cumulative input on axes
406 | var input = Vector3()
407 | input.z += int(Input.is_action_pressed("move_forward"))
408 | input.z -= int(Input.is_action_pressed("move_backward"))
409 | input.x += int(Input.is_action_pressed("move_right"))
410 | input.x -= int(Input.is_action_pressed("move_left"))
411 | # Add input vectors to movement relative to the direction the head is facing
412 | move += input.z * -head.transform.basis.z
413 | move += input.x * head.transform.basis.x
414 | # Normalize to prevent stronger diagonal forces
415 | return move.normalized()
416 |
417 |
418 | # Grow the capsule toward the standing height
419 | func grow_capsule(is_done_shrinking, capsule_scale, move_camera):
420 | is_done_shrinking = false
421 | if capsule.height < original_height:
422 | capsule.height += capsule_scale
423 | capsule_mesh.height += capsule_scale
424 |
--------------------------------------------------------------------------------
/project.godot:
--------------------------------------------------------------------------------
1 | ; Engine configuration file.
2 | ; It's best edited using the editor UI and not directly,
3 | ; since the parameters that go here are not all obvious.
4 | ;
5 | ; Format:
6 | ; [section] ; section goes between []
7 | ; param=value ; assign values to parameters
8 |
9 | config_version=5
10 |
11 | [application]
12 |
13 | config/name="move"
14 | run/main_scene="res://Scenes/scene1.tscn"
15 | config/features=PackedStringArray("4.3")
16 | config/icon="res://icon.png"
17 |
18 | [autoload]
19 |
20 | Draw3D="*res://Scripts/Draw3D.gd"
21 |
22 | [display]
23 |
24 | window/size/viewport_width=1920
25 | window/size/viewport_height=1080
26 | window/size/borderless=true
27 | window/vsync/vsync_mode=false
28 |
29 | [dotnet]
30 |
31 | project/assembly_name="move"
32 |
33 | [input]
34 |
35 | move_forward={
36 | "deadzone": 0.5,
37 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":87,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
38 | ]
39 | }
40 | move_backward={
41 | "deadzone": 0.5,
42 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
43 | ]
44 | }
45 | move_left={
46 | "deadzone": 0.5,
47 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":65,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
48 | ]
49 | }
50 | move_right={
51 | "deadzone": 0.5,
52 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":68,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
53 | ]
54 | }
55 | jump={
56 | "deadzone": 0.5,
57 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":32,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
58 | ]
59 | }
60 | fire={
61 | "deadzone": 0.5,
62 | "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
63 | ]
64 | }
65 | crouch={
66 | "deadzone": 0.5,
67 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194326,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
68 | ]
69 | }
70 | sprint={
71 | "deadzone": 0.5,
72 | "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194325,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
73 | ]
74 | }
75 |
76 | [layer_names]
77 |
78 | 3d_render/layer_1="Player"
79 |
80 | [physics]
81 |
82 | 2d/physics_engine="GodotPhysics"
83 | 3d/physics_engine="JoltPhysics3D"
84 | 3d/default_gravity=14.9
85 | common/physics_fps=240
86 |
87 | [rendering]
88 |
89 | environment/defaults/default_environment="res://default_env.tres"
90 |
--------------------------------------------------------------------------------