From b325976139db654836a3f272606518ef6d2a61d2 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Wed, 15 Jan 2020 14:42:24 -0500 Subject: [PATCH 1/5] Add path following toy demo --- project/demos/follow_path/Drawer.gd | 57 +++++++++++++++++++ project/demos/follow_path/FollowPathDemo.gd | 8 +++ project/demos/follow_path/FollowPathDemo.tscn | 25 +++++++- project/demos/follow_path/PathFollower.gd | 43 ++++++++++++++ project/project.godot | 4 -- project/src/GSTPath.gd | 31 ++++++---- project/src/behaviors/GSTFollowPath.gd | 4 +- 7 files changed, 153 insertions(+), 19 deletions(-) create mode 100644 project/demos/follow_path/Drawer.gd create mode 100644 project/demos/follow_path/FollowPathDemo.gd create mode 100644 project/demos/follow_path/PathFollower.gd diff --git a/project/demos/follow_path/Drawer.gd b/project/demos/follow_path/Drawer.gd new file mode 100644 index 0000000..b14ee8d --- /dev/null +++ b/project/demos/follow_path/Drawer.gd @@ -0,0 +1,57 @@ +extends Node2D + + +signal path_established(points) + + +var active_points: = [] +var drawing: = false +var distance_threshold: = 100.0 + + +func _unhandled_input(event: InputEvent) -> void: + if event is InputEventMouseMotion: + if drawing: + active_points.append(event.position) + update() + elif event is InputEventMouseButton: + if event.pressed and event.button_index == BUTTON_LEFT: + active_points.clear() + active_points.append(event.position) + drawing = true + update() + elif not event.pressed: + drawing = false + _simplify() + + +func _draw() -> void: + if drawing: + for point in active_points: + draw_circle(point, 1, Color.red) + else: + if active_points.size() > 0: + draw_circle(active_points.front(), 2, Color.red) + draw_circle(active_points.back(), 2, Color.yellow) + for i in range(1, active_points.size()): + var start: Vector2 = active_points[i-1] + var end: Vector2 = active_points[i] + draw_line(start, end, Color.skyblue) + + +func _simplify() -> void: + var first: Vector2 = active_points.front() + var last: Vector2 = active_points.back() + var key: = first + var simplified_path: = [first] + for i in range(1, active_points.size()): + var point: Vector2 = active_points[i] + var distance: = point.distance_to(key) + if distance > distance_threshold: + key = point + simplified_path.append(key) + active_points = simplified_path + if active_points.back() != last: + active_points.append(last) + update() + emit_signal("path_established", active_points) diff --git a/project/demos/follow_path/FollowPathDemo.gd b/project/demos/follow_path/FollowPathDemo.gd new file mode 100644 index 0000000..62b2703 --- /dev/null +++ b/project/demos/follow_path/FollowPathDemo.gd @@ -0,0 +1,8 @@ +extends Node2D + + +onready var drawer: = $Drawer + + +func _ready() -> void: + $PathFollower.setup() diff --git a/project/demos/follow_path/FollowPathDemo.tscn b/project/demos/follow_path/FollowPathDemo.tscn index ee075a6..b5cf5a8 100644 --- a/project/demos/follow_path/FollowPathDemo.tscn +++ b/project/demos/follow_path/FollowPathDemo.tscn @@ -1,3 +1,26 @@ -[gd_scene format=2] +[gd_scene load_steps=6 format=2] + +[ext_resource path="res://demos/follow_path/Drawer.gd" type="Script" id=1] +[ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=2] +[ext_resource path="res://demos/follow_path/PathFollower.gd" type="Script" id=3] +[ext_resource path="res://demos/follow_path/FollowPathDemo.gd" type="Script" id=4] + +[sub_resource type="CircleShape2D" id=1] +radius = 16.0 [node name="FollowPathDemo" type="Node2D"] +script = ExtResource( 4 ) + +[node name="Drawer" type="Node2D" parent="."] +script = ExtResource( 1 ) + +[node name="PathFollower" type="KinematicBody2D" parent="."] +position = Vector2( 512, 300 ) +script = ExtResource( 3 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="PathFollower"] +shape = SubResource( 1 ) + +[node name="Sprite" type="Sprite" parent="PathFollower"] +modulate = Color( 0.960784, 0.231373, 0.0392157, 1 ) +texture = ExtResource( 2 ) diff --git a/project/demos/follow_path/PathFollower.gd b/project/demos/follow_path/PathFollower.gd new file mode 100644 index 0000000..b66405a --- /dev/null +++ b/project/demos/follow_path/PathFollower.gd @@ -0,0 +1,43 @@ +extends KinematicBody2D + + +onready var agent: = GSTSteeringAgent.new() +onready var path: = GSTPath.new([ + Vector3(global_position.x, global_position.y, 0), + Vector3(global_position.x, global_position.y, 0) + ], true) +onready var follow: = GSTFollowPath.new(agent, path, 20, 0) + +var _velocity: = Vector2.ZERO +var _accel: = GSTTargetAcceleration.new() +var _valid: = false + + +func setup() -> void: + owner.drawer.connect("path_established", self, "_on_Drawer_path_established") + agent.max_linear_acceleration = 20 + agent.max_linear_speed = 200 + + +func _physics_process(delta: float) -> void: + if _valid: + _update_agent() + _accel = follow.calculate_steering(_accel) + _velocity += Vector2(_accel.linear.x, _accel.linear.y) + _velocity = _velocity.clamped(agent.max_linear_speed) + _velocity = move_and_slide(_velocity) + + +func _update_agent() -> void: + agent.position.x = global_position.x + agent.position.y = global_position.y + agent.linear_velocity.x = _velocity.x + agent.linear_velocity.y = _velocity.y + + +func _on_Drawer_path_established(points: Array) -> void: + var points3: = [] + for p in points: + points3.append(Vector3(p.x, p.y, 0)) + path.create_path(points3) + _valid = true diff --git a/project/project.godot b/project/project.godot index 8a29bcd..fc258be 100644 --- a/project/project.godot +++ b/project/project.godot @@ -161,10 +161,6 @@ _global_script_class_icons={ config/name="SteeringToolkit" config/icon="res://icon.png" -[display] - -window/size/always_on_top=true - [input] sf_left={ diff --git a/project/src/GSTPath.gd b/project/src/GSTPath.gd index 4277025..1f6e502 100644 --- a/project/src/GSTPath.gd +++ b/project/src/GSTPath.gd @@ -7,7 +7,7 @@ class_name GSTPath var open: bool -var path_length: float +var length: float var _segments: Array @@ -16,7 +16,7 @@ var _nearest_point_on_path: Vector3 func _init(waypoints: Array, is_open: = false) -> void: - self.is_open = is_open + open = is_open create_path(waypoints) _nearest_point_on_segment = waypoints[0] _nearest_point_on_path = waypoints[0] @@ -25,10 +25,11 @@ func _init(waypoints: Array, is_open: = false) -> void: func create_path(waypoints: Array) -> void: if not waypoints or waypoints.size() < 2: printerr("Waypoints cannot be null and must contain at least two (2) waypoints.") + return _segments = [] - path_length = 0 - var current: Vector3 = _segments[0] + length = 0 + var current: Vector3 = waypoints.front() var previous: Vector3 for i in range(1, waypoints.size(), 1): @@ -38,14 +39,16 @@ func create_path(waypoints: Array) -> void: elif open: break else: - current = waypoints[0] + current = waypoints.front() var segment: = GSTSegment.new(previous, current) - path_length += segment.length - segment.cumulative_length = path_length + length += segment.length + segment.cumulative_length = length _segments.append(segment) func calculate_distance(agent_current_position: Vector3, path_parameter: Dictionary) -> float: + if _segments.size() == 0: + return 0.0 var smallest_distance_squared: float = INF var nearest_segment: GSTSegment for i in range(_segments.size()): @@ -53,7 +56,8 @@ func calculate_distance(agent_current_position: Vector3, path_parameter: Diction var distance_squared: = _calculate_point_segment_distance_squared( segment.begin, segment.end, - agent_current_position) + agent_current_position + ) if distance_squared < smallest_distance_squared: _nearest_point_on_path = _nearest_point_on_segment @@ -72,12 +76,12 @@ func calculate_distance(agent_current_position: Vector3, path_parameter: Diction func calculate_target_position(param: Dictionary, target_distance: float) -> Vector3: if open: - target_distance = clamp(target_distance, 0, path_length) + target_distance = clamp(target_distance, 0, length) else: if target_distance < 0: - target_distance = path_length + fmod(target_distance, path_length) - elif target_distance > path_length: - target_distance = fmod(target_distance, path_length) + target_distance = length + fmod(target_distance, length) + elif target_distance > length: + target_distance = fmod(target_distance, length) var desired_segment: GSTSegment for i in range(_segments.size()): @@ -86,6 +90,9 @@ func calculate_target_position(param: Dictionary, target_distance: float) -> Vec desired_segment = segment break + if not desired_segment: + desired_segment = _segments.back() + var distance: = desired_segment.cumulative_length - target_distance return ( diff --git a/project/src/behaviors/GSTFollowPath.gd b/project/src/behaviors/GSTFollowPath.gd index 49699a3..d870fee 100644 --- a/project/src/behaviors/GSTFollowPath.gd +++ b/project/src/behaviors/GSTFollowPath.gd @@ -6,7 +6,7 @@ class_name GSTFollowPath var path: GSTPath var path_offset: = 0.0 -var path_param: = {} +var path_param: = {segment_index = 0, distance = 0} var arrive_enabled: = true var prediction_time: = 0.0 @@ -32,7 +32,7 @@ func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAccele var target_position: = path.calculate_target_position(path_param, target_distance) - if arrive_enabled and path.is_open: + if arrive_enabled and path.open: if path_offset >= 0: if target_distance > path.length - deceleration_radius: return _arrive(acceleration, target_position) From dde2825bdec556c832e22dc240c449ce26b9e2e8 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Thu, 16 Jan 2020 11:08:23 -0500 Subject: [PATCH 2/5] Fix divide by 0 bug in FollowPath demo --- project/demos/FollowPath/Drawer.gd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/project/demos/FollowPath/Drawer.gd b/project/demos/FollowPath/Drawer.gd index 52a6c19..0f8e912 100644 --- a/project/demos/FollowPath/Drawer.gd +++ b/project/demos/FollowPath/Drawer.gd @@ -22,7 +22,8 @@ func _unhandled_input(event: InputEvent) -> void: update() elif not event.pressed: drawing = false - _simplify() + if active_points.size() >= 2: + _simplify() func _draw() -> void: From 6e6f27505cbebf86e717661e6b56c2fd629b5fbd Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Thu, 16 Jan 2020 12:31:02 -0500 Subject: [PATCH 3/5] Fix init time setters and export Follow variables The use of `not is_inside_tree()` before setting the setting class' value meant that the starting values would always be the default. Moving the value setting before checking for tree readiness fixes the issue. --- project/demos/Arrive/ArriveDemo.gd | 12 ++-- project/demos/Face/FaceDemo.gd | 20 +++--- project/demos/Face/Turret.gd | 2 +- project/demos/FollowPath/FollowPathDemo.gd | 67 ++++++++++++++++++- project/demos/FollowPath/FollowPathDemo.tscn | 28 +++++++- project/demos/FollowPath/PathFollower.gd | 21 ++++-- .../GroupBehaviors/GroupBehaviorsDemo.gd | 26 +++---- .../GroupBehaviors/GroupBehaviorsDemo.tscn | 30 ++++++++- project/demos/GroupBehaviors/Member.gd | 3 +- project/demos/PursueSeek/BoundaryManager.gd | 2 +- project/demos/PursueSeek/Player.gd | 2 +- project/demos/PursueSeek/PursueVSSeekDemo.gd | 12 ++-- .../demos/PursueSeek/PursueVSSeekDemo.tscn | 3 +- project/demos/PursueSeek/Pursuer.gd | 15 +++-- project/demos/SeekFlee/SeekFleeDemo.gd | 8 +-- 15 files changed, 190 insertions(+), 61 deletions(-) diff --git a/project/demos/Arrive/ArriveDemo.gd b/project/demos/Arrive/ArriveDemo.gd index 5fd9bc1..bb44db2 100644 --- a/project/demos/Arrive/ArriveDemo.gd +++ b/project/demos/Arrive/ArriveDemo.gd @@ -2,7 +2,7 @@ extends Node2D export(float, 0, 2000, 40) var max_linear_speed := 800.0 setget set_max_linear_speed -export(float, 0, 200, 1) var max_linear_acceleration := 80.0 setget set_max_linear_acceleration +export(float, 0, 200, 2.0) var max_linear_acceleration := 80.0 setget set_max_linear_acceleration export(float, 0, 100, 0.1) var arrival_tolerance := 25.0 setget set_arrival_tolerance export(float, 0, 500, 10) var deceleration_radius := 125.0 setget set_deceleration_radius @@ -36,34 +36,32 @@ func _draw(): func set_arrival_tolerance(value: float) -> void: + arrival_tolerance = value if not is_inside_tree(): return - arrival_tolerance = value arriver.arrive.arrival_tolerance = value - update() func set_deceleration_radius(value: float) -> void: + deceleration_radius = value if not is_inside_tree(): return - deceleration_radius = value arriver.arrive.deceleration_radius = value - update() func set_max_linear_speed(value: float) -> void: + max_linear_speed = value if not is_inside_tree(): return - max_linear_speed = value arriver.agent.max_linear_speed = value func set_max_linear_acceleration(value: float) -> void: + max_linear_acceleration = value if not is_inside_tree(): return - max_linear_acceleration = value arriver.agent.max_linear_acceleration = value diff --git a/project/demos/Face/FaceDemo.gd b/project/demos/Face/FaceDemo.gd index 28028b0..f7fa933 100644 --- a/project/demos/Face/FaceDemo.gd +++ b/project/demos/Face/FaceDemo.gd @@ -5,11 +5,11 @@ onready var player := $Player onready var gui := $GUI onready var turret := $Turret -export(int, 0, 359) var max_angular_speed := 90 setget set_max_angular_speed -export(int, 0, 359) var max_angular_accel := 5 setget set_max_angular_accel -export(int, 0, 180) var align_tolerance := 5 setget set_align_tolerance -export(int, 0, 359) var deceleration_radius := 45 setget set_deceleration_radius -export(float, 0, 1000) var player_speed := 600.0 setget set_player_speed +export(int, 0, 359, 2) var max_angular_speed := 120 setget set_max_angular_speed +export(int, 0, 359, 2) var max_angular_accel := 10 setget set_max_angular_accel +export(int, 0, 180, 2) var align_tolerance := 5 setget set_align_tolerance +export(int, 0, 359, 2) var deceleration_radius := 45 setget set_deceleration_radius +export(float, 0, 1000, 40) var player_speed := 600.0 setget set_player_speed func _ready() -> void: @@ -24,40 +24,40 @@ func _ready() -> void: func set_align_tolerance(value: int) -> void: + align_tolerance = value if not is_inside_tree(): return - align_tolerance = value turret.face.alignment_tolerance = deg2rad(value) func set_deceleration_radius(value: int) -> void: + deceleration_radius = value if not is_inside_tree(): return - deceleration_radius = value turret.face.deceleration_radius = deg2rad(value) func set_max_angular_accel(value: int) -> void: + max_angular_accel = value if not is_inside_tree(): return - max_angular_accel = value turret.agent.max_angular_acceleration = deg2rad(value) func set_max_angular_speed(value: int) -> void: + max_angular_speed = value if not is_inside_tree(): return - max_angular_speed = value turret.agent.max_angular_speed = deg2rad(value) func set_player_speed(value: float) -> void: + player_speed = value if not is_inside_tree(): return - player_speed = value player.speed = player_speed diff --git a/project/demos/Face/Turret.gd b/project/demos/Face/Turret.gd index 3e0cdff..2b90411 100644 --- a/project/demos/Face/Turret.gd +++ b/project/demos/Face/Turret.gd @@ -5,7 +5,7 @@ var face: GSTFace var agent := GSTSteeringAgent.new() var _accel := GSTTargetAcceleration.new() -var _angular_drag := 0.01 +var _angular_drag := 0.1 var _cannon: Rect2 onready var collision_shape := $CollisionShape2D diff --git a/project/demos/FollowPath/FollowPathDemo.gd b/project/demos/FollowPath/FollowPathDemo.gd index e990711..081b358 100644 --- a/project/demos/FollowPath/FollowPathDemo.gd +++ b/project/demos/FollowPath/FollowPathDemo.gd @@ -1,8 +1,71 @@ extends Node2D -onready var drawer := $Drawer +export(float, 0, 2000, 40) var max_linear_speed := 600.0 setget set_max_linear_speed +export(float, 0, 200, 10.0) var max_linear_acceleration := 40.0 setget set_max_linear_acceleration +export(float, 0, 100, 0.1) var arrival_tolerance := 10.0 setget set_arrival_tolerance +export(float, 0, 500, 10) var deceleration_radius := 100.0 setget set_deceleration_radius +export(float, 0, 5, 0.1) var predict_time := 0.3 setget set_predict_time +export(float, 0, 200, 10.0) var path_offset := 20.0 setget set_path_offset + +onready var drawer := $Drawer +onready var follower := $PathFollower func _ready() -> void: - $PathFollower.setup() + follower.setup( + path_offset, + predict_time, + max_linear_acceleration, + max_linear_speed, + deceleration_radius, + arrival_tolerance + ) + + +func set_max_linear_speed(value: float) -> void: + max_linear_speed = value + if not is_inside_tree(): + return + + follower.agent.max_linear_speed = value + + +func set_max_linear_acceleration(value: float) -> void: + max_linear_acceleration = value + if not is_inside_tree(): + return + + follower.agent.max_linear_acceleration = value + + +func set_arrival_tolerance(value: float) -> void: + arrival_tolerance = value + if not is_inside_tree(): + return + + follower.follow.arrival_tolerance = value + + +func set_deceleration_radius(value: float) -> void: + deceleration_radius = value + if not is_inside_tree(): + return + + follower.follow.deceleration_radius = value + + +func set_predict_time(value: float) -> void: + predict_time = value + if not is_inside_tree(): + return + + follower.follow.prediction_time = value + + +func set_path_offset(value: float) -> void: + path_offset = value + if not is_inside_tree(): + return + + follower.follow.path_offset = value diff --git a/project/demos/FollowPath/FollowPathDemo.tscn b/project/demos/FollowPath/FollowPathDemo.tscn index d73659b..05b440b 100644 --- a/project/demos/FollowPath/FollowPathDemo.tscn +++ b/project/demos/FollowPath/FollowPathDemo.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=6 format=2] +[gd_scene load_steps=7 format=2] [ext_resource path="res://demos/FollowPath/Drawer.gd" type="Script" id=1] [ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=2] [ext_resource path="res://demos/FollowPath/PathFollower.gd" type="Script" id=3] [ext_resource path="res://demos/FollowPath/FollowPathDemo.gd" type="Script" id=4] +[ext_resource path="res://assets/theme/gdquest.theme" type="Theme" id=5] [sub_resource type="CircleShape2D" id=1] radius = 16.0 @@ -24,3 +25,28 @@ shape = SubResource( 1 ) [node name="Sprite" type="Sprite" parent="PathFollower"] modulate = Color( 0.960784, 0.231373, 0.0392157, 1 ) texture = ExtResource( 2 ) + +[node name="GUI" type="PanelContainer" parent="."] +margin_right = 1024.0 +margin_bottom = 14.0 +theme = ExtResource( 5 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="MarginContainer" type="MarginContainer" parent="GUI"] +margin_right = 1024.0 +margin_bottom = 116.0 + +[node name="RichTextLabel" type="RichTextLabel" parent="GUI/MarginContainer"] +margin_left = 16.0 +margin_top = 16.0 +margin_right = 1008.0 +margin_bottom = 100.0 +rect_min_size = Vector2( 0, 84 ) +bbcode_enabled = true +bbcode_text = "Follow Path Demo +Use the mouse to draw a path on screen and watch the [color=red]red \"Agent\"[/color] follow it to the end." +text = "Follow Path Demo +Use the mouse to draw a path on screen and watch the red \"Agent\" follow it to the end." +scroll_active = false diff --git a/project/demos/FollowPath/PathFollower.gd b/project/demos/FollowPath/PathFollower.gd index 9063acc..8b31d25 100644 --- a/project/demos/FollowPath/PathFollower.gd +++ b/project/demos/FollowPath/PathFollower.gd @@ -6,17 +6,29 @@ onready var path := GSTPath.new([ Vector3(global_position.x, global_position.y, 0), Vector3(global_position.x, global_position.y, 0) ], true) -onready var follow := GSTFollowPath.new(agent, path, 20, 0) +onready var follow := GSTFollowPath.new(agent, path, 0, 0) var _velocity := Vector2.ZERO var _accel := GSTTargetAcceleration.new() var _valid := false +var _drag := 0.1 -func setup() -> void: +func setup( + path_offset: float, + predict_time: float, + max_accel: float, + max_speed: float, + decel_radius: float, + arrival_tolerance: float + ) -> void: owner.drawer.connect("path_established", self, "_on_Drawer_path_established") - agent.max_linear_acceleration = 20 - agent.max_linear_speed = 200 + follow.path_offset = path_offset + follow.prediction_time = predict_time + agent.max_linear_acceleration = max_accel + agent.max_linear_speed = max_speed + follow.deceleration_radius = decel_radius + follow.arrival_tolerance = arrival_tolerance func _physics_process(delta: float) -> void: @@ -24,6 +36,7 @@ func _physics_process(delta: float) -> void: _update_agent() _accel = follow.calculate_steering(_accel) _velocity += Vector2(_accel.linear.x, _accel.linear.y) + _velocity = _velocity.linear_interpolate(Vector2.ZERO, _drag) _velocity = _velocity.clamped(agent.max_linear_speed) _velocity = move_and_slide(_velocity) diff --git a/project/demos/GroupBehaviors/GroupBehaviorsDemo.gd b/project/demos/GroupBehaviors/GroupBehaviorsDemo.gd index 680fd29..42a42a2 100644 --- a/project/demos/GroupBehaviors/GroupBehaviorsDemo.gd +++ b/project/demos/GroupBehaviors/GroupBehaviorsDemo.gd @@ -3,12 +3,12 @@ extends Node2D onready var spawner := $Spawner -export var max_linear_speed := 100.0 setget set_max_linear_speed -export var max_linear_accel := 25.0 setget set_max_linear_accel -export var proximity_radius := 140.0 setget set_proximity_radius -export var separation_decay_coefficient := 2000.0 setget set_separation_decay_coef -export var cohesion_strength := 0.3 setget set_cohesion_strength -export var separation_strength := 1.5 setget set_separation_strength +export(float, 0, 2000, 40.0) var max_linear_speed := 600.0 setget set_max_linear_speed +export(float, 0, 200, 2.0) var max_linear_accel := 40.0 setget set_max_linear_accel +export(float, 0, 300, 2.0) var proximity_radius := 140.0 setget set_proximity_radius +export(float, 0, 10000, 100) var separation_decay_coefficient := 2000.0 setget set_separation_decay_coef +export(float, 0, 2, 0.1) var cohesion_strength := 0.1 setget set_cohesion_strength +export(float, 0, 6, 0.1) var separation_strength := 1.5 setget set_separation_strength export var show_proximity_radius := true setget set_show_proximity_radius @@ -25,56 +25,56 @@ func _ready() -> void: func set_max_linear_speed(value: float) -> void: + max_linear_speed = value if not is_inside_tree(): return - max_linear_speed = value spawner.set_max_linear_speed(value) func set_max_linear_accel(value: float) -> void: + max_linear_accel = value if not is_inside_tree(): return - max_linear_accel = value spawner.set_max_linear_accel(value) func set_proximity_radius(value: float) -> void: + proximity_radius = value if not is_inside_tree(): return - proximity_radius = value spawner.set_proximity_radius(value) func set_show_proximity_radius(value: bool) -> void: + show_proximity_radius = value if not is_inside_tree(): return - show_proximity_radius = value spawner.set_show_proximity_radius(value) func set_separation_decay_coef(value: float) -> void: + separation_decay_coefficient = value if not is_inside_tree(): return - separation_decay_coefficient = value spawner.set_separation_decay_coef(value) func set_cohesion_strength(value: float) -> void: + cohesion_strength = value if not is_inside_tree(): return - cohesion_strength = value spawner.set_cohesion_strength(value) func set_separation_strength(value: float) -> void: + separation_strength = value if not is_inside_tree(): return - separation_strength = value spawner.set_separation_strength(value) diff --git a/project/demos/GroupBehaviors/GroupBehaviorsDemo.tscn b/project/demos/GroupBehaviors/GroupBehaviorsDemo.tscn index 536c138..fe8461c 100644 --- a/project/demos/GroupBehaviors/GroupBehaviorsDemo.tscn +++ b/project/demos/GroupBehaviors/GroupBehaviorsDemo.tscn @@ -1,13 +1,41 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=5 format=2] [ext_resource path="res://demos/GroupBehaviors/Member.tscn" type="PackedScene" id=1] [ext_resource path="res://demos/GroupBehaviors/Spawner.gd" type="Script" id=2] [ext_resource path="res://demos/GroupBehaviors/GroupBehaviorsDemo.gd" type="Script" id=3] +[ext_resource path="res://assets/theme/gdquest.theme" type="Theme" id=4] [node name="GroupBehaviorsDemo" type="Node2D"] script = ExtResource( 3 ) +cohesion_strength = 0.2 +separation_strength = 4.5 [node name="Spawner" type="Node2D" parent="."] position = Vector2( 512, 300 ) script = ExtResource( 2 ) member = ExtResource( 1 ) + +[node name="GUI" type="PanelContainer" parent="."] +margin_right = 1024.0 +margin_bottom = 14.0 +theme = ExtResource( 4 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="MarginContainer" type="MarginContainer" parent="GUI"] +margin_right = 1024.0 +margin_bottom = 116.0 + +[node name="RichTextLabel" type="RichTextLabel" parent="GUI/MarginContainer"] +margin_left = 16.0 +margin_top = 16.0 +margin_right = 1008.0 +margin_bottom = 100.0 +rect_min_size = Vector2( 0, 84 ) +bbcode_enabled = true +bbcode_text = "Group Behavior Demo +Each of the \"Agents\" are both attempting to stay separated and within reach of their nearest group's center of mass." +text = "Group Behavior Demo +Each of the \"Agents\" are both attempting to stay separated and within reach of their nearest group's center of mass." +scroll_active = false diff --git a/project/demos/GroupBehaviors/Member.gd b/project/demos/GroupBehaviors/Member.gd index 31d6386..37e9a09 100644 --- a/project/demos/GroupBehaviors/Member.gd +++ b/project/demos/GroupBehaviors/Member.gd @@ -40,12 +40,13 @@ func _draw() -> void: draw_circle(Vector2.ZERO, proximity.radius, Color(0, 1, 0, 0.1)) -func _process(delta: float) -> void: +func _physics_process(delta: float) -> void: agent.position.x = global_position.x agent.position.y = global_position.y if blend: acceleration = blend.calculate_steering(acceleration) _velocity += Vector2(acceleration.linear.x, acceleration.linear.y) + _velocity = _velocity.linear_interpolate(Vector2.ZERO, 0.1) _velocity = _velocity.clamped(agent.max_linear_speed) move_and_slide(_velocity) diff --git a/project/demos/PursueSeek/BoundaryManager.gd b/project/demos/PursueSeek/BoundaryManager.gd index 59f571c..1887f39 100644 --- a/project/demos/PursueSeek/BoundaryManager.gd +++ b/project/demos/PursueSeek/BoundaryManager.gd @@ -1,5 +1,5 @@ extends Node2D -# Wraps the ships' positions around the world border, and controls their rendering clones. +# Wraps the ships' positions around the world border. var _world_bounds: Vector2 diff --git a/project/demos/PursueSeek/Player.gd b/project/demos/PursueSeek/Player.gd index 66643d9..e94e84d 100644 --- a/project/demos/PursueSeek/Player.gd +++ b/project/demos/PursueSeek/Player.gd @@ -4,7 +4,7 @@ extends KinematicBody2D onready var agent := GSTSteeringAgent.new() -export var thruster_strength := 250.0 +export var thruster_strength := 175.0 export var side_thruster_strength := 10.0 export var max_velocity := 300.0 export var max_angular_velocity := 2.0 diff --git a/project/demos/PursueSeek/PursueVSSeekDemo.gd b/project/demos/PursueSeek/PursueVSSeekDemo.gd index eabd068..bd74ca4 100644 --- a/project/demos/PursueSeek/PursueVSSeekDemo.gd +++ b/project/demos/PursueSeek/PursueVSSeekDemo.gd @@ -1,9 +1,9 @@ extends Node2D -export(float, 0, 2000, 40) var max_linear_speed := 200.0 setget set_max_linear_speed -export(float, 0, 200, 1) var max_linear_accel := 10.0 setget set_max_linear_accel -export(float, 0, 5, 0.1) var predict_time := 2.0 setget set_predict_time +export(float, 0, 2000, 40) var max_linear_speed := 120.0 setget set_max_linear_speed +export(float, 0, 200, 2) var max_linear_accel := 10.0 setget set_max_linear_accel +export(float, 0, 5, 0.1) var predict_time := 1.0 setget set_predict_time onready var pursuer := $BoundaryManager/Pursuer onready var seeker := $BoundaryManager/Seeker @@ -15,26 +15,26 @@ func _ready() -> void: func set_max_linear_speed(value: float) -> void: + max_linear_speed = value if not is_inside_tree(): return - max_linear_speed = value pursuer.agent.max_linear_speed = value seeker.agent.max_linear_speed = value func set_max_linear_accel(value: float) -> void: + max_linear_accel = value if not is_inside_tree(): return - max_linear_accel = value pursuer.agent.max_linear_acceleration = value seeker.agent.max_linear_acceleration = value func set_predict_time(value: float) -> void: + predict_time = value if not is_inside_tree(): return - predict_time = value pursuer._behavior.max_predict_time = value diff --git a/project/demos/PursueSeek/PursueVSSeekDemo.tscn b/project/demos/PursueSeek/PursueVSSeekDemo.tscn index e86fc04..64aff40 100644 --- a/project/demos/PursueSeek/PursueVSSeekDemo.tscn +++ b/project/demos/PursueSeek/PursueVSSeekDemo.tscn @@ -12,8 +12,7 @@ script = ExtResource( 4 ) __meta__ = { "_editor_description_": "Toy demo to demonstrate the use of the Pursue contrasted to the more naive Seek steering behavior." } -max_linear_speed = 120.0 -predict_time = 1.0 +max_linear_speed = 200.0 [node name="BoundaryManager" type="Node2D" parent="."] script = ExtResource( 3 ) diff --git a/project/demos/PursueSeek/Pursuer.gd b/project/demos/PursueSeek/Pursuer.gd index 432beeb..195b66d 100644 --- a/project/demos/PursueSeek/Pursuer.gd +++ b/project/demos/PursueSeek/Pursuer.gd @@ -14,7 +14,7 @@ var _behavior: GSTSteeringBehavior var _linear_velocity := Vector2() var _linear_drag_coefficient := 0.025 var _angular_velocity := 0.0 -var _angular_drag := 1.0 +var _angular_drag := 0.1 func _ready() -> void: @@ -22,13 +22,16 @@ func _ready() -> void: func _physics_process(delta: float) -> void: + _update_agent() + accel = _orient_behavior.calculate_steering(accel) _angular_velocity += accel.angular - if _angular_velocity < 0: - _angular_velocity += _angular_drag * delta - elif _angular_velocity > 0: - _angular_velocity -= _angular_drag * delta + _angular_velocity = clamp( + lerp(_angular_velocity, 0, _angular_drag), + -agent.max_angular_speed, + agent.max_angular_speed + ) rotation += _angular_velocity * delta @@ -37,8 +40,6 @@ func _physics_process(delta: float) -> void: _linear_velocity = _linear_velocity.linear_interpolate(Vector2.ZERO, _linear_drag_coefficient) _linear_velocity = _linear_velocity.clamped(agent.max_linear_speed) _linear_velocity = move_and_slide(_linear_velocity) - - _update_agent() func setup(predict_time: float, max_linear_speed: float, max_linear_accel: float) -> void: diff --git a/project/demos/SeekFlee/SeekFleeDemo.gd b/project/demos/SeekFlee/SeekFleeDemo.gd index 27fd282..40fb417 100644 --- a/project/demos/SeekFlee/SeekFleeDemo.gd +++ b/project/demos/SeekFlee/SeekFleeDemo.gd @@ -43,10 +43,10 @@ func _ready() -> void: func set_behavior_mode(mode: int) -> void: + behavior_mode = mode if not is_inside_tree(): return - behavior_mode = mode match mode: Mode.SEEK: for child in spawner.get_children(): @@ -57,26 +57,26 @@ func set_behavior_mode(mode: int) -> void: func set_max_linear_speed(value: float) -> void: + max_linear_speed = value if not is_inside_tree(): return - max_linear_speed = value for child in spawner.get_children(): child.agent.max_linear_speed = value func set_max_linear_accel(value: float) -> void: + max_linear_accel = value if not is_inside_tree(): return - max_linear_accel = value for child in spawner.get_children(): child.agent.max_linear_acceleration = value func set_player_speed(value: float) -> void: + player_speed = value if not is_inside_tree(): return - player_speed = value player.speed = player_speed From dffec9efa664acd99cb5b4ffe649d7283baf1eb9 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Thu, 16 Jan 2020 17:14:50 -0500 Subject: [PATCH 4/5] Add avoid collisions demo --- .../AvoidCollisions/AvoidCollisionsDemo.gd | 41 ++++++++ .../AvoidCollisions/AvoidCollisionsDemo.tscn | 42 ++++++++ project/demos/AvoidCollisions/Avoider.gd | 95 +++++++++++++++++++ project/demos/AvoidCollisions/Avoider.tscn | 17 ++++ project/demos/AvoidCollisions/Spawner.gd | 65 +++++++++++++ project/project.godot | 4 + project/src/Behaviors/GSTArrive.gd | 2 +- project/src/Behaviors/GSTAvoidCollisions.gd | 4 +- project/src/Behaviors/GSTBlend.gd | 2 +- project/src/Behaviors/GSTCohesion.gd | 2 +- project/src/Behaviors/GSTEvade.gd | 2 +- project/src/Behaviors/GSTFace.gd | 2 +- project/src/Behaviors/GSTFlee.gd | 2 +- project/src/Behaviors/GSTFollowPath.gd | 2 +- project/src/Behaviors/GSTLookWhereYouGo.gd | 2 +- project/src/Behaviors/GSTMatchOrientation.gd | 2 +- project/src/Behaviors/GSTPriority.gd | 2 +- project/src/Behaviors/GSTPursue.gd | 2 +- project/src/Behaviors/GSTSeek.gd | 2 +- project/src/Behaviors/GSTSeparation.gd | 2 +- 20 files changed, 279 insertions(+), 15 deletions(-) create mode 100644 project/demos/AvoidCollisions/AvoidCollisionsDemo.gd create mode 100644 project/demos/AvoidCollisions/AvoidCollisionsDemo.tscn create mode 100644 project/demos/AvoidCollisions/Avoider.gd create mode 100644 project/demos/AvoidCollisions/Avoider.tscn create mode 100644 project/demos/AvoidCollisions/Spawner.gd diff --git a/project/demos/AvoidCollisions/AvoidCollisionsDemo.gd b/project/demos/AvoidCollisions/AvoidCollisionsDemo.gd new file mode 100644 index 0000000..bcb89c3 --- /dev/null +++ b/project/demos/AvoidCollisions/AvoidCollisionsDemo.gd @@ -0,0 +1,41 @@ +extends Node2D + + +export(float, 0, 2000, 40) var max_linear_speed := 350.0 setget set_max_linear_speed +export(float, 0, 100, 2) var max_linear_acceleration := 40.0 setget set_max_linear_accel +export(float, 0, 500, 10) var proximity_radius := 140.0 setget set_proximity_radius +export var draw_proximity := true setget set_draw_proximity + +onready var spawner := $Spawner + + +func set_max_linear_speed(value: float) -> void: + max_linear_speed = value + if not is_inside_tree(): + return + + spawner.set_max_linear_speed(value) + + +func set_max_linear_accel(value: float) -> void: + max_linear_acceleration = value + if not is_inside_tree(): + return + + spawner.set_max_linear_accel(value) + + +func set_proximity_radius(value: float) -> void: + proximity_radius = value + if not is_inside_tree(): + return + + spawner.set_proximity_radius(value) + + +func set_draw_proximity(value: bool) -> void: + draw_proximity = value + if not is_inside_tree(): + return + + spawner.set_draw_proximity(value) diff --git a/project/demos/AvoidCollisions/AvoidCollisionsDemo.tscn b/project/demos/AvoidCollisions/AvoidCollisionsDemo.tscn new file mode 100644 index 0000000..06e81bc --- /dev/null +++ b/project/demos/AvoidCollisions/AvoidCollisionsDemo.tscn @@ -0,0 +1,42 @@ +[gd_scene load_steps=5 format=2] + +[ext_resource path="res://demos/AvoidCollisions/Spawner.gd" type="Script" id=1] +[ext_resource path="res://demos/AvoidCollisions/AvoidCollisionsDemo.gd" type="Script" id=2] +[ext_resource path="res://demos/AvoidCollisions/Avoider.tscn" type="PackedScene" id=3] +[ext_resource path="res://assets/theme/gdquest.theme" type="Theme" id=4] + +[node name="AvoidCollisionsDemo" type="Node2D"] +script = ExtResource( 2 ) +max_linear_speed = 360.0 +proximity_radius = 100.0 + +[node name="Spawner" type="Node2D" parent="."] +script = ExtResource( 1 ) +avoider_template = ExtResource( 3 ) +normal_color = Color( 0.94902, 0.0588235, 0.0588235, 1 ) +highlight_color = Color( 0.0901961, 0.929412, 0.929412, 1 ) + +[node name="GUI" type="PanelContainer" parent="."] +margin_right = 1024.0 +margin_bottom = 14.0 +theme = ExtResource( 4 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="MarginContainer" type="MarginContainer" parent="GUI"] +margin_right = 1024.0 +margin_bottom = 116.0 + +[node name="RichTextLabel" type="RichTextLabel" parent="GUI/MarginContainer"] +margin_left = 16.0 +margin_top = 16.0 +margin_right = 1008.0 +margin_bottom = 100.0 +rect_min_size = Vector2( 0, 84 ) +bbcode_enabled = true +bbcode_text = "Avoid Collisions Demo +Watch each agent try to keep traveling in a particular direction, but prioritize avoiding collisions with other agents." +text = "Avoid Collisions Demo +Watch each agent try to keep traveling in a particular direction, but prioritize avoiding collisions with other agents." +scroll_active = false diff --git a/project/demos/AvoidCollisions/Avoider.gd b/project/demos/AvoidCollisions/Avoider.gd new file mode 100644 index 0000000..54b19cb --- /dev/null +++ b/project/demos/AvoidCollisions/Avoider.gd @@ -0,0 +1,95 @@ +extends KinematicBody2D + + +onready var collision := $CollisionShape2D +onready var agent := GSTSteeringAgent.new() +onready var proximity := GSTRadiusProximity.new(agent, [], 140) +onready var avoid := GSTAvoidCollisions.new(agent, proximity) +onready var target := GSTAgentLocation.new() +onready var seek := GSTSeek.new(agent, target) +onready var priority := GSTPriority.new(agent, 0.0001) +onready var sprite := $Sprite + +var draw_proximity: bool + +var _boundary_right: float +var _boundary_bottom: float +var _radius: float +var _accel := GSTTargetAcceleration.new() +var _velocity := Vector2.ZERO +var _direction := Vector2() +var _drag: = 0.1 + + +func _draw() -> void: + if draw_proximity: + draw_circle(Vector2.ZERO, proximity.radius, Color(0, 1, 0, 0.1)) + + +func _physics_process(delta: float) -> void: + _update_agent() + _accel = priority.calculate_steering(_accel) + _velocity += Vector2(_accel.linear.x, _accel.linear.y) + _velocity = _velocity.linear_interpolate(Vector2.ZERO, _drag) + _velocity = _velocity.clamped(agent.max_linear_speed) + _velocity = move_and_slide(_velocity) + + +func setup( + max_linear_speed: float, + max_linear_accel: float, + proximity_radius: float, + boundary_right: float, + boundary_bottom: float, + draw_proximity: bool, + rng: RandomNumberGenerator + ) -> void: + rng.randomize() + _direction = Vector2(rand_range(-1, 1), rand_range(-1, 1)).normalized() + _update_agent() + agent.max_linear_speed = max_linear_speed + agent.max_linear_acceleration = max_linear_accel + proximity.radius = proximity_radius + _boundary_bottom = boundary_bottom + _boundary_right = boundary_right + _radius = collision.shape.radius + agent.bounding_radius = _radius + + self.draw_proximity = draw_proximity + + priority.add(avoid) + priority.add(seek) + + +func set_proximity_agents(agents: Array) -> void: + proximity.agents = agents + + +func set_random_nonoverlapping_position(others: Array, min_distance_from_boundary: float) -> void: + var rng := RandomNumberGenerator.new() + rng.randomize() + var max_tries := max(100, others.size() * others.size()) + while max_tries >= 0: + max_tries -= 1 + global_position.x = rng.randf_range( + min_distance_from_boundary, _boundary_right-min_distance_from_boundary + ) + global_position.y = rng.randf_range( + min_distance_from_boundary, _boundary_bottom-min_distance_from_boundary + ) + var done := true + for i in range(others.size()): + var other: Node2D = others[i] + if other.global_position.distance_to(position) <= _radius*2 + min_distance_from_boundary: + done = false + if done: + break + + +func _update_agent() -> void: + agent.position.x = global_position.x + agent.position.y = global_position.y + agent.linear_velocity.x = _velocity.x + agent.linear_velocity.y = _velocity.y + target.position.x = agent.position.x + _direction.x*_radius + target.position.y = agent.position.y + _direction.y*_radius diff --git a/project/demos/AvoidCollisions/Avoider.tscn b/project/demos/AvoidCollisions/Avoider.tscn new file mode 100644 index 0000000..0e3386f --- /dev/null +++ b/project/demos/AvoidCollisions/Avoider.tscn @@ -0,0 +1,17 @@ +[gd_scene load_steps=4 format=2] + +[ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=1] +[ext_resource path="res://demos/AvoidCollisions/Avoider.gd" type="Script" id=2] + +[sub_resource type="CircleShape2D" id=1] +radius = 16.0 + +[node name="Avoider" type="KinematicBody2D"] +script = ExtResource( 2 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource( 1 ) + +[node name="Sprite" type="Sprite" parent="."] +modulate = Color( 0.94902, 0.211765, 0.0901961, 1 ) +texture = ExtResource( 1 ) diff --git a/project/demos/AvoidCollisions/Spawner.gd b/project/demos/AvoidCollisions/Spawner.gd new file mode 100644 index 0000000..56c889b --- /dev/null +++ b/project/demos/AvoidCollisions/Spawner.gd @@ -0,0 +1,65 @@ +extends Node2D + + +export var avoider_template: PackedScene +export var normal_color := Color() +export var highlight_color := Color() + +var boundaries: Vector2 + + +func _ready() -> void: + boundaries = Vector2(ProjectSettings["display/window/size/width"], + ProjectSettings["display/window/size/height"]) + var rng: = RandomNumberGenerator.new() + var avoiders := [] + var avoider_agents := [] + for i in range(60): + var avoider := avoider_template.instance() + add_child(avoider) + avoider.setup( + owner.max_linear_speed, + owner.max_linear_acceleration, + owner.proximity_radius, + boundaries.x, + boundaries.y, + true if i == 0 and owner.draw_proximity else false, + rng + ) + avoider_agents.append(avoider.agent) + avoider.set_random_nonoverlapping_position(avoiders, 16) + avoider.sprite.modulate = normal_color if i != 0 or not owner.draw_proximity else highlight_color + avoiders.append(avoider) + for child in get_children(): + child.set_proximity_agents(avoider_agents) + + +func _physics_process(delta: float) -> void: + for child in get_children(): + child.global_position = child.global_position.posmodv(boundaries) + + +func set_max_linear_speed(value: float) -> void: + for child in get_children(): + child.agent.max_linear_speed = value + + +func set_max_linear_accel(value: float) -> void: + for child in get_children(): + child.agent.max_linear_acceleration = value + + +func set_proximity_radius(value: float) -> void: + for child in get_children(): + child.proximity.radius = value + get_child(0).update() + + +func set_draw_proximity(value: bool) -> void: + var child := get_child(0) + child.draw_proximity = value + if not value: + child.sprite.modulate = normal_color + else: + child.sprite.modulate = highlight_color + child.update() diff --git a/project/project.godot b/project/project.godot index dfc6310..d615c5b 100644 --- a/project/project.godot +++ b/project/project.godot @@ -161,6 +161,10 @@ _global_script_class_icons={ config/name="SteeringToolkit" config/icon="res://icon.png" +[display] + +window/size/always_on_top=true + [input] sf_left={ diff --git a/project/src/Behaviors/GSTArrive.gd b/project/src/Behaviors/GSTArrive.gd index a451bd9..8c53a7b 100644 --- a/project/src/Behaviors/GSTArrive.gd +++ b/project/src/Behaviors/GSTArrive.gd @@ -1,5 +1,5 @@ -extends GSTSteeringBehavior class_name GSTArrive +extends GSTSteeringBehavior # Calculates acceleration to take an agent to its target's location. # The calculation will attempt to arrive with zero remaining velocity. diff --git a/project/src/Behaviors/GSTAvoidCollisions.gd b/project/src/Behaviors/GSTAvoidCollisions.gd index 2562b30..8fd9089 100644 --- a/project/src/Behaviors/GSTAvoidCollisions.gd +++ b/project/src/Behaviors/GSTAvoidCollisions.gd @@ -1,6 +1,6 @@ -extends GSTGroupBehavior class_name GSTAvoidCollisions -# Behavior that steers the agent to avoid obstacles lying in its path, approximated by a sphere. +extends GSTGroupBehavior +# Behavior that steers the agent to avoid obstacles lying in its path as approximated by a sphere. var first_neighbor: GSTSteeringAgent diff --git a/project/src/Behaviors/GSTBlend.gd b/project/src/Behaviors/GSTBlend.gd index 310c6fa..e84b5cd 100644 --- a/project/src/Behaviors/GSTBlend.gd +++ b/project/src/Behaviors/GSTBlend.gd @@ -1,5 +1,5 @@ -extends GSTSteeringBehavior class_name GSTBlend +extends GSTSteeringBehavior # Blends multiple steering behaviors into one, and returns acceleration combining all of them. # # Each behavior is associated with a weight - a modifier by which the result will be multiplied by, diff --git a/project/src/Behaviors/GSTCohesion.gd b/project/src/Behaviors/GSTCohesion.gd index 12fe0ac..38b8cb4 100644 --- a/project/src/Behaviors/GSTCohesion.gd +++ b/project/src/Behaviors/GSTCohesion.gd @@ -1,5 +1,5 @@ -extends GSTGroupBehavior class_name GSTCohesion +extends GSTGroupBehavior # Group behavior that produces linear acceleration that attempts to move the agent towards the # center of mass of the agents in the area defined by the defined Proximity. diff --git a/project/src/Behaviors/GSTEvade.gd b/project/src/Behaviors/GSTEvade.gd index b8448fd..9f257ab 100644 --- a/project/src/Behaviors/GSTEvade.gd +++ b/project/src/Behaviors/GSTEvade.gd @@ -1,5 +1,5 @@ -extends GSTPursue class_name GSTEvade +extends GSTPursue # Calculates acceleration to take an agent away from where a target agent will be. # # The `max_predict_time` variable represents how far ahead to calculate the intersection point. diff --git a/project/src/Behaviors/GSTFace.gd b/project/src/Behaviors/GSTFace.gd index 853acaa..45e7983 100644 --- a/project/src/Behaviors/GSTFace.gd +++ b/project/src/Behaviors/GSTFace.gd @@ -1,5 +1,5 @@ -extends GSTMatchOrientation class_name GSTFace +extends GSTMatchOrientation # Calculates angular acceleration to rotate a target to face its target's position. # The acceleration will attempt to arrive with zero remaining angular velocity. diff --git a/project/src/Behaviors/GSTFlee.gd b/project/src/Behaviors/GSTFlee.gd index 021ed24..b5565cd 100644 --- a/project/src/Behaviors/GSTFlee.gd +++ b/project/src/Behaviors/GSTFlee.gd @@ -1,5 +1,5 @@ -extends GSTSeek class_name GSTFlee +extends GSTSeek # Calculates acceleration to take an agent directly away from a target agent. diff --git a/project/src/Behaviors/GSTFollowPath.gd b/project/src/Behaviors/GSTFollowPath.gd index 9c31627..d4b2461 100644 --- a/project/src/Behaviors/GSTFollowPath.gd +++ b/project/src/Behaviors/GSTFollowPath.gd @@ -1,5 +1,5 @@ -extends GSTArrive class_name GSTFollowPath +extends GSTArrive # Produces a linear acceleration that moves the agent along the specified path. diff --git a/project/src/Behaviors/GSTLookWhereYouGo.gd b/project/src/Behaviors/GSTLookWhereYouGo.gd index 9c03af4..460233b 100644 --- a/project/src/Behaviors/GSTLookWhereYouGo.gd +++ b/project/src/Behaviors/GSTLookWhereYouGo.gd @@ -1,5 +1,5 @@ -extends GSTMatchOrientation class_name GSTLookWhereYouGo +extends GSTMatchOrientation # Calculates an angular acceleration to match an agent's orientation to its direction of travel. diff --git a/project/src/Behaviors/GSTMatchOrientation.gd b/project/src/Behaviors/GSTMatchOrientation.gd index ac89974..bb0e4dd 100644 --- a/project/src/Behaviors/GSTMatchOrientation.gd +++ b/project/src/Behaviors/GSTMatchOrientation.gd @@ -1,5 +1,5 @@ -extends GSTSteeringBehavior class_name GSTMatchOrientation +extends GSTSteeringBehavior # Calculates an angular acceleration to match an agent's orientation to its target's. # The calculation will attempt to arrive with zero remaining angular velocity. diff --git a/project/src/Behaviors/GSTPriority.gd b/project/src/Behaviors/GSTPriority.gd index cbe91ea..49c89a6 100644 --- a/project/src/Behaviors/GSTPriority.gd +++ b/project/src/Behaviors/GSTPriority.gd @@ -1,5 +1,5 @@ -extends GSTSteeringBehavior class_name GSTPriority +extends GSTSteeringBehavior # Contains multiple steering behaviors and returns only the result of the first that has a non-zero # acceleration. diff --git a/project/src/Behaviors/GSTPursue.gd b/project/src/Behaviors/GSTPursue.gd index 1e0f53b..16c4c04 100644 --- a/project/src/Behaviors/GSTPursue.gd +++ b/project/src/Behaviors/GSTPursue.gd @@ -1,5 +1,5 @@ -extends GSTSteeringBehavior class_name GSTPursue +extends GSTSteeringBehavior # Calculates acceleration to take an agent to intersect with where a target agent will be. # # The `max_predict_time` variable represents how far ahead to calculate the intersection point. diff --git a/project/src/Behaviors/GSTSeek.gd b/project/src/Behaviors/GSTSeek.gd index 7d9ee30..f2b78e4 100644 --- a/project/src/Behaviors/GSTSeek.gd +++ b/project/src/Behaviors/GSTSeek.gd @@ -1,5 +1,5 @@ -extends GSTSteeringBehavior class_name GSTSeek +extends GSTSteeringBehavior # Calculates acceleration to take an agent to a target agent's position as directly as possible diff --git a/project/src/Behaviors/GSTSeparation.gd b/project/src/Behaviors/GSTSeparation.gd index 7aa6692..110e769 100644 --- a/project/src/Behaviors/GSTSeparation.gd +++ b/project/src/Behaviors/GSTSeparation.gd @@ -1,5 +1,5 @@ -extends GSTGroupBehavior class_name GSTSeparation +extends GSTGroupBehavior # Group behavior that produces acceleration repelling from the other neighbors that are in the # immediate area defined by the given `GSTProximity`. From 0a21aaf3fccd270b3d6a510946b7de0194db3555 Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Thu, 16 Jan 2020 21:56:57 -0500 Subject: [PATCH 5/5] Fix bug using wrong random number generator --- project/demos/AvoidCollisions/Avoider.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/demos/AvoidCollisions/Avoider.gd b/project/demos/AvoidCollisions/Avoider.gd index 54b19cb..0670eb5 100644 --- a/project/demos/AvoidCollisions/Avoider.gd +++ b/project/demos/AvoidCollisions/Avoider.gd @@ -45,7 +45,7 @@ func setup( rng: RandomNumberGenerator ) -> void: rng.randomize() - _direction = Vector2(rand_range(-1, 1), rand_range(-1, 1)).normalized() + _direction = Vector2(rng.randf_range(-1, 1), rng.randf_range(-1, 1)).normalized() _update_agent() agent.max_linear_speed = max_linear_speed agent.max_linear_acceleration = max_linear_accel