Skip to content

Commit

Permalink
Merge pull request #3 from Malcolmnixon/character-control-orientation
Browse files Browse the repository at this point in the history
Added support for controller orientation
  • Loading branch information
Malcolmnixon authored Nov 21, 2023
2 parents 1f62a95 + 818abe6 commit fb5c924
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ signal button_released(name : String)
signal movement_changed(state : MovementState)


## Orientation of the controller
enum ControlOrientation {
VERTICAL, ## Vertical - wand pointing forwards
HORIZONTAL ## Horizontal - wand pointnig to the left
}

## Control reference frame
enum ControlReference {
PLAYER, ## Control input relative to player
WORLD ## Control input relative to world
}

## Movement State
enum MovementState {
IDLE, ## Character is idle
Expand All @@ -55,6 +67,12 @@ enum MovementState {
# Controls group
@export_group("Controls", "control_")

## Orientation of the controller
@export var control_orientation : ControlOrientation = ControlOrientation.VERTICAL

## Control reference frame
@export var control_reference : ControlReference = ControlReference.PLAYER

## Primary button
@export var control_primary : String = "trigger_click"

Expand All @@ -79,6 +97,9 @@ var _player : T5ToolsPlayer
# The camera origin
var _origin : T5Origin3D

# The camera
var _camera : T5Camera3D

# Movement state
var _state : MovementState = MovementState.IDLE

Expand All @@ -94,6 +115,7 @@ func _ready():
# Get the player from the character
_player = T5ToolsCharacter.find_instance(self).player
_origin = _player.get_player_origin()
_camera = _player.get_player_camera()

# Subscribe to player wand events
var controller := _player.get_player_wand(0)
Expand Down Expand Up @@ -131,7 +153,7 @@ func _physics_process(delta : float) -> void:
_set_state(MovementState.FALLING)

# Get the input direction and handle the movement/deceleration.
var control_vel := Vector3(_control.x, 0, -_control.y) * movement_speed
var control_vel := _control_to_global(_control) * movement_speed
var direction := control_vel.normalized()

# Face in the desired direction
Expand Down Expand Up @@ -207,3 +229,29 @@ func _on_input_vector2_changed(p_name : String, p_value : Vector2) -> void:
# Handle known joysticks
if p_name == "stick":
_control = p_value


# Convert control input to global vector
func _control_to_global(control : Vector2) -> Vector3:
# Get the oriented vector
var vec : Vector3
match control_orientation:
ControlOrientation.VERTICAL:
vec = Vector3(_control.x, 0.0, -_control.y)
ControlOrientation.HORIZONTAL:
vec = Vector3(-_control.y, 0.0, -_control.x)

# Translate to reference frame
if control_reference == ControlReference.PLAYER:
# Get the frame Z vector (to-player, horizontal, normalized)
var frame_z := (_camera.global_position - global_position).slide(Vector3.UP).normalized()
var frame := Basis(
Vector3.UP.cross(frame_z),
Vector3.UP,
frame_z)

# Apply the reference frame
vec = frame * vec

# Return the vector
return vec
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ signal button_pressed(name : String)
signal button_released(name : String)


## Orientation of the controller
enum ControlOrientation {
VERTICAL, ## Vertical - wand pointing forwards
HORIZONTAL ## Horizontal - wand pointnig to the left
}

## Control reference frame
enum ControlReference {
PLAYER, ## Control input relative to player
WORLD ## Control input relative to world
}


# Character Centering group
@export_group("Centering", "center_")

Expand All @@ -40,6 +53,12 @@ signal button_released(name : String)
# Controls group
@export_group("Controls", "control_")

## Orientation of the controller
@export var control_orientation : ControlOrientation = ControlOrientation.VERTICAL

## Control reference frame
@export var control_reference : ControlReference = ControlReference.PLAYER

## Primary button
@export var control_primary : String = "trigger_click"

Expand All @@ -65,6 +84,9 @@ var _player : T5ToolsPlayer
# The camera origin
var _origin : T5Origin3D

# The camera
var _camera : T5Camera3D

# Control vector
var _control : Vector2

Expand All @@ -77,6 +99,7 @@ func _ready() -> void:
# Get the player from the character
_player = T5ToolsCharacter.find_instance(self).player
_origin = _player.get_player_origin()
_camera = _player.get_player_camera()

# Subscribe to player wand events
var controller := _player.get_player_wand(0)
Expand Down Expand Up @@ -104,7 +127,7 @@ func _physics_process(_delta : float) -> void:
# Apply movement
if on_ground or movement_air_control:
apply_central_force(
Vector3(_control.x, 0.0, -_control.y) * movement_force)
_control_to_global(_control) * movement_force)


# Handle button presses
Expand Down Expand Up @@ -168,3 +191,29 @@ func _is_on_ground() -> bool:

# No valid collisions
return false


# Convert control input to global vector
func _control_to_global(control : Vector2) -> Vector3:
# Get the oriented vector
var vec : Vector3
match control_orientation:
ControlOrientation.VERTICAL:
vec = Vector3(_control.x, 0.0, -_control.y)
ControlOrientation.HORIZONTAL:
vec = Vector3(-_control.y, 0.0, -_control.x)

# Translate to reference frame
if control_reference == ControlReference.PLAYER:
# Get the frame Z vector (to-player, horizontal, normalized)
var frame_z := (_camera.global_position - global_position).slide(Vector3.UP).normalized()
var frame := Basis(
Vector3.UP.cross(frame_z),
Vector3.UP,
frame_z)

# Apply the reference frame
vec = frame * vec

# Return the vector
return vec
1 change: 0 additions & 1 deletion demo/demo3_scene/character/character.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ height = 1.5
collision_layer = 524288
collision_mask = 524291
script = ExtResource("2_28gu4")
movement_air_control = true

[node name="gobot" parent="CharacterBody3D" index="0" instance=ExtResource("2_fy2fw")]

Expand Down

0 comments on commit fb5c924

Please sign in to comment.