Add freecam and add basic tools and references
This commit is contained in:
145
splunk/addons/freecam_3D/freecam.gd
Normal file
145
splunk/addons/freecam_3D/freecam.gd
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
extends Camera3D
|
||||||
|
|
||||||
|
## Camera with flying script attached to it.
|
||||||
|
class_name Freecam3D
|
||||||
|
|
||||||
|
##
|
||||||
|
## Camera with toggleable freecam mode for prototyping when creating levels, shaders, lighting, etc.
|
||||||
|
##
|
||||||
|
## Usage: Run your game, press <TAB> and fly around freely. Uses Minecraft-like controls.
|
||||||
|
##
|
||||||
|
|
||||||
|
## Customize your own toggle key to avoid collisions with your current mappings.
|
||||||
|
@export var toggle_key: Key = KEY_TAB
|
||||||
|
## Speed up / down by scrolling the mouse whell down / up
|
||||||
|
@export var invert_speed_controls: bool = false
|
||||||
|
|
||||||
|
@export var overlay_text: bool = true
|
||||||
|
|
||||||
|
## Pivot node for camera looking around
|
||||||
|
@onready var pivot := Node3D.new()
|
||||||
|
## Main parent for camera overlay.
|
||||||
|
@onready var screen_overlay := VBoxContainer.new()
|
||||||
|
## Container for the chat-like event log.
|
||||||
|
@onready var event_log := VBoxContainer.new()
|
||||||
|
|
||||||
|
const MAX_SPEED := 4
|
||||||
|
const MIN_SPEED := 0.1
|
||||||
|
const ACCELERATION := 0.1
|
||||||
|
const MOUSE_SENSITIVITY := 0.002
|
||||||
|
|
||||||
|
## Whether or not the camera can move.
|
||||||
|
var movement_active := false:
|
||||||
|
set(val):
|
||||||
|
movement_active = val
|
||||||
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED if movement_active else Input.MOUSE_MODE_VISIBLE)
|
||||||
|
display_message("[Movement ON]" if movement_active else "[Movement OFF]")
|
||||||
|
|
||||||
|
## The current maximum speed. Lower or higher it by scrolling the mouse wheel.
|
||||||
|
var target_speed := MIN_SPEED
|
||||||
|
## Movement velocity.
|
||||||
|
var velocity := Vector3.ZERO
|
||||||
|
|
||||||
|
|
||||||
|
## Sets up pivot and UI overlay elements.
|
||||||
|
func _setup_nodes() -> void:
|
||||||
|
self.add_sibling(pivot)
|
||||||
|
pivot.position = position
|
||||||
|
pivot.rotation = rotation
|
||||||
|
pivot.name = "FreecamPivot"
|
||||||
|
self.reparent(pivot)
|
||||||
|
self.position = Vector3.ZERO
|
||||||
|
self.rotation = Vector3.ZERO
|
||||||
|
# UI stuff
|
||||||
|
screen_overlay.add_theme_constant_override("Separation", 8)
|
||||||
|
self.add_child(screen_overlay)
|
||||||
|
screen_overlay.add_child(_make_label("Debug Camera"))
|
||||||
|
screen_overlay.add_spacer(false)
|
||||||
|
|
||||||
|
screen_overlay.add_child(event_log)
|
||||||
|
screen_overlay.visible = overlay_text
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
_setup_nodes.call_deferred()
|
||||||
|
_add_keybindings()
|
||||||
|
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
|
||||||
|
if Input.is_action_just_released("__debug_camera_toggle"):
|
||||||
|
movement_active = not movement_active
|
||||||
|
|
||||||
|
if movement_active:
|
||||||
|
var dir = Vector3.ZERO
|
||||||
|
if Input.is_action_pressed("__debug_camera_forward"): dir.z -= 1
|
||||||
|
if Input.is_action_pressed("__debug_camera_back"): dir.z += 1
|
||||||
|
if Input.is_action_pressed("__debug_camera_left"): dir.x -= 1
|
||||||
|
if Input.is_action_pressed("__debug_camera_right"): dir.x += 1
|
||||||
|
if Input.is_action_pressed("__debug_camera_up"): dir.y += 1
|
||||||
|
if Input.is_action_pressed("__debug_camera_down"): dir.y -= 1
|
||||||
|
|
||||||
|
dir = dir.normalized()
|
||||||
|
dir = dir.rotated(Vector3.UP, pivot.rotation.y)
|
||||||
|
|
||||||
|
velocity = lerp(velocity, dir * target_speed, ACCELERATION)
|
||||||
|
pivot.position += velocity
|
||||||
|
|
||||||
|
|
||||||
|
func _input(event: InputEvent) -> void:
|
||||||
|
if movement_active:
|
||||||
|
# Turn around
|
||||||
|
if event is InputEventMouseMotion:
|
||||||
|
pivot.rotate_y(-event.relative.x * MOUSE_SENSITIVITY)
|
||||||
|
rotate_x(-event.relative.y * MOUSE_SENSITIVITY)
|
||||||
|
rotation.x = clamp(rotation.x, -PI/2, PI/2)
|
||||||
|
|
||||||
|
var speed_up = func():
|
||||||
|
target_speed = clamp(target_speed + 0.15, MIN_SPEED, MAX_SPEED)
|
||||||
|
display_message("[Speed up] " + str(target_speed))
|
||||||
|
|
||||||
|
var slow_down = func():
|
||||||
|
target_speed = clamp(target_speed - 0.15, MIN_SPEED, MAX_SPEED)
|
||||||
|
display_message("[Slow down] " + str(target_speed))
|
||||||
|
|
||||||
|
# Speed up and down with the mouse wheel
|
||||||
|
if event is InputEventMouseButton:
|
||||||
|
if event.button_index == MOUSE_BUTTON_WHEEL_UP and event.pressed:
|
||||||
|
slow_down.call() if invert_speed_controls else speed_up.call()
|
||||||
|
|
||||||
|
if event.button_index == MOUSE_BUTTON_WHEEL_DOWN and event.pressed:
|
||||||
|
speed_up.call() if invert_speed_controls else slow_down.call()
|
||||||
|
|
||||||
|
|
||||||
|
## Pushes new message label into "chat" and removes the old ones if necessary
|
||||||
|
func display_message(text: String) -> void:
|
||||||
|
while event_log.get_child_count() >= 3:
|
||||||
|
event_log.remove_child(event_log.get_child(0))
|
||||||
|
|
||||||
|
event_log.add_child(_make_label(text))
|
||||||
|
|
||||||
|
|
||||||
|
func _make_label(text: String) -> Label:
|
||||||
|
var l = Label.new()
|
||||||
|
l.text = text
|
||||||
|
return l
|
||||||
|
|
||||||
|
|
||||||
|
func _add_keybindings() -> void:
|
||||||
|
var actions = InputMap.get_actions()
|
||||||
|
if "__debug_camera_forward" not in actions: _add_key_input_action("__debug_camera_forward", KEY_W)
|
||||||
|
if "__debug_camera_back" not in actions: _add_key_input_action("__debug_camera_back", KEY_S)
|
||||||
|
if "__debug_camera_left" not in actions: _add_key_input_action("__debug_camera_left", KEY_A)
|
||||||
|
if "__debug_camera_right" not in actions: _add_key_input_action("__debug_camera_right", KEY_D)
|
||||||
|
if "__debug_camera_up" not in actions: _add_key_input_action("__debug_camera_up", KEY_SPACE)
|
||||||
|
if "__debug_camera_down" not in actions: _add_key_input_action("__debug_camera_down", KEY_SHIFT)
|
||||||
|
if "__debug_camera_toggle" not in actions: _add_key_input_action("__debug_camera_toggle", toggle_key)
|
||||||
|
|
||||||
|
|
||||||
|
func _add_key_input_action(name: String, key: Key) -> void:
|
||||||
|
var ev = InputEventKey.new()
|
||||||
|
ev.physical_keycode = key
|
||||||
|
|
||||||
|
InputMap.add_action(name)
|
||||||
|
InputMap.action_add_event(name, ev)
|
||||||
|
|
||||||
1
splunk/addons/freecam_3D/freecam.gd.uid
Normal file
1
splunk/addons/freecam_3D/freecam.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://8vyuhyx0xogt
|
||||||
BIN
splunk/addons/freecam_3D/mc-camera2.png
Normal file
BIN
splunk/addons/freecam_3D/mc-camera2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 406 B |
34
splunk/addons/freecam_3D/mc-camera2.png.import
Normal file
34
splunk/addons/freecam_3D/mc-camera2.png.import
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://c4kitg6s5bcqu"
|
||||||
|
path="res://.godot/imported/mc-camera2.png-fe60f555c5ea92c0796267cd654ef834.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/freecam_3D/mc-camera2.png"
|
||||||
|
dest_files=["res://.godot/imported/mc-camera2.png-fe60f555c5ea92c0796267cd654ef834.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
|
||||||
7
splunk/addons/freecam_3D/plugin.cfg
Normal file
7
splunk/addons/freecam_3D/plugin.cfg
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[plugin]
|
||||||
|
|
||||||
|
name="Freecam3D"
|
||||||
|
description="A flying freecam with Minecraft-like controls."
|
||||||
|
author="Vojtech Struhar"
|
||||||
|
version="1.2.0"
|
||||||
|
script="plugin.gd"
|
||||||
20
splunk/addons/freecam_3D/plugin.gd
Normal file
20
splunk/addons/freecam_3D/plugin.gd
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
@tool
|
||||||
|
extends EditorPlugin
|
||||||
|
|
||||||
|
##
|
||||||
|
## Bootstraps the Freecam3D node.
|
||||||
|
##
|
||||||
|
|
||||||
|
func _enter_tree() -> void:
|
||||||
|
print("[Freecam3D Plugin] Loaded.")
|
||||||
|
|
||||||
|
add_custom_type(
|
||||||
|
"Freecam3D",
|
||||||
|
"Camera3D",
|
||||||
|
preload("freecam.gd"),
|
||||||
|
preload("mc-camera2.png"))
|
||||||
|
|
||||||
|
|
||||||
|
func _exit_tree() -> void:
|
||||||
|
remove_custom_type("Freecam3D")
|
||||||
|
|
||||||
1
splunk/addons/freecam_3D/plugin.gd.uid
Normal file
1
splunk/addons/freecam_3D/plugin.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://1c16mfvgbate
|
||||||
32
splunk/levels/lobby-scene/lobby.tscn
Normal file
32
splunk/levels/lobby-scene/lobby.tscn
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
[gd_scene load_steps=6 format=3 uid="uid://bj52j4ew2lfr6"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://5vggmy1srgxb" path="res://tools/human-height-reference.tscn" id="1_yyu2g"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://daq1prwl8aaia" path="res://tools/debug.tscn" id="2_72fkp"]
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id="Environment_72fkp"]
|
||||||
|
background_mode = 2
|
||||||
|
|
||||||
|
[sub_resource type="PlaneMesh" id="PlaneMesh_fnh6i"]
|
||||||
|
size = Vector2(20, 20)
|
||||||
|
|
||||||
|
[sub_resource type="BoxShape3D" id="BoxShape3D_yyu2g"]
|
||||||
|
size = Vector3(20, 0.4, 20)
|
||||||
|
|
||||||
|
[node name="Lobby" type="Node3D"]
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
environment = SubResource("Environment_72fkp")
|
||||||
|
|
||||||
|
[node name="TempFloor" type="StaticBody3D" parent="."]
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="TempFloor"]
|
||||||
|
mesh = SubResource("PlaneMesh_fnh6i")
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="TempFloor"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.2, 0)
|
||||||
|
shape = SubResource("BoxShape3D_yyu2g")
|
||||||
|
|
||||||
|
[node name="Human-height-reference" parent="." instance=ExtResource("1_yyu2g")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.33741, 0.953, -5.00694)
|
||||||
|
|
||||||
|
[node name="Debug" parent="." instance=ExtResource("2_72fkp")]
|
||||||
@@ -11,15 +11,21 @@ config_version=5
|
|||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="Splunk"
|
config/name="Splunk"
|
||||||
|
run/main_scene="uid://bj52j4ew2lfr6"
|
||||||
config/features=PackedStringArray("4.4", "Forward Plus")
|
config/features=PackedStringArray("4.4", "Forward Plus")
|
||||||
config/icon="res://icon.svg"
|
config/icon="res://icon.svg"
|
||||||
|
|
||||||
|
[editor_plugins]
|
||||||
|
|
||||||
|
enabled=PackedStringArray("res://addons/freecam_3D/plugin.cfg")
|
||||||
|
|
||||||
[file_customization]
|
[file_customization]
|
||||||
|
|
||||||
folder_colors={
|
folder_colors={
|
||||||
"res://items/": "yellow",
|
"res://items/": "yellow",
|
||||||
"res://levels/": "green",
|
"res://levels/": "green",
|
||||||
"res://player/": "purple"
|
"res://player/": "purple",
|
||||||
|
"res://tools/": "gray"
|
||||||
}
|
}
|
||||||
|
|
||||||
[physics]
|
[physics]
|
||||||
|
|||||||
10
splunk/tools/debug.tscn
Normal file
10
splunk/tools/debug.tscn
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://daq1prwl8aaia"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://8vyuhyx0xogt" path="res://addons/freecam_3D/freecam.gd" id="1_m8a7k"]
|
||||||
|
|
||||||
|
[node name="Debug" type="Node3D"]
|
||||||
|
|
||||||
|
[node name="Freecam3D" type="Camera3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 5, 0)
|
||||||
|
script = ExtResource("1_m8a7k")
|
||||||
|
metadata/_custom_type_script = "uid://8vyuhyx0xogt"
|
||||||
15
splunk/tools/human-height-reference.tscn
Normal file
15
splunk/tools/human-height-reference.tscn
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[gd_scene load_steps=3 format=3 uid="uid://5vggmy1srgxb"]
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_q0jr2"]
|
||||||
|
albedo_color = Color(0.901217, 0.295359, 0.23356, 1)
|
||||||
|
|
||||||
|
[sub_resource type="CylinderMesh" id="CylinderMesh_q0jr2"]
|
||||||
|
material = SubResource("StandardMaterial3D_q0jr2")
|
||||||
|
top_radius = 0.35
|
||||||
|
bottom_radius = 0.35
|
||||||
|
height = 1.905
|
||||||
|
|
||||||
|
[node name="Human-height-reference" type="Node3D"]
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||||
|
mesh = SubResource("CylinderMesh_q0jr2")
|
||||||
Reference in New Issue
Block a user