Add Chopping Gesture
This commit is contained in:
+36
-2
@@ -1,11 +1,18 @@
|
||||
[gd_scene format=3 uid="uid://efaec6ymgabo"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cquqe4f1m1sw6" path="res://addons/godot-xr-tools/objects/snap_zone.gd" id="1_dlkho"]
|
||||
[ext_resource type="AudioStream" uid="uid://bqtk1adk8umbx" path="res://Sounds/220197__gameaudio__click-basic.wav" id="2_0aadn"]
|
||||
[ext_resource type="Script" uid="uid://cql13y8da4auf" path="res://stations/counter.gd" id="1_oapbh"]
|
||||
[ext_resource type="AudioStream" uid="uid://bqtk1adk8umbx" path="res://sounds/220197__gameaudio__click-basic.wav" id="2_0aadn"]
|
||||
[ext_resource type="AudioStream" uid="uid://daiv8ubwdbidf" path="res://sounds/220195__gameaudio__click-wooden-1.wav" id="2_lg82m"]
|
||||
[ext_resource type="PackedScene" uid="uid://dgk88esxip5xi" path="res://items/knife.tscn" id="3_3gvdi"]
|
||||
[ext_resource type="PackedScene" uid="uid://bxbocxdaayvwx" path="res://UI/progress_bar.tscn" id="6_racgh"]
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_24d3s"]
|
||||
size = Vector3(0.6, 1, 0.6)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_vlqg6"]
|
||||
size = Vector3(0.3, 0.05, 0.3)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_1ntq7"]
|
||||
size = Vector3(0.6, 0.12802735, 0.6)
|
||||
|
||||
@@ -18,11 +25,31 @@ albedo_color = Color(0.66595805, 0.53976387, 0.4331022, 1)
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vlqg6"]
|
||||
albedo_color = Color(1.1759251, 0.741115, 0.5692133, 1)
|
||||
|
||||
[node name="Counter" type="StaticBody3D" unique_id=1487893288 groups=["station"]]
|
||||
[node name="Counter" type="StaticBody3D" unique_id=1487893288 node_paths=PackedStringArray("audio", "knife", "progress_bar") groups=["station"]]
|
||||
script = ExtResource("1_oapbh")
|
||||
audio = NodePath("AudioStreamPlayer3D")
|
||||
chop_audio = ExtResource("2_lg82m")
|
||||
knife = NodePath("Knife")
|
||||
progress_bar = NodePath("ProgressBar3D")
|
||||
|
||||
[node name="CollisionShape3DCuttingBoard" type="CollisionShape3D" parent="." unique_id=706340473]
|
||||
shape = SubResource("BoxShape3D_24d3s")
|
||||
|
||||
[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="." unique_id=1941838513]
|
||||
|
||||
[node name="GestureArea" type="Area3D" parent="." unique_id=398687137]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.54, 0)
|
||||
collision_layer = 0
|
||||
collision_mask = 65536
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="GestureArea" unique_id=1450988028]
|
||||
shape = SubResource("BoxShape3D_vlqg6")
|
||||
|
||||
[node name="Knife" parent="." unique_id=1675596942 instance=ExtResource("3_3gvdi")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.78000003, 0)
|
||||
freeze = true
|
||||
release_mode = 1
|
||||
|
||||
[node name="XRToolsSnapZone" type="Area3D" parent="." unique_id=1647380272 groups=["station"]]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5608841, 0)
|
||||
collision_layer = 65536
|
||||
@@ -38,6 +65,9 @@ shape = SubResource("BoxShape3D_1ntq7")
|
||||
|
||||
[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="XRToolsSnapZone" unique_id=1786831079]
|
||||
|
||||
[node name="ProgressBar3D" parent="." unique_id=654673176 instance=ExtResource("6_racgh")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.78000003, -0.18)
|
||||
|
||||
[node name="CSGCombiner3D" type="CSGCombiner3D" parent="." unique_id=451757283]
|
||||
use_collision = true
|
||||
|
||||
@@ -88,3 +118,7 @@ material = SubResource("StandardMaterial3D_vlqg6")
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.1899699, 0.01924485, -0.0039587095)
|
||||
operation = 2
|
||||
size = Vector3(0.037109375, 0.092285156, 0.26757813)
|
||||
|
||||
[connection signal="body_entered" from="GestureArea" to="." method="_on_gesture_area_body_entered"]
|
||||
[connection signal="has_dropped" from="XRToolsSnapZone" to="." method="_on_snap_zone_dropped"]
|
||||
[connection signal="has_picked_up" from="XRToolsSnapZone" to="." method="_on_snap_zone_picked_up"]
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
extends StaticBody3D
|
||||
|
||||
@export var chop_work_steps: float = 5.0
|
||||
|
||||
@export var audio: AudioStreamPlayer3D
|
||||
@export var chop_audio: AudioStream
|
||||
@export var knife: XRToolsPickable
|
||||
@onready var snap_zone: XRToolsSnapZone = $XRToolsSnapZone
|
||||
@export var progress_bar: ProgressBar3D
|
||||
|
||||
# Chopping state. Follow the hob/sink pattern so the display refreshes when
|
||||
# values change; only the world owner runs the station's process in practice.
|
||||
var process_result: String = "": set = _set_result
|
||||
var process_result_work: float = 0.0: set = _set_result_work
|
||||
var work_progress: float = 0.0: set = _set_work_progress
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if not audio:
|
||||
push_error("Counter is missing reference to AudioStreamPlayer3D")
|
||||
if not chop_audio:
|
||||
push_error("Counter is missing reference to chop_audio AudioStream")
|
||||
if not progress_bar or progress_bar is not ProgressBar3D:
|
||||
push_error("Counter missing reference to progressbar, or wrong type:", progress_bar)
|
||||
if not knife or knife is not XRToolsPickable:
|
||||
push_error("Counter missing reference to knife, or wrong type:", knife)
|
||||
if not snap_zone or snap_zone is not XRToolsSnapZone:
|
||||
push_error("Counter missing reference to snap_zone, or wrong type:", snap_zone)
|
||||
|
||||
snap_zone.has_picked_up.connect(_on_object_picked_up)
|
||||
snap_zone.has_dropped.connect(_on_object_dropped)
|
||||
progress_bar.override_fill_color(Color.GREEN)
|
||||
_hide_all_tools()
|
||||
_refresh_progress_bar()
|
||||
|
||||
|
||||
func _set_work_progress(value: float) -> void:
|
||||
work_progress = value
|
||||
_refresh_progress_bar()
|
||||
|
||||
|
||||
func _set_result(value: String) -> void:
|
||||
process_result = value
|
||||
_refresh_progress_bar()
|
||||
# When a chopping recipe is set, show the knife for the player to use.
|
||||
if not process_result.is_empty():
|
||||
knife.visible = true
|
||||
knife.enabled = true
|
||||
print("Counter: chopping recipe set: ", process_result)
|
||||
else:
|
||||
_hide_all_tools()
|
||||
|
||||
|
||||
func _set_result_work(value: float) -> void:
|
||||
process_result_work = value
|
||||
_refresh_progress_bar()
|
||||
|
||||
|
||||
func _refresh_progress_bar() -> void:
|
||||
if not progress_bar:
|
||||
return
|
||||
var progress := 0.0
|
||||
if process_result != "" and process_result_work > 0:
|
||||
progress = clampf(float(work_progress) / process_result_work, 0.0, 1.0)
|
||||
|
||||
progress_bar.set_progress(progress)
|
||||
progress_bar.set_bar_visible(not process_result.is_empty())
|
||||
progress_bar.override_fill_color(Color.GREEN)
|
||||
|
||||
|
||||
# Add work from gesture area (knife hits). This increments the chopping progress.
|
||||
func add_work(work: float) -> void:
|
||||
print("Counter add_work: ", work)
|
||||
# Only the world owner should drive the authoritative state. Guarding is
|
||||
# handled by higher-level NetworkManager logic elsewhere, mirror hob's
|
||||
# convert_held_to_item which checks ownership before spawning.
|
||||
work_progress += work
|
||||
# Play chopping sound if available
|
||||
if audio and chop_audio:
|
||||
audio.stream = chop_audio
|
||||
audio.play()
|
||||
# If we've reached the required time, convert the held item
|
||||
if process_result != "" and process_result_work > 0 and work_progress >= process_result_work:
|
||||
print("Counter: chopping complete, converting item to: ", process_result)
|
||||
work_progress = 0
|
||||
convert_held_to_item(process_result)
|
||||
|
||||
|
||||
func _on_gesture_area_body_entered(body: Node3D) -> void:
|
||||
print("Counter: gesture area entered: ", body)
|
||||
if body.is_in_group("chopping_tool"):
|
||||
if process_result == "":
|
||||
print("Counter: knife entered but nothing to chop")
|
||||
return
|
||||
add_work(chop_work_steps)
|
||||
|
||||
|
||||
func _on_object_picked_up(_item: Variant) -> void:
|
||||
print("Counter: object picked up: ", _item)
|
||||
var food_item = Helper.find_food_item(_item)
|
||||
if not food_item:
|
||||
print("Counter: held object is not a FoodItem")
|
||||
return
|
||||
|
||||
var result = RecipeManager.get_chopping_result(food_item.id)
|
||||
if not result:
|
||||
print("Counter: held a FoodItem that is not choppable, id: %s process_result: %s" % [food_item.id, result])
|
||||
return
|
||||
|
||||
process_result = result
|
||||
process_result_work = RecipeManager.get_chopping_work(food_item.id)
|
||||
print("Counter: set process_result ", process_result, " work: ", process_result_work)
|
||||
|
||||
|
||||
func _on_object_dropped(_item: Variant) -> void:
|
||||
print("Counter: object drop ")
|
||||
work_progress = 0
|
||||
process_result = ""
|
||||
process_result_work = 0
|
||||
_hide_all_tools()
|
||||
|
||||
|
||||
func convert_held_to_item(_item: String) -> void:
|
||||
if not NetworkManager.owns_world():
|
||||
return
|
||||
print("Counter converting ", _item)
|
||||
|
||||
var old_pickable = snap_zone.picked_up_object
|
||||
if not old_pickable:
|
||||
push_warning("Counter finished processing _item, but snap zone is missing its reference")
|
||||
return
|
||||
|
||||
var original_transform = old_pickable.global_transform
|
||||
var new_scene_instance = NetworkManager.spawn_item(RecipeManager.get_item_scene(_item).resource_path, original_transform)
|
||||
|
||||
print("Counter freeing old_pickable ", old_pickable)
|
||||
snap_zone.drop_object()
|
||||
NetworkManager.despawn_item(old_pickable)
|
||||
snap_zone.pick_up_object(new_scene_instance)
|
||||
|
||||
|
||||
func _hide_all_tools():
|
||||
knife.visible = false
|
||||
knife.enabled = false
|
||||
@@ -0,0 +1 @@
|
||||
uid://cql13y8da4auf
|
||||
Reference in New Issue
Block a user