Implement Phase 17a Prop Roles UI/UX Specification and associated functionality
- Added UI/UX specification for prop roles and set down mechanics in phase 17a. - Created `PropStageRoles` script to manage normalized behavior for props, including depth, motion, and collision settings. - Introduced `StagePhysicsPolicy` for shared physics configurations related to props and actors. - Developed comprehensive tests for prop roles, including default settings, legacy migration, serialization, and runtime behavior. - Ensured proper handling of set down actions, including clearance and orientation preservation.
This commit is contained in:
@@ -113,6 +113,7 @@ func _run() -> void:
|
||||
prop.polygon_points = PackedVector2Array([Vector2(-10, -10), Vector2(10, -10), Vector2(10, 10), Vector2(-10, 10)])
|
||||
prop.freeze = true
|
||||
root.add_child(prop)
|
||||
prop.apply_runtime_role(PROP_BLOCK.RuntimeRole.START_STILL)
|
||||
await process_frame
|
||||
var gizmos: StageGizmos = STAGE_GIZMOS.new()
|
||||
root.add_child(gizmos)
|
||||
@@ -128,6 +129,7 @@ func _run() -> void:
|
||||
gizmos.drag_to(prop.global_position + (corner - prop.global_position) * 2.0)
|
||||
gizmos.end_drag()
|
||||
_check(is_equal_approx(prop.scale.x / initial_scale.x, 2.0) and is_equal_approx(prop.scale.y / initial_scale.y, 2.0), "corner drag applies uniform scale")
|
||||
prop.begin_play_instance_scale()
|
||||
await physics_frame
|
||||
var space: PhysicsDirectSpaceState2D = root.get_world_2d().direct_space_state
|
||||
var polygon_inside: PhysicsPointQueryParameters2D = PhysicsPointQueryParameters2D.new()
|
||||
@@ -138,8 +140,7 @@ func _run() -> void:
|
||||
var polygon_outside_hits: Array[Dictionary] = space.intersect_point(polygon_outside)
|
||||
_check(not polygon_inside_hits.is_empty() and polygon_outside_hits.is_empty(), "scaled polygon collision matches its visual extent")
|
||||
prop.global_rotation = deg_to_rad(20.0)
|
||||
prop.begin_play_instance_scale()
|
||||
prop.freeze = false
|
||||
prop.apply_runtime_role(PROP_BLOCK.RuntimeRole.START_PHYSICS)
|
||||
for frame: int in 3:
|
||||
await physics_frame
|
||||
var rotated_local_inside: Vector2 = Vector2(19.0, 0.0).rotated(prop.global_rotation)
|
||||
@@ -154,6 +155,7 @@ func _run() -> void:
|
||||
circle.scale = Vector2(2.0, 2.0)
|
||||
circle.freeze = true
|
||||
root.add_child(circle)
|
||||
circle.apply_runtime_role(PROP_BLOCK.RuntimeRole.START_STILL)
|
||||
await physics_frame
|
||||
var circle_inside: PhysicsPointQueryParameters2D = PhysicsPointQueryParameters2D.new()
|
||||
circle_inside.position = circle.global_position + Vector2(19.0, 0.0)
|
||||
@@ -161,7 +163,7 @@ func _run() -> void:
|
||||
circle_outside.position = circle.global_position + Vector2(21.0, 0.0)
|
||||
_check(not space.intersect_point(circle_inside).is_empty() and space.intersect_point(circle_outside).is_empty(), "scaled circle collision matches its visual extent")
|
||||
circle.begin_play_instance_scale()
|
||||
circle.freeze = false
|
||||
circle.apply_runtime_role(PROP_BLOCK.RuntimeRole.START_PHYSICS)
|
||||
for frame: int in 3:
|
||||
await physics_frame
|
||||
circle_inside.position = circle.global_position + Vector2(19.0, 0.0)
|
||||
@@ -171,6 +173,7 @@ func _run() -> void:
|
||||
circle.end_play_instance_scale()
|
||||
circle.scale = Vector2(2.0, 1.0)
|
||||
circle.begin_play_instance_scale()
|
||||
circle.apply_runtime_role(PROP_BLOCK.RuntimeRole.START_PHYSICS)
|
||||
await physics_frame
|
||||
var ellipse_inside: PhysicsPointQueryParameters2D = PhysicsPointQueryParameters2D.new()
|
||||
ellipse_inside.position = circle.global_position + Vector2(0.0, 9.0)
|
||||
|
||||
Reference in New Issue
Block a user