basic camera movement
This commit is contained in:
parent
aa7386ab2a
commit
170916456e
14 changed files with 1073 additions and 6 deletions
BIN
addons/Free fly camera/Assets/icon.png
Normal file
BIN
addons/Free fly camera/Assets/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1 KiB |
34
addons/Free fly camera/Assets/icon.png.import
Normal file
34
addons/Free fly camera/Assets/icon.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cphgsibvdxlhx"
|
||||
path="res://.godot/imported/icon.png-b04047a434905672807d9eea736bf3b2.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Free fly camera/Assets/icon.png"
|
||||
dest_files=["res://.godot/imported/icon.png-b04047a434905672807d9eea736bf3b2.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
70
addons/Free fly camera/README.md
Normal file
70
addons/Free fly camera/README.md
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
# Freefly Camera Script for Godot
|
||||
|
||||
This is a versatile free-fly camera script for Godot, designed to handle 3D character movement with smooth camera controls. It features adjustable movement settings, mouse sensitivity, sprinting, head rotation clamping, and more. This script is perfect for exploring 3D environments or any other project that requires a free-form camera perspective.
|
||||
|
||||
## Features
|
||||
|
||||
- **Movement Controls**: Move in 3D space with configurable movement speed and sprinting.
|
||||
- **Mouse Look**: Control the camera's rotation with mouse input, with optional acceleration and clamping.
|
||||
- **Collision**: Optionally enable/disable collision detection.
|
||||
- **Customizable Key Bindings**: Configure movement keys, sprinting, and escape for toggling mouse capture.
|
||||
- **Head Rotation Clamping**: Option to limit vertical camera rotation for more control.
|
||||
- **Camera Node**: Easily attach the camera to a character node.
|
||||
- **Advanced Settings**: Customize settings like whether updates should occur on physics ticks.
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Prerequisites
|
||||
- Godot 4.x (tested with Godot 4.3)
|
||||
- A 3D scene with a `CharacterBody3D` node
|
||||
|
||||
### Installation
|
||||
|
||||
1. Clone or download this repository to your Godot project folder.
|
||||
2. In your Godot project, create a new **CharacterBody3D** node (or use an existing one).
|
||||
3. Attach this script to the **CharacterBody3D** node.
|
||||
4. Assign a **Camera3D** node to the `camera` variable in the Inspector.
|
||||
5. Adjust the settings in the Inspector to fit your needs.
|
||||
|
||||
### Key Bindings
|
||||
|
||||
You can modify the default key bindings in the Inspector for the following actions:
|
||||
|
||||
- **Movement**:
|
||||
- Forward: `W`
|
||||
- Backward: `S`
|
||||
- Left: `A`
|
||||
- Right: `D`
|
||||
- Up: `Space`
|
||||
- Down: `Ctrl`
|
||||
|
||||
- **Sprint**: `Shift`
|
||||
- **Escape**: Toggle mouse capture
|
||||
|
||||
### Customization
|
||||
|
||||
- `movement_speed`: Controls the speed of movement.
|
||||
- `sprint_multiplier`: Adjusts how much faster you move when sprinting.
|
||||
- `MOUSE_SENS`: Adjusts mouse sensitivity.
|
||||
- `MOUSE_ACCEL`: Defines the acceleration factor for the mouse.
|
||||
- `CLAMP_HEAD_ROTATION_MIN` and `CLAMP_HEAD_ROTATION_MAX`: Set the min/max angles for vertical camera rotation.
|
||||
- `UPDATE_ON_PHYSICS`: Determines whether the input is processed during the physics step.
|
||||
|
||||
### Controls
|
||||
|
||||
- **W/A/S/D**: Move the camera around.
|
||||
- **Mouse**: Look around (with optional head rotation clamping).
|
||||
- **Shift**: Sprint.
|
||||
- **Escape**: Toggle mouse capture.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the **GPL v3.0** License. See the [LICENSE](LICENSE) file for details.
|
||||
|
||||
## Attribution
|
||||
|
||||
Part of the camera code in this project is derived from the **Basic FPS Player Godot 4.0** project by [sammburr](https://github.com/sammburr/). You can find the original project [here](https://github.com/sammburr/Basic-FPS-Player-GODOT-4.0). Thank you!
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are welcome! If you find bugs or have suggestions, feel free to open an issue or submit a pull request.
|
||||
143
addons/Free fly camera/Src/free_fly_startup.gd
Normal file
143
addons/Free fly camera/Src/free_fly_startup.gd
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
extends CharacterBody3D
|
||||
|
||||
# Movement Settings
|
||||
@export_subgroup("Movement settings")
|
||||
@export var movement_speed : float = 10.0 # Default movement speed
|
||||
@export var sprint_multiplier: float = 2.0 # Sprint speed multiplier
|
||||
|
||||
# Key Bindings
|
||||
@export_subgroup("Movement keybinds")
|
||||
@export var KEY_FORWARD: String = "move_forward"
|
||||
@export var KEY_BACKWARD: String = "move_backward"
|
||||
@export var KEY_LEFT: String = "move_left"
|
||||
@export var KEY_RIGHT: String = "move_right"
|
||||
@export var KEY_UP: String = "move_up"
|
||||
@export var KEY_DOWN: String = "move_down"
|
||||
@export var KEY_SPRINT: String = "sprint"
|
||||
|
||||
# Mouse Settings
|
||||
@export_subgroup("Mouse")
|
||||
@export var MOUSE_ACCEL_STATE := true # Enable mouse acceleration
|
||||
@export var MOUSE_SENS := 0.005 # Mouse sensitivity
|
||||
@export var MOUSE_ACCEL := 50 # Mouse acceleration factor
|
||||
|
||||
# Head Rotation Clamping
|
||||
@export_subgroup("Clamp Head Rotation")
|
||||
@export var CLAMP_HEAD_ROTATION := true # Enable head rotation clamping
|
||||
@export var CLAMP_HEAD_ROTATION_MIN := -90.0 # Min head rotation
|
||||
@export var CLAMP_HEAD_ROTATION_MAX := 90.0 # Max head rotation
|
||||
|
||||
# Camera Node
|
||||
@export_subgroup("Camera node")
|
||||
@export var camera: Camera3D # Camera attached to the character
|
||||
|
||||
# Collision Settings (Optional)
|
||||
@export_subgroup("Collision (Optional)")
|
||||
@export var collision_state := true # Enable or disable collision
|
||||
@export var collision: CollisionShape3D # Collision shape for the character
|
||||
|
||||
# Advanced Settings
|
||||
@export_category("Advanced")
|
||||
@export var UPDATE_ON_PHYSICS := true # Should the update happen on physics ticks?
|
||||
@export var KEY_ESCAPE: String = "KEY_ESCAPE" # Escape key for toggling mouse capture
|
||||
|
||||
# Internal variables for rotation and mouse capture
|
||||
var rotation_target_player : float
|
||||
var rotation_target_head : float
|
||||
var mouse_captured: bool = true
|
||||
|
||||
# Called when the node enters the scene tree for the first time
|
||||
func _ready():
|
||||
# Toggle collision state if set
|
||||
if collision != null:
|
||||
collision.disabled = !collision_state
|
||||
|
||||
# If no camera is assigned, create a new one and add it to the node
|
||||
if camera == null:
|
||||
camera = Camera3D.new()
|
||||
add_child(camera)
|
||||
|
||||
# Capture the mouse at the start
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||
|
||||
# Process the input every frame if not using physics
|
||||
func _process(delta: float) -> void:
|
||||
if !UPDATE_ON_PHYSICS:
|
||||
handle_input() # Handle player input
|
||||
rotate_player(delta) # Apply player and camera rotation
|
||||
|
||||
# Process input and rotation on physics ticks
|
||||
func _physics_process(delta: float) -> void:
|
||||
if UPDATE_ON_PHYSICS:
|
||||
handle_input()
|
||||
rotate_player(delta)
|
||||
|
||||
# Handle player movement input and apply to the character
|
||||
func handle_input():
|
||||
var move_direction = Vector3.ZERO # Initial movement direction is zero
|
||||
|
||||
# Toggle mouse capture when the escape key is pressed
|
||||
if Input.is_action_just_pressed(KEY_ESCAPE):
|
||||
mouse_captured = not mouse_captured
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED if mouse_captured else Input.MOUSE_MODE_VISIBLE
|
||||
|
||||
if mouse_captured:
|
||||
# Movement input for each direction
|
||||
if Input.is_action_pressed(KEY_FORWARD):
|
||||
move_direction.z += 1
|
||||
if Input.is_action_pressed(KEY_BACKWARD):
|
||||
move_direction.z -= 1
|
||||
if Input.is_action_pressed(KEY_LEFT):
|
||||
move_direction.x -= 1
|
||||
if Input.is_action_pressed(KEY_RIGHT):
|
||||
move_direction.x += 1
|
||||
if Input.is_action_pressed(KEY_UP):
|
||||
move_direction.y += 1
|
||||
if Input.is_action_pressed(KEY_DOWN):
|
||||
move_direction.y -= 1
|
||||
|
||||
# Normalize the movement vector to ensure consistent speed
|
||||
move_direction = move_direction.normalized()
|
||||
|
||||
# Get the direction relative to the camera orientation
|
||||
var forward = -camera.global_transform.basis.z
|
||||
var right = camera.global_transform.basis.x
|
||||
var up = camera.global_transform.basis.y
|
||||
|
||||
# Sprinting multiplier if sprint key is pressed
|
||||
var speed_mod = sprint_multiplier if Input.is_action_pressed(KEY_SPRINT) else 1.0
|
||||
velocity = (forward * move_direction.z + right * move_direction.x + up * move_direction.y) * movement_speed * speed_mod
|
||||
|
||||
# Move the character
|
||||
move_and_slide()
|
||||
|
||||
# Capture mouse motion input and update rotations
|
||||
func _input(event):
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
|
||||
# Process mouse motion when the mouse is captured
|
||||
if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
|
||||
set_rotation_target(event.relative)
|
||||
|
||||
# Update the target rotations for the player and camera based on mouse motion
|
||||
func set_rotation_target(mouse_motion: Vector2):
|
||||
# Update player rotation based on mouse X movement
|
||||
rotation_target_player += -mouse_motion.x * MOUSE_SENS
|
||||
# Update head rotation based on mouse Y movement
|
||||
rotation_target_head += -mouse_motion.y * MOUSE_SENS
|
||||
|
||||
# Clamp the head rotation if enabled
|
||||
if CLAMP_HEAD_ROTATION:
|
||||
rotation_target_head = clamp(rotation_target_head, deg_to_rad(CLAMP_HEAD_ROTATION_MIN), deg_to_rad(CLAMP_HEAD_ROTATION_MAX))
|
||||
|
||||
# Rotate the player and camera smoothly based on target rotation
|
||||
func rotate_player(delta):
|
||||
if MOUSE_ACCEL_STATE:
|
||||
# Apply spherical interpolation (slerp) for smooth rotation
|
||||
quaternion = quaternion.slerp(Quaternion(Vector3.UP, rotation_target_player), MOUSE_ACCEL * delta)
|
||||
camera.quaternion = camera.quaternion.slerp(Quaternion(Vector3.RIGHT, rotation_target_head), MOUSE_ACCEL * delta)
|
||||
else:
|
||||
# If mouse acceleration is off, directly set to target rotation
|
||||
quaternion = Quaternion(Vector3.UP, rotation_target_player)
|
||||
camera.quaternion = Quaternion(Vector3.RIGHT, rotation_target_head)
|
||||
1
addons/Free fly camera/Src/free_fly_startup.gd.uid
Normal file
1
addons/Free fly camera/Src/free_fly_startup.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://c3tuul2bry2d3
|
||||
8
addons/Free fly camera/free_fly_camera.gd
Normal file
8
addons/Free fly camera/free_fly_camera.gd
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
func _enter_tree():
|
||||
add_custom_type("Free fly camera", "CharacterBody3D", preload("Src/free_fly_startup.gd"), preload("Assets/icon.png"))
|
||||
|
||||
func _exit_tree():
|
||||
remove_custom_type("Free fly camera")
|
||||
1
addons/Free fly camera/free_fly_camera.gd.uid
Normal file
1
addons/Free fly camera/free_fly_camera.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://5vj88r3lnd6k
|
||||
BIN
addons/Free fly camera/icon.png
Normal file
BIN
addons/Free fly camera/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1 KiB |
34
addons/Free fly camera/icon.png.import
Normal file
34
addons/Free fly camera/icon.png.import
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cffkul203p7mk"
|
||||
path="res://.godot/imported/icon.png-39dbe21aa156283e14ed29482797b196.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://addons/Free fly camera/icon.png"
|
||||
dest_files=["res://.godot/imported/icon.png-39dbe21aa156283e14ed29482797b196.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
10
addons/Free fly camera/plugin.cfg
Normal file
10
addons/Free fly camera/plugin.cfg
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[plugin]
|
||||
|
||||
name="Free fly camera"
|
||||
description="Adds the \"Free fly camera\" node.
|
||||
Currently version V1.0.0, features include:
|
||||
- Basic movement
|
||||
- Mouse acceleration"
|
||||
author="highlife"
|
||||
version="V1.0.0"
|
||||
script="free_fly_camera.gd"
|
||||
Loading…
Add table
Add a link
Reference in a new issue