multyplayer
This commit is contained in:
@@ -16,6 +16,11 @@ material = SubResource("StandardMaterial3D_m5xe2")
|
||||
[sub_resource type="SphereShape3D" id="SphereShape3D_vlqg6"]
|
||||
radius = 0.3
|
||||
|
||||
[sub_resource type="SceneReplicationConfig" id="Repl_hob"]
|
||||
properties/0/path = NodePath(".:progress")
|
||||
properties/0/spawn = true
|
||||
properties/0/replication_mode = 1
|
||||
|
||||
[node name="Hob" type="StaticBody3D" unique_id=1687971542 groups=["station"]]
|
||||
script = ExtResource("1_7jc4g")
|
||||
|
||||
@@ -40,3 +45,6 @@ metadata/_custom_type_script = "uid://cquqe4f1m1sw6"
|
||||
[node name="CollisionShape3D2" type="CollisionShape3D" parent="XRToolsSnapZone" unique_id=370920392]
|
||||
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, -0.000975132, 0)
|
||||
shape = SubResource("SphereShape3D_vlqg6")
|
||||
|
||||
[node name="ProgressSync" type="MultiplayerSynchronizer" parent="."]
|
||||
replication_config = SubResource("Repl_hob")
|
||||
|
||||
+32
-29
@@ -1,59 +1,62 @@
|
||||
extends StaticBody3D
|
||||
|
||||
## Cooking station. The cook timer and item conversion run only on the machine
|
||||
## that owns world logic (server or offline host); `progress` is replicated to
|
||||
## clients for UI via a MultiplayerSynchronizer. This is the reference
|
||||
## implementation of the reusable "station work-progress" pattern: a server-owned
|
||||
## progress value advanced by an input source (here, a timer), which converts the
|
||||
## held item once it reaches the threshold and spawns the result over the network.
|
||||
|
||||
@export var cook_speed = 1
|
||||
@export var cook_speed := 1.0
|
||||
@onready var snap_zone: XRToolsSnapZone = $XRToolsSnapZone
|
||||
|
||||
var item = null
|
||||
var progress = 0
|
||||
var progress: float = 0.0
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
if snap_zone.initial_object:
|
||||
item = snap_zone.initial_object
|
||||
print("Hob has item: ", item)
|
||||
else:
|
||||
print("Hob is empty")
|
||||
|
||||
|
||||
func convert_item(cookable: CookableItem) -> void:
|
||||
print("Hob converting ", cookable)
|
||||
|
||||
var old_pickable = snap_zone.picked_up_object
|
||||
if not old_pickable:
|
||||
push_warning("Hob finished cooking item, but snap zone is missing its reference")
|
||||
return
|
||||
|
||||
print("picked_up_object ", snap_zone.picked_up_object)
|
||||
|
||||
var original_transform = old_pickable.global_transform
|
||||
var new_scene_instance = cookable.turns_into.instantiate()
|
||||
|
||||
# Add the new item to the hob's parent (so it lives in the main world space)
|
||||
get_parent().add_child(new_scene_instance)
|
||||
new_scene_instance.global_transform = original_transform
|
||||
var original_transform: Transform3D = old_pickable.global_transform
|
||||
|
||||
snap_zone.drop_object()
|
||||
print("old_pickable ", old_pickable)
|
||||
# Spawn the result over the network (server) or locally (offline).
|
||||
var result := NetworkManager.spawn_item(cookable.turns_into.resource_path, original_transform)
|
||||
|
||||
# Remove the cooked item (despawn replicates for spawner-managed items).
|
||||
snap_zone.drop_object()
|
||||
old_pickable.queue_free()
|
||||
snap_zone.pick_up_object(new_scene_instance)
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
# Find the CookableItem in held object
|
||||
# Snap the result into the now-empty zone.
|
||||
if result:
|
||||
snap_zone.pick_up_object(result)
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
# Only the world owner runs cooking logic; clients receive `progress` + the
|
||||
# converted item via replication.
|
||||
if not NetworkManager.owns_world():
|
||||
return
|
||||
|
||||
# Find the CookableItem in the held object.
|
||||
var cookable = null
|
||||
if snap_zone.picked_up_object:
|
||||
var matches = snap_zone.picked_up_object.get_children().filter(func(c): return c is CookableItem)
|
||||
if matches.size() > 0:
|
||||
cookable = matches[0]
|
||||
|
||||
# Cook it if exists, then convert item after cooking
|
||||
|
||||
# Advance progress and convert once cooked.
|
||||
if cookable:
|
||||
progress += cook_speed * delta
|
||||
print("Cooking ", progress)
|
||||
if progress >= cookable.cooking_time:
|
||||
progress = 0
|
||||
progress = 0.0
|
||||
convert_item(cookable)
|
||||
else:
|
||||
progress = 0
|
||||
|
||||
progress = 0.0
|
||||
|
||||
@@ -13,10 +13,10 @@ func _ready() -> void:
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
# Only the world owner dispenses, so every client doesn't spawn its own copy.
|
||||
if not NetworkManager.owns_world():
|
||||
return
|
||||
if not snap_zone.picked_up_object:
|
||||
var new_item = item_scene.instantiate()
|
||||
|
||||
# Add the new item to the hob's parent (so it lives in the main world space)
|
||||
get_parent().add_child(new_item)
|
||||
new_item.global_transform = snap_zone.transform
|
||||
snap_zone.pick_up_object(new_item)
|
||||
var new_item := NetworkManager.spawn_item(item_scene.resource_path, snap_zone.global_transform)
|
||||
if new_item:
|
||||
snap_zone.pick_up_object(new_item)
|
||||
|
||||
Reference in New Issue
Block a user