much better field edit tool, camera specifically
This commit is contained in:
@@ -4,11 +4,11 @@ extends Node3D
|
||||
signal path_updated()
|
||||
|
||||
@export var data_file: FlowFieldData
|
||||
@export var flow_node_scene: PackedScene
|
||||
@export var start_points: Array[Node3D]
|
||||
@export var goal_points: Array[Node3D]
|
||||
@export var nodes_visible: bool = false
|
||||
|
||||
var flow_node_scene: PackedScene = preload("res://Scenes/FlowField/flow_node.tscn")
|
||||
var nodes: Array[FlowNode] = []
|
||||
var start_nodes: Array[FlowNode] = []
|
||||
var goal_nodes: Array[FlowNode] = []
|
||||
@@ -29,6 +29,9 @@ func load_from_data(data: FlowFieldData = data_file) -> void:
|
||||
var dict: Dictionary[FlowNodeData, FlowNode] = {}
|
||||
for node_data: FlowNodeData in data_file.nodes:
|
||||
var new_flow_node: FlowNode = create_node(node_data.position)
|
||||
new_flow_node.grid_id = node_data.grid_id
|
||||
new_flow_node.grid_x = node_data.grid_x
|
||||
new_flow_node.grid_y = node_data.grid_y
|
||||
new_flow_node.buildable = node_data.buildable
|
||||
dict[node_data] = new_flow_node
|
||||
nodes.append(new_flow_node)
|
||||
@@ -186,8 +189,11 @@ func toggle_buildable(node: FlowNode) -> void:
|
||||
node.buildable = !node.buildable
|
||||
|
||||
|
||||
func create_node(pos: Vector3 = Vector3.ZERO) -> FlowNode:
|
||||
func create_node(pos: Vector3 = Vector3.ZERO, grid_id: int = -1, grid_x: int = 0, grid_y: int = 0) -> FlowNode:
|
||||
var node: FlowNode = flow_node_scene.instantiate()
|
||||
node.grid_id = grid_id
|
||||
node.grid_x = grid_x
|
||||
node.grid_y = grid_y
|
||||
node.position = pos
|
||||
node.set_color(Color.WEB_GRAY)
|
||||
nodes.append(node)
|
||||
@@ -216,6 +222,8 @@ func disconnect_nodes(node1: FlowNode, node2: FlowNode) -> void:
|
||||
|
||||
|
||||
func create_grid(x_size: int, y_size: int, gap: float) -> void:
|
||||
data_file.grids += 1
|
||||
var grid_id: int = data_file.grids
|
||||
var grid: Array[Array] = []
|
||||
for x: int in x_size:
|
||||
var row: Array[FlowNode] = []
|
||||
@@ -224,7 +232,7 @@ func create_grid(x_size: int, y_size: int, gap: float) -> void:
|
||||
var point_position: Vector3 = Vector3((x - floori(x_size / 2.0)) * gap, 0, (y - floori(y_size / 2.0)) * gap)
|
||||
#point_position += global_position
|
||||
#row.append(create_node(start_pos + Vector3(gap * x, 0, gap * y)))
|
||||
row.append(create_node(point_position))
|
||||
row.append(create_node(point_position, grid_id, x, y))
|
||||
grid.append(row)
|
||||
for x: int in grid.size():
|
||||
for y: int in grid[x].size():
|
||||
|
||||
5
Scenes/FlowField/flow_field_data.gd
Normal file
5
Scenes/FlowField/flow_field_data.gd
Normal file
@@ -0,0 +1,5 @@
|
||||
class_name FlowFieldData
|
||||
extends Resource
|
||||
|
||||
@export var nodes: Array[FlowNodeData]
|
||||
@export var grids: int = 0
|
||||
1
Scenes/FlowField/flow_field_data.gd.uid
Normal file
1
Scenes/FlowField/flow_field_data.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://ds7m1p5666qby
|
||||
258
Scenes/FlowField/flow_field_tool.gd
Normal file
258
Scenes/FlowField/flow_field_tool.gd
Normal file
@@ -0,0 +1,258 @@
|
||||
class_name FlowFieldTool
|
||||
extends Node
|
||||
|
||||
@export_group("Basic Function")
|
||||
@export var zone_list: Array[PackedScene]
|
||||
@export var zone_holder: Node3D
|
||||
|
||||
@export_group("Flow Field Editor")
|
||||
@export var flow_field: FlowField
|
||||
@export var raycast: RayCast3D
|
||||
@export var project_raycast: RayCast3D
|
||||
@export var camera: Camera3D
|
||||
@export var camera_pivot: Node3D
|
||||
@export var position_field: HBoxContainer
|
||||
@export var x_field: LineEdit
|
||||
@export var y_field: LineEdit
|
||||
@export var z_field: LineEdit
|
||||
@export var x_size_field: LineEdit
|
||||
@export var y_size_field: LineEdit
|
||||
@export var gap_field: LineEdit
|
||||
@export var save_path: LineEdit
|
||||
|
||||
var hover: FlowNode = null
|
||||
var selected: Array[FlowNode] = []
|
||||
var vector_dirty: bool = false
|
||||
var editing: bool = false
|
||||
var selected_zone: int = -1
|
||||
var level: Level
|
||||
var radius: float = 0
|
||||
var up_angle: float = 0
|
||||
var rotate_held: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
var i: int = 0
|
||||
for zone: PackedScene in zone_list:
|
||||
i += 1
|
||||
$VBoxContainer2/OptionButton.add_item("Zone " + str(i))
|
||||
$VBoxContainer2/OptionButton.select(0)
|
||||
$VBoxContainer2/OptionButton.item_selected.connect(select_zone)
|
||||
_on_trash_button_pressed()
|
||||
|
||||
|
||||
func select_zone(zone_index: int) -> void:
|
||||
selected_zone = zone_index
|
||||
|
||||
|
||||
func load_zone() -> void:
|
||||
_on_trash_button_pressed()
|
||||
if level:
|
||||
level.queue_free()
|
||||
level = zone_list[selected_zone].instantiate() as Level
|
||||
zone_holder.add_child(level)
|
||||
camera.make_current()
|
||||
editing = true
|
||||
print("set editing true")
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if editing:
|
||||
if raycast.is_colliding() and (!hover or hover != raycast.get_collider()):
|
||||
hover = raycast.get_collider()
|
||||
if hover and !raycast.is_colliding():
|
||||
hover = null
|
||||
if selected.size() == 1 and vector_dirty:
|
||||
position_field.visible = true
|
||||
x_field.text = str(selected[0].global_position.x)
|
||||
y_field.text = str(selected[0].global_position.y)
|
||||
z_field.text = str(selected[0].global_position.z)
|
||||
vector_dirty = false
|
||||
elif selected.size() != 1:
|
||||
position_field.visible = false
|
||||
|
||||
set_node_colors()
|
||||
|
||||
if Input.is_action_just_pressed("Secondary Fire"):
|
||||
rotate_held = true
|
||||
if Input.is_action_just_released("Secondary Fire"):
|
||||
rotate_held = false
|
||||
|
||||
var y: float = Input.get_axis("Move Forward", "Move Backward")
|
||||
var x: float = Input.get_axis("Move Left", "Move Right")
|
||||
var input_vector: Vector2 = Input.get_vector("Move Left", "Move Right", "Move Forward", "Move Backward")
|
||||
#camera_pivot.position += Vector3(x, 0, y) * delta * 30
|
||||
#set_cam_position()
|
||||
var movement: Vector3 = ((camera_pivot.transform.basis.z * input_vector.y) + (camera_pivot.transform.basis.x * input_vector.x))
|
||||
var vec2: Vector2 = Vector2(movement.x, movement.z).normalized()
|
||||
camera_pivot.position += Vector3(vec2.x, 0.0, vec2.y) * delta * 30.0
|
||||
|
||||
|
||||
func set_node_colors() -> void:
|
||||
for node: FlowNode in flow_field.nodes:
|
||||
if node.traversable and node.buildable:
|
||||
node.set_color(Color.WEB_GRAY)
|
||||
elif node.traversable and !node.buildable:
|
||||
node.set_color(Color.CORAL)
|
||||
else:
|
||||
node.set_color(Color.BLACK)
|
||||
if flow_field.goal_nodes.has(node):
|
||||
node.set_color(Color.BLUE)
|
||||
if flow_field.start_nodes.has(node):
|
||||
node.set_color(Color.PINK)
|
||||
if selected.has(node):
|
||||
node.set_color(Color.GREEN)
|
||||
if node == hover:
|
||||
node.set_color(Color.RED)
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseMotion:
|
||||
var from: Vector3 = camera.project_ray_origin(event.position)
|
||||
var to: Vector3 = camera.project_local_ray_normal(event.position)
|
||||
raycast.global_position = from
|
||||
raycast.target_position = to * 1000.0
|
||||
if event is InputEventMouseButton and event.button_index == 1 and hover:
|
||||
if !selected.has(hover):
|
||||
selected.append(hover)
|
||||
vector_dirty = true
|
||||
if event is InputEventMouseButton and event.button_index == 2 and selected.size() > 0:
|
||||
selected = []
|
||||
|
||||
if event is InputEventMouseButton and event.button_index == 5:
|
||||
zoom_in()
|
||||
|
||||
if event is InputEventMouseButton and event.button_index == 4:
|
||||
zoom_out()
|
||||
|
||||
if event is InputEventMouseMotion and rotate_held:
|
||||
camera_pivot.rotation.y -= (event.relative.x * get_viewport().get_final_transform().x.x) * (Data.preferences.mouse_sens / 10000.0) * (-1 if Data.preferences.invert_lookY else 1)
|
||||
up_angle -= (event.relative.y * get_viewport().get_final_transform().y.y) * (Data.preferences.mouse_sens / 10000.0) * (-1 if Data.preferences.invert_lookY else 1)
|
||||
up_angle = clamp(up_angle, deg_to_rad(-90), deg_to_rad(90))
|
||||
camera_pivot.rotation.x = up_angle
|
||||
|
||||
|
||||
func zoom_out() -> void:
|
||||
camera.position.z -= 0.3
|
||||
|
||||
|
||||
func zoom_in() -> void:
|
||||
camera.position.z += 0.3
|
||||
|
||||
|
||||
func _on_x_field_changed(text: String) -> void:
|
||||
selected[0].global_position.x = float(text)
|
||||
|
||||
|
||||
func _on_y_field_changed(text: String) -> void:
|
||||
selected[0].global_position.y = float(text)
|
||||
|
||||
|
||||
func _on_z_field_changed(text: String) -> void:
|
||||
selected[0].global_position.z = float(text)
|
||||
|
||||
|
||||
func _on_create_button_pressed() -> void:
|
||||
flow_field.create_node()
|
||||
|
||||
|
||||
func _on_generate_grid_button_pressed() -> void:
|
||||
flow_field.create_grid(int(x_size_field.text), int(y_size_field.text), float(gap_field.text))
|
||||
selected.append_array(flow_field.nodes)
|
||||
|
||||
|
||||
func _on_calculate_button_pressed() -> void:
|
||||
flow_field.calculate()
|
||||
|
||||
|
||||
func _on_connect_button_pressed() -> void:
|
||||
flow_field.connect_many_nodes(selected[0], selected.slice(1, selected.size()))
|
||||
|
||||
|
||||
func _on_mark_goal_button_pressed() -> void:
|
||||
flow_field.toggle_goal(selected)
|
||||
selected = []
|
||||
vector_dirty = true
|
||||
|
||||
|
||||
func _on_mark_start_button_pressed() -> void:
|
||||
flow_field.toggle_start(selected)
|
||||
selected = []
|
||||
vector_dirty = true
|
||||
|
||||
|
||||
func _on_extrude_button_pressed() -> void:
|
||||
if selected.size() == 1:
|
||||
var node: FlowNode = flow_field.create_node(selected[0].position)
|
||||
node.add_connection(selected[0])
|
||||
selected[0].add_connection(node)
|
||||
selected[0].set_color(Color.WEB_GRAY)
|
||||
selected = []
|
||||
selected.append(node)
|
||||
vector_dirty = true
|
||||
|
||||
|
||||
func _on_toggle_traversable_button_pressed() -> void:
|
||||
for node: FlowNode in selected:
|
||||
if !flow_field.toggle_traversable(node):
|
||||
flow_field.toggle_traversable(node)
|
||||
selected = []
|
||||
return
|
||||
selected = []
|
||||
|
||||
|
||||
func _on_toggle_buildable_button_pressed() -> void:
|
||||
for node: FlowNode in selected:
|
||||
flow_field.toggle_buildable(node)
|
||||
|
||||
|
||||
#TODO: This doesnt work as you'd expect because of physics frames
|
||||
func _on_project_downwards_button_pressed() -> void:
|
||||
for node: FlowNode in selected:
|
||||
project_raycast.global_position = node.global_position + Vector3.UP
|
||||
project_raycast.target_position = Vector3.DOWN * 100.0
|
||||
await get_tree().physics_frame
|
||||
await get_tree().physics_frame
|
||||
await get_tree().physics_frame
|
||||
await get_tree().physics_frame
|
||||
if project_raycast.is_colliding():
|
||||
node.global_position = project_raycast.get_collision_point()
|
||||
|
||||
|
||||
func _on_save_button_pressed() -> void:
|
||||
var new_flow_field_data: FlowFieldData = FlowFieldData.new()
|
||||
var dict: Dictionary[FlowNode, FlowNodeData] = {}
|
||||
for node: FlowNode in flow_field.nodes:
|
||||
var new_flow_node_data: FlowNodeData = FlowNodeData.new()
|
||||
new_flow_node_data.grid_id = node.grid_id
|
||||
new_flow_node_data.grid_x = node.grid_x
|
||||
new_flow_node_data.grid_y = node.grid_y
|
||||
new_flow_node_data.position = node.global_position
|
||||
new_flow_node_data.buildable = node.buildable
|
||||
if flow_field.start_nodes.has(node):
|
||||
new_flow_node_data.type = FlowNodeData.NodeType.START
|
||||
elif flow_field.goal_nodes.has(node):
|
||||
new_flow_node_data.type = FlowNodeData.NodeType.GOAL
|
||||
else:
|
||||
new_flow_node_data.type = FlowNodeData.NodeType.STANDARD
|
||||
dict[node] = new_flow_node_data
|
||||
for node: FlowNode in flow_field.nodes:
|
||||
var flow_node_data: FlowNodeData = dict[node]
|
||||
for neighbor: FlowNode in node.connections:
|
||||
flow_node_data.connected_nodes.append(dict[neighbor])
|
||||
new_flow_field_data.nodes.append(flow_node_data)
|
||||
ResourceSaver.save(new_flow_field_data, save_path.text)
|
||||
|
||||
|
||||
func _on_load_button_pressed() -> void:
|
||||
if ResourceLoader.exists(save_path.text):
|
||||
var resource: Resource = ResourceLoader.load(save_path.text)
|
||||
if resource is FlowFieldData:
|
||||
flow_field.load_from_data(resource)
|
||||
|
||||
|
||||
func _on_trash_button_pressed() -> void:
|
||||
if flow_field:
|
||||
flow_field.queue_free()
|
||||
flow_field = FlowField.new()
|
||||
add_child(flow_field)
|
||||
1
Scenes/FlowField/flow_field_tool.gd.uid
Normal file
1
Scenes/FlowField/flow_field_tool.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://05c5q1v2nv8p
|
||||
@@ -1,14 +1,17 @@
|
||||
[gd_scene format=3 uid="uid://cccowrgelgswj"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://05c5q1v2nv8p" path="res://Scripts/flow_field_tool.gd" id="1_e7pmn"]
|
||||
[ext_resource type="Script" uid="uid://05c5q1v2nv8p" path="res://Scenes/FlowField/flow_field_tool.gd" id="1_e7pmn"]
|
||||
[ext_resource type="PackedScene" uid="uid://y1qa1g3ic8sp" path="res://Worlds/GreenPlanet/Levels/Bridge/bridge.tscn" id="2_030xf"]
|
||||
[ext_resource type="PackedScene" uid="uid://csq7if8wojp4g" path="res://Worlds/GreenPlanet/Levels/Cave/cave.tscn" id="3_xar7e"]
|
||||
|
||||
[sub_resource type="Environment" id="Environment_e7pmn"]
|
||||
ambient_light_source = 2
|
||||
ambient_light_color = Color(0.728822, 0.728822, 0.728822, 1)
|
||||
|
||||
|
||||
[node name="FlowFieldTool" type="Node" node_paths=PackedStringArray("raycast", "project_raycast", "camera", "camera_pivot", "position_field", "x_field", "y_field", "z_field", "x_size_field", "y_size_field", "gap_field", "save_path")]
|
||||
[node name="FlowFieldTool" type="Node" unique_id=897052359 node_paths=PackedStringArray("zone_holder", "raycast", "project_raycast", "camera", "camera_pivot", "position_field", "x_field", "y_field", "z_field", "x_size_field", "y_size_field", "gap_field", "save_path")]
|
||||
script = ExtResource("1_e7pmn")
|
||||
zone_list = Array[PackedScene]([ExtResource("2_030xf"), ExtResource("3_xar7e")])
|
||||
zone_holder = NodePath("ZoneHolder")
|
||||
raycast = NodePath("CameraFocus/Camera3D/RayCast3D")
|
||||
project_raycast = NodePath("RayCast3D")
|
||||
camera = NodePath("CameraFocus/Camera3D")
|
||||
@@ -24,8 +27,16 @@ save_path = NodePath("VBoxContainer/FileNameInput")
|
||||
metadata/_custom_type_script = "uid://05c5q1v2nv8p"
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=1159336300]
|
||||
offset_right = 296.0
|
||||
anchors_preset = 1
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
offset_left = -173.0
|
||||
offset_bottom = 572.0
|
||||
grow_horizontal = 0
|
||||
|
||||
[node name="Button" type="Button" parent="VBoxContainer" unique_id=1948996218]
|
||||
layout_mode = 2
|
||||
text = "Trash FlowField"
|
||||
|
||||
[node name="Create" type="Button" parent="VBoxContainer" unique_id=1093532280]
|
||||
layout_mode = 2
|
||||
@@ -89,24 +100,24 @@ text = "Extrude"
|
||||
layout_mode = 2
|
||||
text = "Calculate"
|
||||
|
||||
<<<<<<< HEAD
|
||||
[node name="Finalize" type="Button" parent="VBoxContainer" unique_id=1604655281]
|
||||
=======
|
||||
[node name="FileNameInput" type="LineEdit" parent="VBoxContainer"]
|
||||
>>>>>>> 48b1add (first flow field resource draft)
|
||||
layout_mode = 2
|
||||
text = "Finalize"
|
||||
|
||||
[node name="FileNameInput" type="LineEdit" parent="VBoxContainer" unique_id=1302446264]
|
||||
layout_mode = 2
|
||||
placeholder_text = "level title"
|
||||
alignment = 1
|
||||
|
||||
[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer"]
|
||||
[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer" unique_id=426824804]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Save" type="Button" parent="VBoxContainer/HBoxContainer2"]
|
||||
[node name="Save" type="Button" parent="VBoxContainer/HBoxContainer2" unique_id=128915038]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Save"
|
||||
|
||||
[node name="Load" type="Button" parent="VBoxContainer/HBoxContainer2"]
|
||||
[node name="Load" type="Button" parent="VBoxContainer/HBoxContainer2" unique_id=397086630]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Load"
|
||||
@@ -135,14 +146,30 @@ size_flags_horizontal = 3
|
||||
[node name="CameraFocus" type="Node3D" parent="." unique_id=1567712529]
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="CameraFocus" unique_id=1970273041]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.34202, 0.939693, 0, -0.939693, 0.34202, 0, 8.50452, 3.40739)
|
||||
transform = Transform3D(1, 0, 0, 0, 1.0000002, 0, 0, 0, 1.0000002, 0, 0, 3)
|
||||
environment = SubResource("Environment_e7pmn")
|
||||
|
||||
[node name="RayCast3D" type="RayCast3D" parent="CameraFocus/Camera3D" unique_id=1801773920]
|
||||
collision_mask = 64
|
||||
|
||||
[node name="CSGSphere3D" type="CSGSphere3D" parent="CameraFocus" unique_id=275568945]
|
||||
|
||||
[node name="RayCast3D" type="RayCast3D" parent="." unique_id=431196612]
|
||||
|
||||
[node name="ZoneHolder" type="Node3D" parent="." unique_id=1127890663]
|
||||
|
||||
[node name="VBoxContainer2" type="HBoxContainer" parent="." unique_id=1656150952]
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
|
||||
[node name="OptionButton" type="OptionButton" parent="VBoxContainer2" unique_id=298744483]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Button" type="Button" parent="VBoxContainer2" unique_id=1468940506]
|
||||
layout_mode = 2
|
||||
text = "Load zone"
|
||||
|
||||
[connection signal="pressed" from="VBoxContainer/Button" to="." method="_on_trash_button_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/Create" to="." method="_on_create_button_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/Delete" to="." method="_on_create_button_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/HBoxContainer/GenerateGrid" to="." method="_on_generate_grid_button_pressed"]
|
||||
@@ -159,3 +186,4 @@ collision_mask = 64
|
||||
[connection signal="text_changed" from="Position/x" to="." method="_on_x_field_changed"]
|
||||
[connection signal="text_changed" from="Position/y" to="." method="_on_y_field_changed"]
|
||||
[connection signal="text_changed" from="Position/z" to="." method="_on_z_field_changed"]
|
||||
[connection signal="pressed" from="VBoxContainer2/Button" to="." method="load_zone"]
|
||||
|
||||
67
Scenes/FlowField/flow_node.gd
Normal file
67
Scenes/FlowField/flow_node.gd
Normal file
@@ -0,0 +1,67 @@
|
||||
class_name FlowNode
|
||||
extends StaticBody3D
|
||||
|
||||
@export var connections: Array[FlowNode]
|
||||
@export var visualisers: Array[Node3D]
|
||||
@export var traversable: bool = true
|
||||
@export var buildable: bool = true
|
||||
|
||||
var visual_scene: PackedScene = preload("res://Scenes/FlowField/cube2.tscn")
|
||||
var grid_id: int = -1
|
||||
var grid_x: int = 0
|
||||
var grid_y: int = 0
|
||||
var best_path: FlowNode :
|
||||
get():
|
||||
return best_path
|
||||
set(value):
|
||||
set_connector_color(best_path, Color.DARK_GRAY)
|
||||
best_path = value
|
||||
set_connector_color(best_path, Color.DARK_GREEN)
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
visualisers = []
|
||||
for node: FlowNode in connections:
|
||||
var visual: Node3D = visual_scene.instantiate()
|
||||
add_child(visual)
|
||||
visual.owner = self
|
||||
visualisers.append(visual)
|
||||
set_connector_color(node, Color.WEB_GRAY)
|
||||
|
||||
|
||||
@warning_ignore("unused_parameter")
|
||||
func _process(delta: float) -> void:
|
||||
if visible:
|
||||
for i: int in connections.size():
|
||||
var distance: float = global_position.distance_to(connections[i].global_position)
|
||||
visualisers[i].scale = Vector3(0.3, 0.3, 1.0 * (distance / 2.0))
|
||||
visualisers[i].position = to_local(connections[i].global_position) / 4.0
|
||||
if distance >= 0.05:
|
||||
visualisers[i].look_at(connections[i].global_position)
|
||||
|
||||
|
||||
func set_color(new_color: Color) -> void:
|
||||
$flow_node/Sphere.material_override.albedo_color = new_color
|
||||
|
||||
|
||||
func set_connector_color(node: FlowNode, new_color: Color) -> void:
|
||||
if visible:
|
||||
var i: int = connections.find(node)
|
||||
visualisers[i].get_child(0).material_override.albedo_color = new_color
|
||||
|
||||
|
||||
func add_connection(node: FlowNode) -> void:
|
||||
if !connections.has(node):
|
||||
var visual: Node3D = visual_scene.instantiate()
|
||||
add_child(visual)
|
||||
visual.owner = self
|
||||
connections.append(node)
|
||||
visualisers.append(visual)
|
||||
set_connector_color(node, Color.WEB_GRAY)
|
||||
|
||||
|
||||
func remove_connection(node: FlowNode) -> void:
|
||||
if connections.has(node):
|
||||
var i: int = connections.find(node)
|
||||
visualisers.pop_at(i).queue_free()
|
||||
connections.remove_at(i)
|
||||
1
Scenes/FlowField/flow_node.gd.uid
Normal file
1
Scenes/FlowField/flow_node.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c86ygtor5tksd
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_scene format=3 uid="uid://bssfvyxv5uo1f"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c86ygtor5tksd" path="res://Scripts/flow_node.gd" id="1_ng65h"]
|
||||
[ext_resource type="Script" uid="uid://c86ygtor5tksd" path="res://Scenes/FlowField/flow_node.gd" id="1_ng65h"]
|
||||
[ext_resource type="PackedScene" uid="uid://h7el2c2awv6" path="res://Scenes/FlowField/flow_node2.tscn" id="2_bmgs5"]
|
||||
|
||||
[sub_resource type="SphereShape3D" id="SphereShape3D_bmgs5"]
|
||||
|
||||
17
Scenes/FlowField/flow_node_data.gd
Normal file
17
Scenes/FlowField/flow_node_data.gd
Normal file
@@ -0,0 +1,17 @@
|
||||
class_name FlowNodeData
|
||||
extends Resource
|
||||
|
||||
enum NodeType {
|
||||
STANDARD = 0,
|
||||
START = 1,
|
||||
GOAL = 2,
|
||||
}
|
||||
|
||||
@export var position: Vector3 = Vector3.ZERO
|
||||
@export var type: NodeType = NodeType.STANDARD
|
||||
@export var buildable: bool = true
|
||||
@export var connected_nodes: Array[FlowNodeData]
|
||||
@export var in_grid: bool = false
|
||||
@export var grid_id: int = -1
|
||||
@export var grid_x: int = 0
|
||||
@export var grid_y: int = 0
|
||||
1
Scenes/FlowField/flow_node_data.gd.uid
Normal file
1
Scenes/FlowField/flow_node_data.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://udtpnemisl0t
|
||||
Reference in New Issue
Block a user