update interaction system
This commit is contained in:
parent
9ff35349a1
commit
c240efa56f
31
README.md
31
README.md
|
@ -65,30 +65,29 @@ func watch_state(entity: String, callback: Callable[entity: Entity]) -> Callable
|
|||
|
||||
### Interaction Events
|
||||
|
||||
Each time a button is pressed on the primary controller, a raycast is done to be able to interact with devices or the UI.
|
||||
Each time a button is pressed on the primary controller, a ray-cast is done to be able to interact with devices or the UI.
|
||||
|
||||
**InteractionEvent**
|
||||
```js
|
||||
{
|
||||
position: Vector3,
|
||||
rotation: Vector3
|
||||
```python
|
||||
InteractionEvent {
|
||||
"controller": XRController3D, # The controller that triggered the event
|
||||
"ray": RayCast3D, # The ray-cast that triggered the event
|
||||
}
|
||||
```
|
||||
|
||||
| Function called | Args | Description |
|
||||
| -- | -- | -- |
|
||||
| `_click` | `[event: InteractionEvent]` | The back trigger button has been pressed and released |
|
||||
| `_dbl_click` | `[event: InteractionEvent]` | The back trigger button has been pressed and released twice in a row |
|
||||
| `_long_click` | `[event: InteractionEvent]` | The back trigger button has been pressed, then hold still for a short period, then released |
|
||||
| `_press_down` | `[event: InteractionEvent]` | The back trigger button has been pressed down |
|
||||
| `_press_move` | `[event: InteractionEvent]` | The back trigger button has been moved while pressed down |
|
||||
| `_press_up` | `[event: InteractionEvent]` | The back trigger button has been released |
|
||||
| `_grab_down` | `[event: InteractionEvent]` | The side grap button been pressed down |
|
||||
| `_grab_move` | `[event: InteractionEvent]` | The side grap button been pressed down |
|
||||
| `_grab_up` | `[event: InteractionEvent]` | The side grap button been released |
|
||||
| `_on_click` | `[event: InteractionEvent]` | The back trigger button has been pressed and released |
|
||||
| `_on_press_down` | `[event: InteractionEvent]` | The back trigger button has been pressed down |
|
||||
| `_on_press_move` | `[event: InteractionEvent]` | The back trigger button has been moved while pressed down |
|
||||
| `_on_press_up` | `[event: InteractionEvent]` | The back trigger button has been released |
|
||||
| `_on_grab_down` | `[event: InteractionEvent]` | The side grab button been pressed down |
|
||||
| `_on_grab_move` | `[event: InteractionEvent]` | The side grab button been pressed down |
|
||||
| `_on_grab_up` | `[event: InteractionEvent]` | The side grab button been released |
|
||||
| `_on_ray_enter` | `[event: InteractionEvent]` | The ray-cast enters the the collision body |
|
||||
| `_on_ray_leave` | `[event: InteractionEvent]` | The ray-cast leaves the the collision body |
|
||||
|
||||
### Testing without a VR Headset
|
||||
|
||||
In order to test without a headset, press the run project (F5) button in Godot and ignore the prompt that OpenXR failed to start.
|
||||
To simulate the headset and controller movement, we're using the [XR Input Simulator](https://godotengine.org/asset-library/asset/1775) asset.
|
||||
Click at the link to get a list of the supported controlls.
|
||||
Click at the link to get a list of the supported controls.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=12 format=3 uid="uid://eecv28y6jxk4"]
|
||||
[gd_scene load_steps=13 format=3 uid="uid://eecv28y6jxk4"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://clc5dre31iskm" path="res://addons/godot-xr-tools/xr/start_xr.tscn" id="1_i4c04"]
|
||||
[ext_resource type="Script" path="res://src/raycast.gd" id="1_tsqxc"]
|
||||
|
@ -7,6 +7,7 @@
|
|||
[ext_resource type="PackedScene" uid="uid://c3kdssrmv84kv" path="res://scenes/menu.tscn" id="3_1tbp3"]
|
||||
[ext_resource type="PackedScene" uid="uid://ctltchlf2j2r4" path="res://addons/xr-simulator/XRSimulator.tscn" id="5_3qc8g"]
|
||||
[ext_resource type="Material" uid="uid://bf5ina366dwm6" path="res://assets/materials/sky.material" id="5_wgwf8"]
|
||||
[ext_resource type="PackedScene" uid="uid://cscl5k7lhopj5" path="res://scenes/entities/switch.tscn" id="8_uxmrb"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_m58yb"]
|
||||
ao_enabled = true
|
||||
|
@ -76,3 +77,7 @@ shadow_enabled = true
|
|||
|
||||
[node name="XRSimulator" parent="." instance=ExtResource("5_3qc8g")]
|
||||
xr_origin = NodePath("../XROrigin3D")
|
||||
|
||||
[node name="Switch" parent="." instance=ExtResource("8_uxmrb")]
|
||||
transform = Transform3D(0.999999, -1.39635e-11, 0, 9.48031e-12, 1, 0, 0, 0, 1, 0.564168, 0.725642, -1.56163)
|
||||
entity_id = "switch.plug_printer_2_fale"
|
||||
|
|
|
@ -6,6 +6,9 @@ extends StaticBody3D
|
|||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
var stateInfo = await HomeAdapters.adapter_ws.get_state(entity_id)
|
||||
if stateInfo == null:
|
||||
return
|
||||
|
||||
if stateInfo["state"] == "on":
|
||||
sprite.set_frame(0)
|
||||
else:
|
||||
|
|
|
@ -10,6 +10,7 @@ var token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIzZjQ0ZGM2N2Y3YzY0M
|
|||
var LOG_MESSAGES := false
|
||||
|
||||
var authenticated := false
|
||||
var loading := true
|
||||
var id := 1
|
||||
var entities: Dictionary = {}
|
||||
|
||||
|
@ -100,6 +101,7 @@ func start_subscriptions():
|
|||
"attributes": packet.event.a[entity]["a"]
|
||||
}
|
||||
entitiy_callbacks.call_key(entity, [entities[entity]])
|
||||
loading = false
|
||||
on_connect.emit()
|
||||
|
||||
if packet.event.has("c"):
|
||||
|
@ -171,13 +173,13 @@ func encode_packet(packet: Dictionary):
|
|||
return JSON.stringify(packet)
|
||||
|
||||
func load_devices():
|
||||
if !authenticated:
|
||||
if loading:
|
||||
await on_connect
|
||||
|
||||
return entities
|
||||
|
||||
func get_state(entity: String):
|
||||
if !authenticated:
|
||||
if loading:
|
||||
await on_connect
|
||||
|
||||
if entities.has(entity):
|
||||
|
@ -186,14 +188,14 @@ func get_state(entity: String):
|
|||
|
||||
|
||||
func watch_state(entity: String, callback: Callable):
|
||||
if !authenticated:
|
||||
if loading:
|
||||
await on_connect
|
||||
|
||||
entitiy_callbacks.add(entity, callback)
|
||||
|
||||
|
||||
func set_state(entity: String, state: String, attributes: Dictionary = {}):
|
||||
assert(authenticated, "Not authenticated")
|
||||
assert(!loading, "Still loading")
|
||||
|
||||
var domain = entity.split(".")[0]
|
||||
var service: String
|
||||
|
|
|
@ -5,23 +5,92 @@ extends Node3D
|
|||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
_controller.button_pressed.connect(self._on_button_pressed)
|
||||
_controller.button_pressed.connect(_on_button_pressed)
|
||||
_controller.button_released.connect(_on_button_released)
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
pass
|
||||
var _last_collided: Object = null
|
||||
var _is_pressed := false
|
||||
var _is_grabbed := false
|
||||
var _moved := false
|
||||
var _click_point := Vector3.ZERO
|
||||
|
||||
func _on_button_pressed(button):
|
||||
print(button)
|
||||
if button != "trigger_click":
|
||||
func _physics_process(delta):
|
||||
_handle_enter_leave()
|
||||
_handle_move()
|
||||
|
||||
func _get_event_data():
|
||||
return {
|
||||
"controller": _controller,
|
||||
"ray": ray,
|
||||
}
|
||||
|
||||
func _handle_move():
|
||||
var distance = ray.get_collision_point().distance_to(_click_point)
|
||||
|
||||
if distance > 0.01:
|
||||
if _is_pressed:
|
||||
_call_fn("_on_press_move")
|
||||
_moved = true
|
||||
if _is_grabbed:
|
||||
_call_fn("_on_grab_move")
|
||||
_moved = true
|
||||
|
||||
func _handle_enter_leave():
|
||||
var collider = ray.get_collider()
|
||||
|
||||
if collider == _last_collided:
|
||||
return
|
||||
|
||||
if _last_collided != null && _last_collided.has_method("_on_ray_enter"):
|
||||
_last_collided._on_ray_enter(_get_event_data())
|
||||
|
||||
if collider != null && collider.has_method("_on_ray_leave"):
|
||||
collider._on_ray_leave(_get_event_data())
|
||||
|
||||
_last_collided = collider
|
||||
|
||||
func _on_button_pressed(button):
|
||||
var collider = ray.get_collider()
|
||||
|
||||
if collider == null:
|
||||
return
|
||||
|
||||
print(collider)
|
||||
match button:
|
||||
"trigger_click":
|
||||
_is_pressed = true
|
||||
_click_point = ray.get_collision_point()
|
||||
_call_fn("_on_press_down")
|
||||
"grip_click":
|
||||
_is_grabbed = true
|
||||
_click_point = ray.get_collision_point()
|
||||
_call_fn("_on_grab_down")
|
||||
|
||||
if collider.has_method("_on_toggle"):
|
||||
collider._on_toggle()
|
||||
func _on_button_released(button):
|
||||
var collider = ray.get_collider()
|
||||
|
||||
if collider == null:
|
||||
return
|
||||
|
||||
match button:
|
||||
"trigger_click":
|
||||
if _is_pressed:
|
||||
if _moved == false:
|
||||
_call_fn("_on_click")
|
||||
_call_fn("_on_press_up")
|
||||
_is_pressed = false
|
||||
_moved = false
|
||||
"grip_click":
|
||||
if _is_grabbed:
|
||||
_call_fn("_on_grab_up")
|
||||
_is_grabbed = false
|
||||
_moved = false
|
||||
|
||||
func _call_fn(fn_name: String):
|
||||
print("call_fn", fn_name)
|
||||
var collider = ray.get_collider()
|
||||
|
||||
if collider == null:
|
||||
return
|
||||
|
||||
if collider.has_method(fn_name):
|
||||
collider.call(fn_name, _get_event_data())
|
||||
|
|
Loading…
Reference in New Issue
Block a user