From 6df6b9ac2901df26e5f6027ab9ce9d6213b8e3f2 Mon Sep 17 00:00:00 2001 From: Torsten Crass Date: Sat, 12 Aug 2023 14:41:31 +0200 Subject: [PATCH 1/5] Added signal for teleporter (de)activation. --- .../functions/function_teleport.gd | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/addons/godot-xr-tools/functions/function_teleport.gd b/addons/godot-xr-tools/functions/function_teleport.gd index 24d08d5a..10e43df2 100644 --- a/addons/godot-xr-tools/functions/function_teleport.gd +++ b/addons/godot-xr-tools/functions/function_teleport.gd @@ -14,6 +14,13 @@ extends CharacterBody3D ## a teleport function on that controller. +## Signal emitted when the teleporter is activated +signal teleporter_activated() + +## Signal emitted when the teleporter is deactivated +signal teleporter_deactivated() + + # Default teleport collision mask of all const DEFAULT_MASK := 0b1111_1111_1111_1111_1111_1111_1111_1111 @@ -56,7 +63,7 @@ const DEFAULT_MASK := 0b1111_1111_1111_1111_1111_1111_1111_1111 var is_on_floor : bool = true -var is_teleporting : bool = false +var is_teleporting : bool = false: set = set_is_teleporting var can_teleport : bool = true var teleport_rotation : float = 0.0; var floor_normal : Vector3 = Vector3.UP @@ -371,6 +378,16 @@ func set_player_radius(p_radius : float) -> void: _update_player_radius() +# Set is_teleporting property and notify about its changes +func set_is_teleporting(new_value : bool) -> void: + if new_value != is_teleporting: + is_teleporting = new_value + if is_teleporting: + _report_activated() + else: + _report_deactivated() + + # Player height update handler func _update_player_height() -> void: if collision_shape: @@ -390,3 +407,13 @@ func _update_player_radius(): if capsule: capsule.mesh.height = player_height capsule.mesh.radius = player_radius + + +# Report events for teleporter activation +func _report_activated(): + teleporter_activated.emit() + + +# Report events for teleporter deactivation +func _report_deactivated(): + teleporter_deactivated.emit() From 3e1385034a325e58dbb0d37fb2a463b391ca9fdc Mon Sep 17 00:00:00 2001 From: Torsten Crass Date: Sat, 12 Aug 2023 16:24:45 +0200 Subject: [PATCH 2/5] Added signal for teleportation to target location. --- addons/godot-xr-tools/functions/function_teleport.gd | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/addons/godot-xr-tools/functions/function_teleport.gd b/addons/godot-xr-tools/functions/function_teleport.gd index 10e43df2..003c29ff 100644 --- a/addons/godot-xr-tools/functions/function_teleport.gd +++ b/addons/godot-xr-tools/functions/function_teleport.gd @@ -17,6 +17,9 @@ extends CharacterBody3D ## Signal emitted when the teleporter is activated signal teleporter_activated() +## Signal emitted when the player gets teleportet to the teleporter's target location +signal teleported_to(location) + ## Signal emitted when the teleporter is deactivated signal teleporter_deactivated() @@ -328,6 +331,7 @@ func _physics_process(delta): # now move the origin such that the new global user_feet_transform # would be == new_transform origin_node.global_transform = new_transform * user_feet_transform.inverse() + _report_teleported_to(new_transform.origin) # and disable is_teleporting = false; @@ -414,6 +418,11 @@ func _report_activated(): teleporter_activated.emit() +# Report events for teleportation to target location +func _report_teleported_to(location : Vector3) -> void: + teleported_to.emit(location) + + # Report events for teleporter deactivation func _report_deactivated(): teleporter_deactivated.emit() From 469177b914b4373d1a09958a39dcd7d775e037f7 Mon Sep 17 00:00:00 2001 From: Torsten Crass Date: Sat, 12 Aug 2023 22:42:09 +0200 Subject: [PATCH 3/5] Added signal for change in the teleporter's ability to perform teleportation. --- .../functions/function_teleport.gd | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/addons/godot-xr-tools/functions/function_teleport.gd b/addons/godot-xr-tools/functions/function_teleport.gd index 003c29ff..d84db087 100644 --- a/addons/godot-xr-tools/functions/function_teleport.gd +++ b/addons/godot-xr-tools/functions/function_teleport.gd @@ -17,6 +17,9 @@ extends CharacterBody3D ## Signal emitted when the teleporter is activated signal teleporter_activated() +## Signal emitted when the teleporter's ability to perform a teleportation changes +signal can_teleport_changed(can_teleport) + ## Signal emitted when the player gets teleportet to the teleporter's target location signal teleported_to(location) @@ -67,7 +70,7 @@ const DEFAULT_MASK := 0b1111_1111_1111_1111_1111_1111_1111_1111 var is_on_floor : bool = true var is_teleporting : bool = false: set = set_is_teleporting -var can_teleport : bool = true +var can_teleport : bool = true: set = set_can_teleport var teleport_rotation : float = 0.0; var floor_normal : Vector3 = Vector3.UP var last_target_transform : Transform3D = Transform3D() @@ -382,6 +385,12 @@ func set_player_radius(p_radius : float) -> void: _update_player_radius() +func set_can_teleport(new_value : bool) -> void: + if new_value != can_teleport: + can_teleport = new_value + _report_can_teleport_changed(can_teleport) + + # Set is_teleporting property and notify about its changes func set_is_teleporting(new_value : bool) -> void: if new_value != is_teleporting: @@ -418,6 +427,11 @@ func _report_activated(): teleporter_activated.emit() +# Report events for teleportation ability changes +func _report_can_teleport_changed(can_teleport : bool) -> void: + can_teleport_changed.emit(can_teleport) + + # Report events for teleportation to target location func _report_teleported_to(location : Vector3) -> void: teleported_to.emit(location) From 5ed41ea2e0344d0f32ad9e701627fa65c40695e0 Mon Sep 17 00:00:00 2001 From: Torsten Crass Date: Sat, 2 Sep 2023 07:04:33 +0200 Subject: [PATCH 4/5] Added signals for notifying when the teleporter beam hits suitable targets. --- .../functions/function_teleport.gd | 71 ++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/addons/godot-xr-tools/functions/function_teleport.gd b/addons/godot-xr-tools/functions/function_teleport.gd index d84db087..a330d090 100644 --- a/addons/godot-xr-tools/functions/function_teleport.gd +++ b/addons/godot-xr-tools/functions/function_teleport.gd @@ -20,6 +20,15 @@ signal teleporter_activated() ## Signal emitted when the teleporter's ability to perform a teleportation changes signal can_teleport_changed(can_teleport) +# signal emitted when the teleporter beam hits a suitable target +signal teleporter_target_entered(node, at) + +# signal emitted when the teleporter beam moves along a suitable target +signal teleporter_target_moved(node, from, to) + +# signal emitted when the teleporter beam leaves a suitable target +signal teleporter_target_exited(node, at) + ## Signal emitted when the player gets teleportet to the teleporter's target location signal teleported_to(location) @@ -71,6 +80,8 @@ const DEFAULT_MASK := 0b1111_1111_1111_1111_1111_1111_1111_1111 var is_on_floor : bool = true var is_teleporting : bool = false: set = set_is_teleporting var can_teleport : bool = true: set = set_can_teleport +var target_node : Node3D = null +var target_hit_pos : Vector3 var teleport_rotation : float = 0.0; var floor_normal : Vector3 = Vector3.UP var last_target_transform : Transform3D = Transform3D() @@ -261,6 +272,9 @@ func _physics_process(delta): if not valid_teleport_mask & collider_mask: is_on_floor = false + if is_on_floor: + _update_target(intersects["collider"], intersects["position"]) + # we are colliding, find our if we're colliding on a wall or # floor, one we can do, the other nope... cast_length += (collided_at - target_global_origin).length() @@ -334,6 +348,7 @@ func _physics_process(delta): # now move the origin such that the new global user_feet_transform # would be == new_transform origin_node.global_transform = new_transform * user_feet_transform.inverse() + _clear_target() _report_teleported_to(new_transform.origin) # and disable @@ -385,9 +400,13 @@ func set_player_radius(p_radius : float) -> void: _update_player_radius() +# Set property telling whether all conditions for successful teleportation are met func set_can_teleport(new_value : bool) -> void: if new_value != can_teleport: can_teleport = new_value + if not can_teleport: + # Can't teleport => no suitable target + _clear_target() _report_can_teleport_changed(can_teleport) @@ -421,9 +440,27 @@ func _update_player_radius(): capsule.mesh.height = player_height capsule.mesh.radius = player_radius +# Teleporter target doesn't hit something suitable +func _clear_target(): + _update_target(null, Vector3.ZERO) + + +# Teleporter target hit something suitiable change handler +func _update_target(node: Node3D, hit_pos: Vector3) -> void: + if node == target_node: + if (hit_pos != target_hit_pos): + _report_target_moved(target_node, target_hit_pos, hit_pos) + else: + if target_node != null: + _report_target_exited(target_node, target_hit_pos) + if node != null: + _report_target_entered(node, hit_pos) + target_node = node + target_hit_pos = hit_pos + # Report events for teleporter activation -func _report_activated(): +func _report_activated() -> void: teleporter_activated.emit() @@ -432,11 +469,41 @@ func _report_can_teleport_changed(can_teleport : bool) -> void: can_teleport_changed.emit(can_teleport) +# Report events for the teleporter target entering a node +func _report_target_entered(node: Node3D, at: Vector3) -> void: + teleporter_target_entered.emit(node, at) + if is_instance_valid(node): + if node.has_signal("teleporter_target_entered"): + node.emit_signal("teleporter_target_entered", at) + elif node.has_method("teleporter_target_entered"): + node.teleporter_target_entered(at) + + +# Report event for the teleporter target moving on a node +func _report_target_moved(node: Node3D, from: Vector3, to: Vector3) -> void: + teleporter_target_moved.emit(node, from, to) + if is_instance_valid(node): + if node.has_signal("teleporter_target_moved"): + node.emit_signal("teleporter_target_moved", from, to) + elif node.has_method("teleporter_target_moved"): + node.teleporter_target_moved(from, to) + + +# Report events for the teleporter target exiting a node +func _report_target_exited(node: Node3D, at: Vector3) -> void: + teleporter_target_exited.emit(node, at) + if is_instance_valid(node): + if node.has_signal("teleporter_target_exited"): + node.emit_signal("teleporter_target_exited", at) + elif node.has_method("teleporter_target_exited"): + node.teleporter_target_exited(at) + + # Report events for teleportation to target location func _report_teleported_to(location : Vector3) -> void: teleported_to.emit(location) # Report events for teleporter deactivation -func _report_deactivated(): +func _report_deactivated() -> void: teleporter_deactivated.emit() From 8ffe875b6d393dc58b8b2bdb59a8e048dd458d33 Mon Sep 17 00:00:00 2001 From: Torsten Crass Date: Fri, 22 Sep 2023 12:35:49 +0200 Subject: [PATCH 5/5] Transporter events reafactored in order to be consistent with pointer events. --- .../godot-xr-tools/events/teleporter_event.gd | 217 ++++++++++++++++++ .../functions/function_teleport.gd | 104 ++------- 2 files changed, 236 insertions(+), 85 deletions(-) create mode 100644 addons/godot-xr-tools/events/teleporter_event.gd diff --git a/addons/godot-xr-tools/events/teleporter_event.gd b/addons/godot-xr-tools/events/teleporter_event.gd new file mode 100644 index 00000000..05e76ec2 --- /dev/null +++ b/addons/godot-xr-tools/events/teleporter_event.gd @@ -0,0 +1,217 @@ +class_name XRToolsTeleporterEvent + +## Types of pointer events +enum Type { + ## Teleporter activated + ACTIVATED, # 0 + + ## Teleporter beam hit a suitable target + ENTERED, # 1 + + ## Teleporter beam moved inside a suitable target + MOVED, # 2 + + ## Teleporter beam left a suitable target + EXITED, # 3 + + ## Teleporter's ability to perform teleportation changed + CAN_TELEPORT_CHANGED, # 4 + + ## Player got teleportet to the teleporter's target location + TELEPORTED, # 5 + + ## Teleporter deactivated + DEACTIVATED # 6 +} + +## Type of teleporter event +var event_type : Type + +## Teleporter generating event +var teleporter : Node3D + +## Teleporter activated +var is_teleporting : bool + +## Teleporter's ability to perform teleportation +var can_teleport : bool + +## Current teleporter target +var target : Node3D + +## Teleporter target position +var position : Vector3 + +## Last target position +var last_position : Vector3 + + +## Initialize a new instance of the XRToolsPointerEvent class +func _init( + p_event_type : Type, + p_teleporter : Node3D, + p_is_teleporting : bool, + p_can_teleport : bool, + p_target : Node3D, + p_position : Vector3, + p_last_position : Vector3) -> void: + event_type = p_event_type + teleporter = p_teleporter + is_teleporting = p_is_teleporting + can_teleport = p_can_teleport + target = p_target + position = p_position + last_position = p_last_position + + +## Report teleporter activated event +static func activated( + teleporter : Node3D, + can_teleport : bool, + target : Node3D, + at : Vector3) -> void: + report( + XRToolsTeleporterEvent.new( + Type.ACTIVATED, + teleporter, + true, + can_teleport, + target, + at, + at + ) + ) + +## Report teleporter beam entered target event +static func entered( + teleporter : Node3D, + is_teleporting : bool, + can_teleport : bool, + target : Node3D, + at : Vector3) -> void: + report( + XRToolsTeleporterEvent.new( + Type.ENTERED, + teleporter, + is_teleporting, + can_teleport, + target, + at, + at + ) + ) + + +## Report teleporter beam moved inside target event +static func moved( + teleporter : Node3D, + is_teleporting : bool, + can_teleport : bool, + target : Node3D, + to : Vector3, + from : Vector3) -> void: + report( + XRToolsTeleporterEvent.new( + Type.MOVED, + teleporter, + is_teleporting, + can_teleport, + target, + to, + from + ) + ) + + +## Report teleporter beam entered target event +static func exited( + teleporter : Node3D, + is_teleporting : bool, + can_teleport : bool, + target : Node3D, + last : Vector3) -> void: + report( + XRToolsTeleporterEvent.new( + Type.EXITED, + teleporter, + is_teleporting, + can_teleport, + target, + last, + last + ) + ) + + +## Report teleportation event +static func can_teleport_changed( + teleporter : Node3D, + is_teleporting : bool, + can_teleport : bool, + target : Node3D, + position : Vector3) -> void: + report( + XRToolsTeleporterEvent.new( + Type.CAN_TELEPORT_CHANGED, + teleporter, + is_teleporting, + can_teleport, + target, + position, + position + ) + ) + + +## Report teleportation event +static func teleported( + teleporter : Node3D, + is_teleporting : bool, + can_teleport : bool, + target : Node3D, + position : Vector3) -> void: + report( + XRToolsTeleporterEvent.new( + Type.TELEPORTED, + teleporter, + is_teleporting, + can_teleport, + target, + position, + position + ) + ) + + +## Report teleporter deactivated event +static func deactivated( + teleporter : Node3D, + can_teleport : bool, + target : Node3D, + at : Vector3) -> void: + report( + XRToolsTeleporterEvent.new( + Type.DEACTIVATED, + teleporter, + false, + can_teleport, + target, + at, + at + ) + ) + + +## Report a pointer event +static func report(event : XRToolsTeleporterEvent) -> void: + # Fire event on pointer + if is_instance_valid(event.teleporter): + if event.teleporter.has_signal("teleporter_event"): + event.teleporter.emit_signal("teleporter_event", event) + + # Fire event/method on the target if it's valid + if is_instance_valid(event.target): + if event.target.has_signal("teleporter_event"): + event.target.emit_signal("teleporter_event", event) + elif event.target.has_method("teleporter_event"): + event.target.pointer_event(event) diff --git a/addons/godot-xr-tools/functions/function_teleport.gd b/addons/godot-xr-tools/functions/function_teleport.gd index 885d8c5f..1dfe7b4b 100644 --- a/addons/godot-xr-tools/functions/function_teleport.gd +++ b/addons/godot-xr-tools/functions/function_teleport.gd @@ -12,26 +12,9 @@ extends Node3D ## a teleport function on that controller. -## Signal emitted when the teleporter is activated -signal teleporter_activated() -## Signal emitted when the teleporter's ability to perform a teleportation changes -signal can_teleport_changed(can_teleport) - -# signal emitted when the teleporter beam hits a suitable target -signal teleporter_target_entered(node, at) - -# signal emitted when the teleporter beam moves along a suitable target -signal teleporter_target_moved(node, from, to) - -# signal emitted when the teleporter beam leaves a suitable target -signal teleporter_target_exited(node, at) - -## Signal emitted when the player gets teleportet to the teleporter's target location -signal teleported_to(location) - -## Signal emitted when the teleporter is deactivated -signal teleporter_deactivated() +## Signal emitted when this teleporter's state changed +signal teleporter_event(event) # Default teleport collision mask of all @@ -107,7 +90,7 @@ var player_material : StandardMaterial3D = _DefaultMaterial : set = set_player_ var is_on_floor : bool = true var is_teleporting : bool = false: set = set_is_teleporting -var can_teleport : bool = true: set = set_can_teleport +var can_teleport : bool = false: set = set_can_teleport var target_node : Node3D = null var target_hit_pos : Vector3 var teleport_rotation : float = 0.0; @@ -178,7 +161,7 @@ func _physics_process(delta): # if we're not enabled no point in doing mode if !enabled: # reset these - is_teleporting = false; + is_teleporting = false $Teleport.visible = false $Target.visible = false @@ -302,7 +285,7 @@ func _physics_process(delta): is_on_floor = false if is_on_floor: - _update_target(intersects["collider"], intersects["position"]) + _update_target(intersects["collider"], collided_at) # we are colliding, find our if we're colliding on a wall or # floor, one we can do, the other nope... @@ -356,10 +339,9 @@ func _physics_process(delta): new_transform.basis.x = new_transform.basis.y.cross(new_transform.basis.z).normalized() new_transform.basis.z = new_transform.basis.x.cross(new_transform.basis.y).normalized() - _clear_target() # Teleport the player player_body.teleport(new_transform) - _report_teleported_to(new_transform.origin) + XRToolsTeleporterEvent.teleported(self, is_teleporting, can_teleport, target_node, new_transform.origin) # and disable is_teleporting = false; @@ -484,21 +466,22 @@ func _update_target_texture(): # Set property telling whether all conditions for successful teleportation are met func set_can_teleport(new_value : bool) -> void: if new_value != can_teleport: - can_teleport = new_value - if not can_teleport: - # Can't teleport => no suitable target + if not new_value: _clear_target() - _report_can_teleport_changed(can_teleport) + can_teleport = new_value + XRToolsTeleporterEvent.can_teleport_changed(self, is_teleporting, can_teleport, target_node, target_hit_pos) # Set is_teleporting property and notify about its changes func set_is_teleporting(new_value : bool) -> void: if new_value != is_teleporting: - is_teleporting = new_value - if is_teleporting: - _report_activated() + if new_value: + XRToolsTeleporterEvent.activated(self, can_teleport, target_node, target_hit_pos) else: - _report_deactivated() + _clear_target() + can_teleport = false + XRToolsTeleporterEvent.deactivated(self, can_teleport, target_node, target_hit_pos) + is_teleporting = new_value # Player height update handler @@ -521,6 +504,7 @@ func _update_player_radius(): capsule.mesh.height = player_height capsule.mesh.radius = player_radius + # Update the player scene func _update_player_scene() -> void: # Free the current player @@ -552,61 +536,11 @@ func _clear_target(): func _update_target(node: Node3D, hit_pos: Vector3) -> void: if node == target_node: if (hit_pos != target_hit_pos): - _report_target_moved(target_node, target_hit_pos, hit_pos) + XRToolsTeleporterEvent.moved(self, is_teleporting, can_teleport, node, hit_pos, target_hit_pos) else: if target_node != null: - _report_target_exited(target_node, target_hit_pos) + XRToolsTeleporterEvent.exited(self, is_teleporting, can_teleport, target_node, target_hit_pos) if node != null: - _report_target_entered(node, hit_pos) + XRToolsTeleporterEvent.entered(self, is_teleporting, can_teleport, node, hit_pos) target_node = node target_hit_pos = hit_pos - - -# Report events for teleporter activation -func _report_activated() -> void: - teleporter_activated.emit() - - -# Report events for teleportation ability changes -func _report_can_teleport_changed(can_teleport : bool) -> void: - can_teleport_changed.emit(can_teleport) - - -# Report events for the teleporter target entering a node -func _report_target_entered(node: Node3D, at: Vector3) -> void: - teleporter_target_entered.emit(node, at) - if is_instance_valid(node): - if node.has_signal("teleporter_target_entered"): - node.emit_signal("teleporter_target_entered", at) - elif node.has_method("teleporter_target_entered"): - node.teleporter_target_entered(at) - - -# Report event for the teleporter target moving on a node -func _report_target_moved(node: Node3D, from: Vector3, to: Vector3) -> void: - teleporter_target_moved.emit(node, from, to) - if is_instance_valid(node): - if node.has_signal("teleporter_target_moved"): - node.emit_signal("teleporter_target_moved", from, to) - elif node.has_method("teleporter_target_moved"): - node.teleporter_target_moved(from, to) - - -# Report events for the teleporter target exiting a node -func _report_target_exited(node: Node3D, at: Vector3) -> void: - teleporter_target_exited.emit(node, at) - if is_instance_valid(node): - if node.has_signal("teleporter_target_exited"): - node.emit_signal("teleporter_target_exited", at) - elif node.has_method("teleporter_target_exited"): - node.teleporter_target_exited(at) - - -# Report events for teleportation to target location -func _report_teleported_to(location : Vector3) -> void: - teleported_to.emit(location) - - -# Report events for teleporter deactivation -func _report_deactivated() -> void: - teleporter_deactivated.emit()