17 Commits
1.0 ... 2.0

Author SHA1 Message Date
88db434420 * delta 2023-01-27 09:54:22 +01:00
ca59509782 fixed bugs and cleaned code 2023-01-27 09:27:24 +01:00
db124a0776 added information alert 2023-01-27 09:25:41 +01:00
0e10367fc9 added controller support 2023-01-27 09:05:12 +01:00
6538bf5f7f reverted unknown change 2023-01-24 13:41:50 +01:00
17b2fd0817 big performance improvement 2023-01-24 13:41:25 +01:00
Yannik
983dbf978f Update readme.md 2023-01-13 23:13:01 +01:00
9697ab1216 jitterfix 0.5f faster 2023-01-06 16:53:45 +01:00
eee59dfa6a custom actual working jitterfix 2023-01-06 16:49:36 +01:00
3c0c6ce9c0 Merge branch 'master' of https://github.com/vaporvee/gd-mono-thirdpersoncontroller 2023-01-06 16:22:37 +01:00
61922a1b52 changed max fps like less physics simulations 2023-01-06 15:25:40 +01:00
Yannik
8897be3be1 Create LICENSE.md 2023-01-06 01:53:15 +01:00
af8f505fcc adjusted mousepitch clamp 2023-01-04 20:26:06 +01:00
4276bf20c5 Merge branch 'master' of https://github.com/vaporvee/gd-mono-thirdpersoncontroller 2023-01-04 20:24:55 +01:00
f4ec2bf05d renamed icon 2023-01-04 20:24:49 +01:00
Yannik
a41f5afb4f Update readme.md 2023-01-03 20:21:03 +01:00
Yannik
e5cfe86cb5 Update readme.md 2023-01-03 20:13:11 +01:00
9 changed files with 121 additions and 47 deletions

21
LICENSE.md Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 vaporvee
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,4 +1,4 @@
<Project Sdk="Godot.NET.Sdk/4.0.0-beta.10"> <Project Sdk="Godot.NET.Sdk/4.0.0-beta.13">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading> <EnableDynamicLoading>true</EnableDynamicLoading>

View File

@@ -0,0 +1,7 @@
<Project Sdk="Godot.NET.Sdk/4.0.0-beta.10">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
<RootNamespace>gd-mono-thirdpersoncontroller</RootNamespace>
</PropertyGroup>
</Project>

View File

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View File

@@ -3,15 +3,15 @@
importer="texture" importer="texture"
type="CompressedTexture2D" type="CompressedTexture2D"
uid="uid://nqd2l5xjbwh1" uid="uid://nqd2l5xjbwh1"
path="res://.godot/imported/gd-mono-thirdpersoncontroller.png-1aea9d41ab1691227a784d4d60205324.ctex" path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"
metadata={ metadata={
"vram_texture": false "vram_texture": false
} }
[deps] [deps]
source_file="res://gd-mono-thirdpersoncontroller.png" source_file="res://icon.png"
dest_files=["res://.godot/imported/gd-mono-thirdpersoncontroller.png-1aea9d41ab1691227a784d4d60205324.ctex"] dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"]
[params] [params]

View File

@@ -13,9 +13,8 @@ config_version=5
config/name="Godot Mono thirdperson controller" config/name="Godot Mono thirdperson controller"
run/main_scene="res://scenes/main.tscn" run/main_scene="res://scenes/main.tscn"
config/features=PackedStringArray("4.0", "Forward Plus") config/features=PackedStringArray("4.0", "Forward Plus")
run/max_fps=144
boot_splash/show_image=false boot_splash/show_image=false
config/icon="res://gd-mono-thirdpersoncontroller.png" config/icon="res://icon.png"
[autoload] [autoload]
@@ -30,37 +29,66 @@ window/stretch/aspect="expand"
project/assembly_name="gd-mono-thirdpersoncontroller" project/assembly_name="gd-mono-thirdpersoncontroller"
[editor]
export/convert_text_resources_to_binary=true
[input] [input]
move_jump={
"deadzone": 0.5,
"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,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
]
}
move_left={ move_left={
"deadzone": 0.5, "deadzone": 0.5,
"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,"unicode":0,"echo":false,"script":null) "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,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
] ]
} }
move_right={ move_right={
"deadzone": 0.5, "deadzone": 0.5,
"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,"unicode":0,"echo":false,"script":null) "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,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
] ]
} }
move_forward={ move_forward={
"deadzone": 0.5, "deadzone": 0.5,
"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,"unicode":0,"echo":false,"script":null) "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,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
] ]
} }
move_backward={ move_backward={
"deadzone": 0.5, "deadzone": 0.5,
"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,"unicode":0,"echo":false,"script":null) "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,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
] ]
} }
move_jump={ gp_cam_left={
"deadzone": 0.5, "deadzone": 0.5,
"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,"unicode":0,"echo":false,"script":null) "events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":2,"axis_value":-1.0,"script":null)
]
}
gp_cam_right={
"deadzone": 0.5,
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":2,"axis_value":1.0,"script":null)
]
}
gp_cam_up={
"deadzone": 0.5,
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":3,"axis_value":-1.0,"script":null)
]
}
gp_cam_down={
"deadzone": 0.5,
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":3,"axis_value":1.0,"script":null)
] ]
} }
fullscreen={ fullscreen={
"deadzone": 0.5, "deadzone": 0.5,
"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":4194342,"physical_keycode":0,"unicode":0,"echo":false,"script":null) "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":4194342,"physical_keycode":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":true,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194309,"physical_keycode":0,"unicode":0,"echo":false,"script":null) , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":true,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":0,"unicode":0,"echo":false,"script":null)
] ]
} }
uncapture_mouse={ uncapture_mouse={
@@ -72,13 +100,9 @@ uncapture_mouse={
[physics] [physics]
common/physics_ticks_per_second=144 3d/run_on_separate_thread=true
3d/default_gravity=12.0 3d/default_gravity=12.0
[rendering] [rendering]
lights_and_shadows/directional_shadow/size=6144
lights_and_shadows/directional_shadow/soft_shadow_filter_quality=5
anti_aliasing/quality/msaa_3d=2
anti_aliasing/quality/screen_space_aa=1
occlusion_culling/use_occlusion_culling=true occlusion_culling/use_occlusion_culling=true

View File

@@ -1,3 +1,7 @@
# Godot Mono thirdperson controller # Godot Mono thirdperson controller
This is a working thirdperson controller made in the mono version of godot with C# <br> This is a working thirdperson controller made in the mono version of godot with C# <br>
Currently running in Godot 4 beta 10 Currently running in Godot 4 beta 10<br>
<br>
Demo video: https://www.youtube.com/watch?v=qTzU90Vj3Nw<br>
<br>
<img width="200px" src="https://raw.githubusercontent.com/vaporvee/gd-mono-thirdpersoncontroller/master/icon.png">

View File

@@ -2,18 +2,40 @@ using Godot;
public partial class player : CharacterBody3D public partial class player : CharacterBody3D
{ {
public Vector3 direction;
public Vector2 gpCamVector;
public bool gamepadMode;
[Export] float speed = 5.0f; [Export] float speed = 5.0f;
[Export] float jumpVelocity = 5f; [Export] float jumpVelocity = 5f;
[Export] float gravity = 14f; [Export] float gravity = 14f;
[Export(PropertyHint.Range, "0.1,1.0")] float mouseSensitivity = 0.3f; [Export(PropertyHint.Range, "0.1,1.0")] float camSensitivity = 0.3f;
[Export(PropertyHint.Range, "-90,0,1")] float minMousePitch = -90f; [Export(PropertyHint.Range, "-90,0,1")] float minCamPitch = -50f;
[Export(PropertyHint.Range, "0,90,1")] float maxMousePitch = 90f; [Export(PropertyHint.Range, "0,90,1")] float maxCamPitch = 30f;
public override void _Process(double delta) public override void _Process(double delta)
{ {
//uncapturing the mouse disables player movement but still simulates gravity //uncapturing the mouse disables PC movement but still simulates gravity
if (Input.IsActionJustPressed("uncapture_mouse")) Input.MouseMode = Input.MouseModeEnum.Visible; if (Input.IsActionJustPressed("uncapture_mouse")) Input.MouseMode = Input.MouseModeEnum.Visible;
if (Input.IsMouseButtonPressed(MouseButton.Left)) Input.MouseMode = Input.MouseModeEnum.Captured; if (Input.IsMouseButtonPressed(MouseButton.Left)) Input.MouseMode = Input.MouseModeEnum.Captured;
/**body rotation is in regular process because it lags in physicsprocess and is more a animation anyway
maybe rotate extra collisions separately for invisible lag that may occur**/
if (direction != Vector3.Zero && Input.MouseMode == Input.MouseModeEnum.Captured | gamepadMode)
{
Vector3 bodyRotation = GetNode<MeshInstance3D>("collision/body").Rotation;
bodyRotation.y = Mathf.LerpAngle(bodyRotation.y,Mathf.Atan2(-direction.x, -direction.z), (float)delta * speed);
GetNode<MeshInstance3D>("collision/body").Rotation = bodyRotation;
}
//camera gamepad part (needs constant movement so _Input event wouldn't work with this like mouseinput)
gpCamVector = Input.GetVector("gp_cam_left", "gp_cam_right", "gp_cam_up", "gp_cam_down");
if(gpCamVector != Vector2.Zero)
{
Vector3 camRot = GetNode<Marker3D>("camera_center").RotationDegrees;
camRot.y -= gpCamVector.x * camSensitivity * (float)delta * 500;
camRot.x -= gpCamVector.y * camSensitivity * (float)delta * 500;
camRot.x = Mathf.Clamp(camRot.x, minCamPitch, maxCamPitch); //prevents camera from going endlessly around the player
GetNode<Marker3D>("camera_center").RotationDegrees = camRot;
}
} }
public override void _PhysicsProcess(double delta) public override void _PhysicsProcess(double delta)
{ {
@@ -22,19 +44,15 @@ public partial class player : CharacterBody3D
if (!IsOnFloor()) if (!IsOnFloor())
velocity.y -= gravity * (float)delta; //characterbodys don't have physic simulations by default like rigidbody velocity.y -= gravity * (float)delta; //characterbodys don't have physic simulations by default like rigidbody
if (Input.IsActionJustPressed("move_jump") && IsOnFloor() && Input.MouseMode == Input.MouseModeEnum.Captured) if (Input.IsActionJustPressed("move_jump") && IsOnFloor() && Input.MouseMode == Input.MouseModeEnum.Captured | gamepadMode)
velocity.y = jumpVelocity; velocity.y = jumpVelocity;
Vector2 inputDir = Input.GetVector("move_left", "move_right", "move_forward", "move_backward"); Vector2 inputDir = Input.GetVector("move_left", "move_right", "move_forward", "move_backward");
Vector3 direction = new Vector3(inputDir.x, 0, inputDir.y).Rotated(Vector3.Up, GetNode<Marker3D>("camera_center").Rotation.y).Normalized(); //rotates the input direction with camera rotation direction = new Vector3(inputDir.x, 0, inputDir.y).Rotated(Vector3.Up, GetNode<Marker3D>("camera_center").Rotation.y).Normalized(); //rotates the input direction with camera rotation
if (direction != Vector3.Zero) if (direction != Vector3.Zero && Input.MouseMode == Input.MouseModeEnum.Captured | gamepadMode)
{ {
velocity.x = direction.x * speed; velocity.x = direction.x * speed * (float)delta * 60;
velocity.z = direction.z * speed; velocity.z = direction.z * speed * (float)delta * 60;
//Rotating the body mesh to movement
Vector3 bodyRotation = GetNode<MeshInstance3D>("collision/body").Rotation;
bodyRotation.y = Mathf.LerpAngle(bodyRotation.y,Mathf.Atan2(-direction.x, -direction.z), (float)delta * speed);
GetNode<MeshInstance3D>("collision/body").Rotation = bodyRotation;
} }
else else
{ {
@@ -43,16 +61,17 @@ public partial class player : CharacterBody3D
} }
Velocity = velocity; Velocity = velocity;
MoveAndSlide(); MoveAndSlide();
} }
public override void _Input(InputEvent @event) public override void _Input(InputEvent @event)
{ {
gamepadMode = @event is InputEventJoypadButton | @event is InputEventJoypadMotion;
Vector3 camRot = GetNode<Marker3D>("camera_center").RotationDegrees;
if (@event is InputEventMouseMotion mouseMotion && Input.MouseMode == Input.MouseModeEnum.Captured) if (@event is InputEventMouseMotion mouseMotion && Input.MouseMode == Input.MouseModeEnum.Captured)
{ {
Vector3 camRot = GetNode<Marker3D>("camera_center").RotationDegrees; camRot.y -= mouseMotion.Relative.x * camSensitivity;
camRot.y -= mouseMotion.Relative.x * mouseSensitivity; camRot.x -= mouseMotion.Relative.y * camSensitivity;
camRot.x -= mouseMotion.Relative.y * mouseSensitivity;
camRot.x = Mathf.Clamp(camRot.x, minMousePitch, maxMousePitch); //prevents camera from going endlessly around the player
GetNode<Marker3D>("camera_center").RotationDegrees = camRot;
} }
camRot.x = Mathf.Clamp(camRot.x, minCamPitch, maxCamPitch); //prevents camera from going endlessly around the player
GetNode<Marker3D>("camera_center").RotationDegrees = camRot;
} }
} }

View File

@@ -4,17 +4,16 @@ using System;
public partial class window : Node public partial class window : Node
{ {
public override void _Ready() public override void _Ready()
{ {
ProjectSettings.SetSetting("physics/common/physics_ticks_per_second", Performance.GetMonitor(Performance.Monitor.TimeFps)); OS.Alert("Make sure that you either capture your mouse or play with a gamepad. Jump with space or bottom gamepad face button. Remove this message in window.cs - vaporvee.com","Information");
} }
public override void _Process(double delta) public override void _Process(double delta)
{ {
if (Input.IsActionJustPressed("fullscreen")) if (Input.IsActionJustPressed("fullscreen"))
{ {
if (DisplayServer.WindowGetMode() == DisplayServer.WindowMode.Fullscreen) if (DisplayServer.WindowGetMode() == DisplayServer.WindowMode.Fullscreen)
DisplayServer.WindowSetMode(DisplayServer.WindowMode.Windowed); DisplayServer.WindowSetMode(DisplayServer.WindowMode.Windowed);
else DisplayServer.WindowSetMode(DisplayServer.WindowMode.Fullscreen); else DisplayServer.WindowSetMode(DisplayServer.WindowMode.Fullscreen);
} }
} }
} }