multyplayer
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
class_name NetPickable
|
||||
extends Node
|
||||
|
||||
## Networks an XRToolsPickable (RigidBody3D). Default authority is the server,
|
||||
## which simulates free items and syncs their transform. Grabbing an item with a
|
||||
## hand transfers authority to the grabbing client (its local kinematic grab
|
||||
## driver then drives the synced transform); releasing returns authority and the
|
||||
## throw velocity to the server. Non-authority peers keep the body frozen and
|
||||
## follow the synced transform, so only one machine ever simulates an item.
|
||||
|
||||
@onready var _item: XRToolsPickable = get_parent() as XRToolsPickable
|
||||
|
||||
var net_held_by := 0 # peer id currently holding (0 = free); kept consistent via NetworkManager
|
||||
var _was_authority := true
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if not _item:
|
||||
push_error("NetPickable must be a child of an XRToolsPickable")
|
||||
return
|
||||
_item.grabbed.connect(_on_grabbed)
|
||||
_item.released.connect(_on_released)
|
||||
_was_authority = _item.is_multiplayer_authority()
|
||||
_apply_authority_state()
|
||||
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
if not NetworkManager.is_online():
|
||||
return
|
||||
var mine := _item.is_multiplayer_authority()
|
||||
if mine != _was_authority:
|
||||
_was_authority = mine
|
||||
_apply_authority_state()
|
||||
|
||||
|
||||
# Configure physics for whether we own this item or merely mirror it.
|
||||
func _apply_authority_state() -> void:
|
||||
if not _item:
|
||||
return
|
||||
if _item.is_multiplayer_authority():
|
||||
# We own physics: simulate the item whenever it is not held.
|
||||
if not _item.is_picked_up():
|
||||
_item.freeze = false
|
||||
else:
|
||||
# Someone else owns it: follow the synced transform kinematically.
|
||||
_item.freeze = true
|
||||
_item.freeze_mode = RigidBody3D.FREEZE_MODE_KINEMATIC
|
||||
|
||||
|
||||
func _on_grabbed(_pickable: Node3D, by: Node3D) -> void:
|
||||
if not NetworkManager.is_online():
|
||||
return
|
||||
# Only hand grabs transfer authority; snap-zone grabs are server-driven.
|
||||
if not (by is XRToolsFunctionPickup):
|
||||
return
|
||||
NetworkManager.request_item_authority.rpc_id(1, _item.get_path())
|
||||
|
||||
|
||||
func _on_released(_pickable: Node3D, by: Node3D) -> void:
|
||||
if not NetworkManager.is_online():
|
||||
return
|
||||
if not (by is XRToolsFunctionPickup):
|
||||
return
|
||||
NetworkManager.release_item_authority.rpc_id(1, _item.get_path(), _item.linear_velocity, _item.angular_velocity)
|
||||
Reference in New Issue
Block a user