Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve snap turning logic #229

Merged
merged 1 commit into from
Oct 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions VERSIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Improved pointer demo supporting left hand with switching
- Enhanced pointer laser visibility options for colliding with targets.
- Implement poke feature (finger interaction)
- Improvements to snap turning

# 3.0.0
- Included demo project with test scenes to evaluate features
Expand Down
2 changes: 1 addition & 1 deletion addons/godot-xr-tools/assets/player_body.gd
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ func override_player_height(key, value: float = -1.0):
func _update_body_under_camera():
# Calculate the player height based on the camera position in the origin and the calibration
var player_height: float = clamp(
camera_node.transform.origin.y + player_head_height + player_height_offset,
camera_node.transform.origin.y + player_head_height + player_height_offset + XRToolsUserSettings.player_height_adjust,
player_height_min * ARVRServer.world_scale,
player_height_max * ARVRServer.world_scale)

Expand Down
25 changes: 21 additions & 4 deletions addons/godot-xr-tools/functions/movement_turn.gd
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ extends XRToolsMovementProvider
## Movement provider order
export var order : int = 5

## Use smooth rotation (may cause motion sickness)
export var smooth_rotation : bool = false
## Movement mode
enum TurnMode {
DEFAULT,
SNAP,
SMOOTH
}

export (TurnMode) var turn_mode = TurnMode.DEFAULT

## Smooth turn speed in radians per second
export var smooth_turn_speed : float = 2.0
Expand All @@ -38,22 +44,33 @@ var _turn_step : float = 0.0
# Controller node
onready var _controller : ARVRController = get_parent()

func _snap_turning():
if turn_mode == TurnMode.SNAP:
return true
elif turn_mode == TurnMode.SMOOTH:
return false
else:
return XRToolsUserSettings.snap_turning

# Perform jump movement
func physics_movement(delta: float, player_body: XRToolsPlayerBody, _disabled: bool):
# Skip if the controller isn't active
if !_controller.get_is_active():
return

var deadzone = 0.1
if _snap_turning():
deadzone = XRTools.get_snap_turning_deadzone()

# Read the left/right joystick axis
var left_right := _controller.get_joystick_axis(XRTools.Axis.VR_PRIMARY_X_AXIS)
if abs(left_right) <= 0.1:
if abs(left_right) <= deadzone:
# Not turning
_turn_step = 0.0
return

# Handle smooth rotation
if smooth_rotation:
if !_snap_turning():
_rotate_player(player_body, smooth_turn_speed * delta * left_right)
return

Expand Down
71 changes: 66 additions & 5 deletions addons/godot-xr-tools/plugin.gd
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ enum Buttons {

static func get_grip_threshold() -> float:
# can return null which is not a float, so don't type this!
var threshold = ProjectSettings.get_setting("godot_xr_tools/input/grip_threshold")
var threshold = 0.7

if ProjectSettings.has_setting("godot_xr_tools/input/grip_threshold"):
threshold = ProjectSettings.get_setting("godot_xr_tools/input/grip_threshold")

if threshold == null:
# plugin disabled or setting not saved, return our default.
threshold = 0.7
if !(threshold >= 0.2 and threshold <= 0.8):
# out of bounds? reset to default
threshold = 0.7

return threshold

static func set_grip_threshold(p_threshold : float) -> void:
Expand All @@ -55,6 +55,61 @@ static func set_grip_threshold(p_threshold : float) -> void:

ProjectSettings.set_setting("godot_xr_tools/input/grip_threshold", p_threshold)


static func get_snap_turning_deadzone() -> float:
# can return null which is not a float, so don't type this!
var deadzone = 0.25

if ProjectSettings.has_setting("godot_xr_tools/input/snap_turning_deadzone"):
deadzone = ProjectSettings.get_setting("godot_xr_tools/input/snap_turning_deadzone")

if !(deadzone >= 0.0 and deadzone <= 0.5):
# out of bounds? reset to default
deadzone = 0.25

return deadzone

static func set_snap_turning_deadzone(p_deadzone : float) -> void:
if !(p_deadzone >= 0.0 and p_deadzone <= 0.5):
print("Deadzone out of bounds")
return

ProjectSettings.set_setting("godot_xr_tools/input/snap_turning_deadzone", p_deadzone)


static func get_default_snap_turning() -> bool:
var default = true

if ProjectSettings.has_setting("godot_xr_tools/input/default_snap_turning"):
default = ProjectSettings.get_setting("godot_xr_tools/input/default_snap_turning")

# default may not be bool, so JIC
return default == true

static func set_default_snap_turning(p_default : bool) -> void:
ProjectSettings.set_setting("godot_xr_tools/input/default_snap_turning", p_default)


static func get_player_standard_height() -> float:
var standard_height = 1.85

if ProjectSettings.has_setting("godot_xr_tools/player/standard_height"):
standard_height = ProjectSettings.get_setting("godot_xr_tools/player/standard_height")

if !(standard_height >= 1.0 and standard_height <= 2.5):
# out of bounds? reset to default
standard_height = 1.85

return standard_height

static func set_player_standard_height(p_height : float) -> void:
if !(p_height >= 1.0 and p_height <= 2.5):
print("Standard height out of bounds")
return

ProjectSettings.set_setting("godot_xr_tools/player/standard_height", p_height)


func _define_project_setting(p_name : String, p_type : int, p_hint : int = PROPERTY_HINT_NONE , p_hint_string : String = "", p_default_val = "") -> void:
# p_default_val can be any type!!

Expand All @@ -77,7 +132,13 @@ func _enter_tree():

# provide meta data for our project settings
_define_project_setting("godot_xr_tools/input/grip_threshold", TYPE_REAL, PROPERTY_HINT_RANGE, "0.2,0.8,0.05", 0.7)
_define_project_setting("godot_xr_tools/input/snap_turning_deadzone", TYPE_REAL, PROPERTY_HINT_RANGE, "0.0,0.5,0.05", 0.25)
_define_project_setting("godot_xr_tools/input/default_snap_turning", TYPE_BOOL, PROPERTY_HINT_NONE, "", true)

_define_project_setting("godot_xr_tools/player/standard_height", TYPE_REAL, PROPERTY_HINT_RANGE, "1.0,2.5,0.1", 1.85)

# register our autoload user settings object
add_autoload_singleton("XRToolsUserSettings", "res://addons/godot-xr-tools/user_settings/user_settings.gd")

func _exit_tree():
# our plugin is turned off
Expand Down
63 changes: 63 additions & 0 deletions addons/godot-xr-tools/user_settings/user_settings.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
extends Node

# our settings
export var snap_turning : bool = true
export var player_height_adjust : float = 0.0 setget set_player_height_adjust

var settings_file_name = "user://xtools_user_settings.json"

func set_player_height_adjust(new_value : float) -> void:
player_height_adjust = clamp(new_value, -1.0, 1.0)


func reset_to_defaults():
# Reset to defaults
snap_turning = XRTools.get_default_snap_turning()
player_height_adjust = 0.0


func _load():
# First reset our values
reset_to_defaults()

# Now attempt to load our settings file
var file = File.new()
if !file.file_exists(settings_file_name):
return

if file.open(settings_file_name, File.READ):
var text = file.get_as_text()
file.close()

var data : Dictionary = parse_json(text)

# Parse our input settings
if data.has("input"):
var input : Dictionary = data["input"]
if input.has("default_snap_turning"):
snap_turning = input["default_snap_turning"]

# Parse our player settings
if data.has("player"):
var player : Dictionary = data["player"]
if player.has("height_adjust"):
player_height_adjust = player["height_adjust"]

func save():
var data = {
"input" : {
"default_snap_turning" : snap_turning
},
"player" : {
"height_adjust" : player_height_adjust
}
}

var file = File.new()
if file.open(settings_file_name, File.WRITE):
file.store_line(to_json(data))
file.close()

# Called when the node enters the scene tree for the first time.
func _ready():
_load()
54 changes: 54 additions & 0 deletions addons/godot-xr-tools/user_settings/user_settings_ui.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
extends TabContainer

export (NodePath) var camera
export var player_head_height : float = 0.1

func _update():
# Input
$Input/SnapTurning/SnapTurningCB.pressed = XRToolsUserSettings.snap_turning

# Player
$Player/PlayerHeight/PlayerHeightSlider.value = XRToolsUserSettings.player_height_adjust

# Called when the node enters the scene tree for the first time.
func _ready():
if XRToolsUserSettings:
_update()
else:
$Save/Button.disabled = true


func _on_Save_pressed():
if XRToolsUserSettings:
# Save
XRToolsUserSettings.save()


func _on_Reset_pressed():
if XRToolsUserSettings:
XRToolsUserSettings.reset_to_defaults()
_update()

# Input settings changed
func _on_SnapTurningCB_pressed():
XRToolsUserSettings.snap_turning = $Input/SnapTurning/SnapTurningCB.pressed

# Player settings changed
func _on_PlayerHeightSlider_drag_ended(value_changed):
XRToolsUserSettings.player_height_adjust = $Player/PlayerHeight/PlayerHeightSlider.value


func _on_PlayerHeightStandard_pressed():
if !camera:
return

var camera_node = get_node_or_null(camera)
if !camera_node:
return

var base_height = camera_node.transform.origin.y + player_head_height
var height_adjust = XRTools.get_player_standard_height() - base_height
XRToolsUserSettings.player_height_adjust = height_adjust
$Player/PlayerHeight/PlayerHeightSlider.value = XRToolsUserSettings.player_height_adjust


Loading