Add Station move handle has ghost
This commit is contained in:
+2
-2
@@ -47,7 +47,7 @@ properties/2/spawn = true
|
||||
properties/2/replication_mode = 1
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_vlqg6"]
|
||||
size = Vector3(0.6, 1, 0.6)
|
||||
size = Vector3(0.5, 1, 0.5)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vlqg6"]
|
||||
transparency = 1
|
||||
@@ -247,7 +247,7 @@ script = ExtResource("15_trny8")
|
||||
[node name="MoveGhost" type="Area3D" parent="." unique_id=2098037388]
|
||||
visible = false
|
||||
collision_layer = 0
|
||||
collision_mask = 589831
|
||||
collision_mask = 524295
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="MoveGhost" unique_id=486115686]
|
||||
shape = SubResource("BoxShape3D_vlqg6")
|
||||
|
||||
@@ -7,11 +7,15 @@ extends Node
|
||||
@export var station: StaticBody3D
|
||||
|
||||
var move_handle_rigid: RigidBody3D
|
||||
var original_collision_layer
|
||||
var original_y_pos: float
|
||||
var original_collision_layer: int = 0
|
||||
var original_y_pos: float = 0.0
|
||||
var original_station_transform: Transform3D = Transform3D.IDENTITY
|
||||
var moving: bool = false
|
||||
var ghost_materials: Array[StandardMaterial3D] = []
|
||||
|
||||
const GHOST_COLOR_VALID: Color = Color(0, 1, 0, 0.35)
|
||||
const GHOST_COLOR_INVALID: Color = Color(1, 0, 0, 0.35)
|
||||
|
||||
# TODO: Reject placing station in occupied spot.
|
||||
# TODO: Make ghost version of station that is displayed instead of model.
|
||||
# TODO: public toggle to disable handle in build mode.
|
||||
# TODO: If game exits build mode, drop the handle before disabling it.
|
||||
|
||||
@@ -19,28 +23,111 @@ var original_y_pos: float
|
||||
func _ready() -> void:
|
||||
if not station:
|
||||
push_error("StationMovement is missing referece to station")
|
||||
if not move_handle:
|
||||
push_error("StationMovement is missing reference to move_handle")
|
||||
if not move_ghost:
|
||||
push_error("StationMovement is missing reference to move_ghost")
|
||||
|
||||
move_handle_rigid = move_handle as RigidBody3D
|
||||
original_collision_layer = station.collision_layer
|
||||
original_y_pos = move_handle.transform.origin.y
|
||||
original_station_transform = station.global_transform
|
||||
move_handle.picked_up.connect(_handle_pickup)
|
||||
move_handle.dropped.connect(_handle_drop)
|
||||
|
||||
move_ghost.monitoring = true
|
||||
move_ghost.visible = false
|
||||
_cache_ghost_materials()
|
||||
_set_ghost_color(GHOST_COLOR_VALID)
|
||||
|
||||
func _handle_pickup(_by):
|
||||
|
||||
func _cache_ghost_materials() -> void:
|
||||
var combiner = move_ghost.get_node_or_null("CSGCombiner3D")
|
||||
if not combiner:
|
||||
return
|
||||
_collect_ghost_materials(combiner)
|
||||
|
||||
|
||||
func _collect_ghost_materials(node: Node) -> void:
|
||||
if node is CSGCombiner3D:
|
||||
# Combiner nodes do not expose a material property to modify.
|
||||
for child in node.get_children():
|
||||
_collect_ghost_materials(child)
|
||||
return
|
||||
|
||||
if node is CSGShape3D:
|
||||
var material = node.material
|
||||
if material and material is StandardMaterial3D:
|
||||
var instance = material.duplicate() as StandardMaterial3D
|
||||
instance.transparency = material.transparency
|
||||
instance.albedo_color = material.albedo_color
|
||||
node.material = instance
|
||||
ghost_materials.append(instance)
|
||||
|
||||
for child in node.get_children():
|
||||
_collect_ghost_materials(child)
|
||||
|
||||
|
||||
func _set_ghost_color(color: Color) -> void:
|
||||
for material in ghost_materials:
|
||||
material.albedo_color = color
|
||||
|
||||
|
||||
func _handle_pickup(_by: Node) -> void:
|
||||
print("StationMovement handle pickup")
|
||||
moving = true
|
||||
move_ghost.visible = true
|
||||
station.visible = false
|
||||
station.collision_layer = 0
|
||||
original_station_transform = station.global_transform
|
||||
move_ghost.global_transform = original_station_transform
|
||||
|
||||
|
||||
func _handle_drop(_by):
|
||||
func _handle_drop(_by: Node) -> void:
|
||||
print("StationMovement handle drop")
|
||||
moving = false
|
||||
move_ghost.visible = false
|
||||
station.visible = true
|
||||
station.collision_layer = original_collision_layer
|
||||
if _is_move_position_valid():
|
||||
station.global_transform = move_ghost.global_transform
|
||||
else:
|
||||
station.global_transform = original_station_transform
|
||||
move_handle.global_position = station.global_position + Vector3(0, original_y_pos, 0)
|
||||
move_handle.rotation = station.rotation
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
station.global_position.x = snappedf(move_handle.global_position.x, snap_grid_size)
|
||||
station.global_position.z = snappedf(move_handle.global_position.z, snap_grid_size)
|
||||
station.global_rotation_degrees.y = snappedf(move_handle.global_rotation_degrees.y, 90)
|
||||
if not moving:
|
||||
return
|
||||
|
||||
var target_transform: Transform3D = move_handle.global_transform
|
||||
target_transform.origin.x = snappedf(target_transform.origin.x, snap_grid_size)
|
||||
target_transform.origin.z = snappedf(target_transform.origin.z, snap_grid_size)
|
||||
target_transform.origin.y = original_station_transform.origin.y
|
||||
var target_yaw: float = snappedf(move_handle.global_rotation_degrees.y, 90)
|
||||
target_transform.basis = Basis(Vector3.UP, deg_to_rad(target_yaw))
|
||||
|
||||
move_ghost.global_transform = target_transform
|
||||
if _is_move_position_valid():
|
||||
_set_ghost_color(GHOST_COLOR_VALID)
|
||||
else:
|
||||
_set_ghost_color(GHOST_COLOR_INVALID)
|
||||
|
||||
|
||||
func _is_move_position_valid() -> bool:
|
||||
for body in move_ghost.get_overlapping_bodies():
|
||||
print("Overlapping body: ", body)
|
||||
if body == move_handle:
|
||||
continue
|
||||
if body == station:
|
||||
continue
|
||||
return false
|
||||
|
||||
for area in move_ghost.get_overlapping_areas():
|
||||
print("Overlapping area: ", area)
|
||||
if area == move_ghost:
|
||||
continue
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user