diff --git a/project/demos/Arrive/Arriver.gd b/project/demos/Arrive/Arriver.gd index 9a71df8..0d3b81d 100644 --- a/project/demos/Arrive/Arriver.gd +++ b/project/demos/Arrive/Arriver.gd @@ -1,7 +1,7 @@ extends KinematicBody2D -var agent := GSTSteeringAgent.new() +var agent := GSTKinematicBody2DAgent.new(self) var target := GSTAgentLocation.new() var arrive := GSTArrive.new(agent, target) var _accel := GSTTargetAcceleration.new() @@ -11,11 +11,8 @@ var _drag := 0.1 func _physics_process(delta: float) -> void: - _update_agent() - _accel = arrive.calculate_steering(_accel) - _velocity += Vector2(_accel.linear.x, _accel.linear.y) - _velocity = _velocity.linear_interpolate(Vector2.ZERO, _drag).clamped(agent.linear_speed_max) - _velocity = move_and_slide(_velocity) + arrive.calculate_steering(_accel) + agent._apply_steering(_accel, delta) func setup( @@ -26,12 +23,7 @@ func setup( ) -> void: agent.linear_speed_max = linear_speed_max agent.linear_acceleration_max = linear_acceleration_max - agent.position = Vector3(global_position.x, global_position.y, 0) + agent.linear_drag_percentage = _drag arrive.deceleration_radius = deceleration_radius arrive.arrival_tolerance = arrival_tolerance target.position = agent.position - - -func _update_agent() -> void: - agent.position = Vector3(global_position.x, global_position.y, 0) - agent.linear_velocity = Vector3(_velocity.x, _velocity.y, 0) diff --git a/project/demos/AvoidCollisions/Avoider.gd b/project/demos/AvoidCollisions/Avoider.gd index ad87840..dfb8281 100644 --- a/project/demos/AvoidCollisions/Avoider.gd +++ b/project/demos/AvoidCollisions/Avoider.gd @@ -13,7 +13,7 @@ var _drag := 0.1 var _color := Color(0.4, 1.0, 0.89, 0.3) onready var collision := $CollisionShape2D -onready var agent := GSTSteeringAgent.new() +onready var agent := GSTKinematicBody2DAgent.new(self) onready var proximity := GSTRadiusProximity.new(agent, [], 140) onready var avoid := GSTAvoidCollisions.new(agent, proximity) onready var target := GSTAgentLocation.new() @@ -27,12 +27,11 @@ func _draw() -> void: 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.linear_speed_max) - _velocity = move_and_slide(_velocity) + target.position.x = agent.position.x + _direction.x*_radius + target.position.y = agent.position.y + _direction.y*_radius + + priority.calculate_steering(_accel) + agent._apply_steering(_accel, delta) func setup( @@ -46,15 +45,19 @@ func setup( ) -> void: rng.randomize() _direction = Vector2(rng.randf_range(-1, 1), rng.randf_range(-1, 1)).normalized() - _update_agent() + agent.linear_speed_max = linear_speed_max agent.linear_acceleration_max = linear_accel_max + proximity.radius = proximity_radius _boundary_bottom = boundary_bottom _boundary_right = boundary_right + _radius = collision.shape.radius agent.bounding_radius = _radius + agent.linear_drag_percentage = _drag + self.draw_proximity = draw_proximity priority.add(avoid) @@ -84,12 +87,3 @@ func set_random_nonoverlapping_position(others: Array, distance_from_boundary_mi 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/Face/Turret.gd b/project/demos/Face/Turret.gd index 468bf54..8326837 100644 --- a/project/demos/Face/Turret.gd +++ b/project/demos/Face/Turret.gd @@ -2,7 +2,7 @@ extends KinematicBody2D var face: GSTFace -var agent := GSTSteeringAgent.new() +var agent := GSTKinematicBody2DAgent.new(self) var _accel := GSTTargetAcceleration.new() var _angular_drag := 0.1 @@ -19,15 +19,8 @@ func _ready() -> void: func _physics_process(delta: float) -> void: - _accel = face.calculate_steering(_accel) - agent.angular_velocity = clamp( - agent.angular_velocity + _accel.angular, - -agent.angular_speed_max, - agent.angular_speed_max - ) - agent.angular_velocity = lerp(agent.angular_velocity, 0, _angular_drag) - agent.orientation += agent.angular_velocity * delta - rotation = agent.orientation + face.calculate_steering(_accel) + agent._apply_steering(_accel, delta) func _draw() -> void: @@ -48,5 +41,4 @@ func setup( agent.angular_acceleration_max = angular_accel_max agent.angular_speed_max = angular_speed_max - agent.position = Vector3(global_position.x, global_position.y, 0) - + agent.angular_drag_percentage = _angular_drag diff --git a/project/demos/FollowPath/PathFollower.gd b/project/demos/FollowPath/PathFollower.gd index c19c9a6..d9b54cb 100644 --- a/project/demos/FollowPath/PathFollower.gd +++ b/project/demos/FollowPath/PathFollower.gd @@ -6,7 +6,7 @@ var _accel := GSTTargetAcceleration.new() var _valid := false var _drag := 0.1 -onready var agent := GSTSteeringAgent.new() +onready var agent := GSTKinematicBody2DAgent.new(self) onready var path := GSTPath.new([ Vector3(global_position.x, global_position.y, 0), Vector3(global_position.x, global_position.y, 0) @@ -25,27 +25,18 @@ func setup( owner.drawer.connect("path_established", self, "_on_Drawer_path_established") follow.path_offset = path_offset follow.prediction_time = predict_time - agent.linear_acceleration_max = accel_max - agent.linear_speed_max = speed_max follow.deceleration_radius = decel_radius follow.arrival_tolerance = arrival_tolerance + + agent.linear_acceleration_max = accel_max + agent.linear_speed_max = speed_max + agent.linear_drag_percentage = _drag 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.linear_interpolate(Vector2.ZERO, _drag) - _velocity = _velocity.clamped(agent.linear_speed_max) - _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 + follow.calculate_steering(_accel) + agent._apply_steering(_accel, delta) func _on_Drawer_path_established(points: Array) -> void: diff --git a/project/demos/GroupBehaviors/Member.gd b/project/demos/GroupBehaviors/Member.gd index 43eca39..183a681 100644 --- a/project/demos/GroupBehaviors/Member.gd +++ b/project/demos/GroupBehaviors/Member.gd @@ -4,7 +4,7 @@ extends KinematicBody2D var separation: GSTSeparation var cohesion: GSTCohesion var proximity: GSTRadiusProximity -var agent := GSTSteeringAgent.new() +var agent := GSTKinematicBody2DAgent.new(self) var blend := GSTBlend.new(agent) var acceleration := GSTTargetAcceleration.new() var draw_proximity := false @@ -28,6 +28,7 @@ func setup( agent.linear_acceleration_max = linear_accel_max agent.linear_speed_max = linear_speed_max + agent.linear_drag_percentage = 0.1 proximity = GSTRadiusProximity.new(agent, [], proximity_radius) separation = GSTSeparation.new(agent, proximity) @@ -43,14 +44,9 @@ func _draw() -> 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.linear_speed_max) - move_and_slide(_velocity) + blend.calculate_steering(acceleration) + agent._apply_steering(acceleration, delta) func set_neighbors(neighbor: Array) -> void: diff --git a/project/demos/PursueSeek/Pursuer.gd b/project/demos/PursueSeek/Pursuer.gd index 133fd57..cfe4884 100644 --- a/project/demos/PursueSeek/Pursuer.gd +++ b/project/demos/PursueSeek/Pursuer.gd @@ -4,71 +4,68 @@ extends KinematicBody2D export var use_seek: bool = false -var _orient_behavior: GSTSteeringBehavior -var _behavior: GSTSteeringBehavior +var _blend: GSTBlend -var _linear_velocity := Vector2() var _linear_drag_coefficient := 0.025 -var _angular_velocity := 0.0 var _angular_drag := 0.1 var _direction_face := GSTAgentLocation.new() -onready var agent := GSTSteeringAgent.new() +onready var agent := GSTKinematicBody2DAgent.new(self) onready var accel := GSTTargetAcceleration.new() onready var player_agent: GSTSteeringAgent = owner.find_node("Player", true, false).agent func _ready() -> void: + agent.calculate_velocities = false set_physics_process(false) func _physics_process(delta: float) -> void: - _update_agent() - - accel = _behavior.calculate_steering(accel) - _direction_face.position = agent.position + accel.linear.normalized() - accel = _orient_behavior.calculate_steering(accel) - _angular_velocity += accel.angular - - _angular_velocity = clamp( - lerp(_angular_velocity, 0, _angular_drag), + _blend.calculate_steering(accel) + + agent.angular_velocity = clamp( + agent.angular_velocity + accel.angular, -agent.angular_speed_max, agent.angular_speed_max ) + agent.angular_velocity = lerp(agent.angular_velocity, 0, _angular_drag) + + rotation += agent.angular_velocity * delta - rotation += _angular_velocity * delta + var linear_velocity := ( + GSTUtils.to_vector2(agent.linear_velocity) + + (GSTUtils.angle_to_vector2(rotation) * -agent.linear_acceleration_max) + ) + linear_velocity = linear_velocity.clamped(agent.linear_speed_max) + linear_velocity = linear_velocity.linear_interpolate( + Vector2.ZERO, + _linear_drag_coefficient + ) - _linear_velocity += GSTUtils.angle_to_vector2(rotation) * -agent.linear_acceleration_max - _linear_velocity = _linear_velocity.clamped(agent.linear_speed_max) - _linear_velocity = _linear_velocity.linear_interpolate(Vector2.ZERO, _linear_drag_coefficient) - _linear_velocity = move_and_slide(_linear_velocity) + linear_velocity = move_and_slide(linear_velocity) + agent.linear_velocity = GSTUtils.to_vector3(linear_velocity) func setup(predict_time: float, linear_speed_max: float, linear_accel_max: float) -> void: + var behavior: GSTSteeringBehavior if use_seek: - _behavior = GSTSeek.new(agent, player_agent) + behavior = GSTSeek.new(agent, player_agent) else: - _behavior = GSTPursue.new(agent, player_agent, predict_time) + behavior = GSTPursue.new(agent, player_agent, predict_time) - _orient_behavior = GSTFace.new(agent, _direction_face) - _orient_behavior.alignment_tolerance = deg2rad(5) - _orient_behavior.deceleration_radius = deg2rad(5) + var orient_behavior := GSTFace.new(agent, _direction_face) + orient_behavior.alignment_tolerance = deg2rad(5) + orient_behavior.deceleration_radius = deg2rad(5) + + _blend = GSTBlend.new(agent) + _blend.add(behavior, 1) + _blend.add(orient_behavior, 1) agent.angular_acceleration_max = deg2rad(40) agent.angular_speed_max = deg2rad(90) agent.linear_acceleration_max = linear_accel_max agent.linear_speed_max = linear_speed_max - _update_agent() set_physics_process(true) - - -func _update_agent() -> void: - agent.position.x = global_position.x - agent.position.y = global_position.y - agent.orientation = rotation - agent.linear_velocity.x = _linear_velocity.x - agent.linear_velocity.y = _linear_velocity.y - agent.angular_velocity = _angular_velocity diff --git a/project/demos/SeekFlee/Seeker.gd b/project/demos/SeekFlee/Seeker.gd index d27b381..a18d111 100644 --- a/project/demos/SeekFlee/Seeker.gd +++ b/project/demos/SeekFlee/Seeker.gd @@ -1,5 +1,4 @@ extends KinematicBody2D -# AI agent that uses the Seek behavior to hone in on the player's location as directly as possible. var player_agent: GSTAgentLocation @@ -8,7 +7,7 @@ var start_speed: float var start_accel: float var use_seek := true -onready var agent := GSTSteeringAgent.new() +onready var agent := GSTKinematicBody2DAgent.new(self) onready var accel := GSTTargetAcceleration.new() onready var seek := GSTSeek.new(agent, player_agent) onready var flee := GSTFlee.new(agent, player_agent) @@ -23,18 +22,9 @@ func _physics_process(delta: float) -> void: if not player_agent: return - _update_agent() if use_seek: - accel = seek.calculate_steering(accel) + seek.calculate_steering(accel) else: - accel = flee.calculate_steering(accel) + flee.calculate_steering(accel) - velocity = (velocity + Vector2(accel.linear.x, accel.linear.y)).clamped(agent.linear_speed_max) - 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 + agent._apply_steering(accel, delta) diff --git a/project/project.godot b/project/project.godot index d615c5b..888d2b6 100644 --- a/project/project.godot +++ b/project/project.godot @@ -64,6 +64,16 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/Proximities/GSTInfiniteProximity.gd" }, { +"base": "GSTSpecializedAgent", +"class": "GSTKinematicBody2DAgent", +"language": "GDScript", +"path": "res://src/Agents/GSTKinematicBody2DAgent.gd" +}, { +"base": "GSTSpecializedAgent", +"class": "GSTKinematicBodyAgent", +"language": "GDScript", +"path": "res://src/Agents/GSTKinematicBodyAgent.gd" +}, { "base": "GSTMatchOrientation", "class": "GSTLookWhereYouGo", "language": "GDScript", @@ -99,6 +109,16 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/Proximities/GSTRadiusProximity.gd" }, { +"base": "GSTSpecializedAgent", +"class": "GSTRigidBody2DAgent", +"language": "GDScript", +"path": "res://src/Agents/GSTRigidBody2DAgent.gd" +}, { +"base": "GSTSpecializedAgent", +"class": "GSTRigidBodyAgent", +"language": "GDScript", +"path": "res://src/Agents/GSTRigidBodyAgent.gd" +}, { "base": "GSTSteeringBehavior", "class": "GSTSeek", "language": "GDScript", @@ -109,6 +129,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/Behaviors/GSTSeparation.gd" }, { +"base": "GSTSteeringAgent", +"class": "GSTSpecializedAgent", +"language": "GDScript", +"path": "res://src/Agents/GSTSpecializedAgent.gd" +}, { "base": "GSTAgentLocation", "class": "GSTSteeringAgent", "language": "GDScript", @@ -128,6 +153,11 @@ _global_script_classes=[ { "class": "GSTUtils", "language": "GDScript", "path": "res://src/GSTUtils.gd" +}, { +"base": "EditorScript", +"class": "ReferenceCollector", +"language": "GDScript", +"path": "res://ReferenceCollector.gd" } ] _global_script_class_icons={ "GSTAgentLocation": "", @@ -141,6 +171,8 @@ _global_script_class_icons={ "GSTFollowPath": "", "GSTGroupBehavior": "", "GSTInfiniteProximity": "", +"GSTKinematicBody2DAgent": "", +"GSTKinematicBodyAgent": "", "GSTLookWhereYouGo": "", "GSTMatchOrientation": "", "GSTPath": "", @@ -148,12 +180,16 @@ _global_script_class_icons={ "GSTProximity": "", "GSTPursue": "", "GSTRadiusProximity": "", +"GSTRigidBody2DAgent": "", +"GSTRigidBodyAgent": "", "GSTSeek": "", "GSTSeparation": "", +"GSTSpecializedAgent": "", "GSTSteeringAgent": "", "GSTSteeringBehavior": "", "GSTTargetAcceleration": "", -"GSTUtils": "" +"GSTUtils": "", +"ReferenceCollector": "" } [application] diff --git a/project/reference.json b/project/reference.json deleted file mode 100644 index 1e9c8ba..0000000 --- a/project/reference.json +++ /dev/null @@ -1,2238 +0,0 @@ -[ - { - "name": "GSTArrive", - "path": "res://src/Behaviors/GSTArrive.gd", - "extends_class": [ - "GSTSteeringBehavior" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTArrive", - "description": " Calculates acceleration to take an agent to its target's location. The\n calculation attempts to arrive with zero remaining velocity.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "target", - "data_type": "GSTAgentLocation", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var target: GSTAgentLocation", - "description": " Target agent to arrive to.\n" - }, - { - "name": "arrival_tolerance", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var arrival_tolerance: float", - "description": " Distance from the target for the agent to be considered successfully\n arrived.\n" - }, - { - "name": "deceleration_radius", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var deceleration_radius: float", - "description": " Distance from the target for the agent to begin slowing down.\n" - }, - { - "name": "time_to_reach", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var time_to_reach: float", - "description": " Represents the time it takes to change acceleration.\n" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, target: GSTAgentLocation) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "target", - "type": "GSTAgentLocation" - } - ] - }, - { - "name": "_arrive", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _arrive(acceleration: GSTTargetAcceleration, target_position: Vector3) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - }, - { - "name": "target_position", - "type": "Vector3" - } - ] - }, - { - "name": "_calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTAvoidCollisions", - "path": "res://src/Behaviors/GSTAvoidCollisions.gd", - "extends_class": [ - "GSTGroupBehavior" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTAvoidCollisions", - "description": " Steers the agent to avoid obstacles in its path. Approximates obstacles as\n spheres.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "_first_neighbor", - "data_type": "GSTSteeringAgent", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _first_neighbor: GSTSteeringAgent", - "description": "" - }, - { - "name": "_shortest_time", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _shortest_time: float", - "description": "" - }, - { - "name": "_first_minimum_separation", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _first_minimum_separation: float", - "description": "" - }, - { - "name": "_first_distance", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _first_distance: float", - "description": "" - }, - { - "name": "_first_relative_position", - "data_type": "Vector3", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _first_relative_position: Vector3", - "description": "" - }, - { - "name": "_first_relative_velocity", - "data_type": "Vector3", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _first_relative_velocity: Vector3", - "description": "" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, proximity: GSTProximity) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "proximity", - "type": "GSTProximity" - } - ] - }, - { - "name": "_calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - } - ] - }, - { - "name": "_report_neighbor", - "return_type": "bool", - "rpc_mode": 0, - "signature": "func _report_neighbor(neighbor: GSTSteeringAgent) -> bool", - "description": " Callback for the proximity to call when finding neighbors. Keeps track of every `neighbor`\n that was found but only keeps the one the owning agent will most likely collide with.\n tags: virtual\n", - "arguments": [ - { - "name": "neighbor", - "type": "GSTSteeringAgent" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTBlend", - "path": "res://src/Behaviors/GSTBlend.gd", - "extends_class": [ - "GSTSteeringBehavior" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTBlend", - "description": " Blends multiple steering behaviors into one, and returns a weighted\n acceleration from their calculations.\n\n Stores the behaviors internally as dictionaries of the form\n {\n \tbehavior : GSTSteeringBehavior,\n \tweight : float\n }\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "_behaviors", - "data_type": "Array", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _behaviors: Array", - "description": "" - }, - { - "name": "_accel", - "data_type": "GSTTargetAcceleration", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _accel: GSTTargetAcceleration", - "description": "" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - } - ] - }, - { - "name": "add", - "return_type": "null", - "rpc_mode": 0, - "signature": "func add(behavior: GSTSteeringBehavior, weight: float) -> null", - "description": " Appends a behavior to the internal array along with its `weight`.\n", - "arguments": [ - { - "name": "behavior", - "type": "GSTSteeringBehavior" - }, - { - "name": "weight", - "type": "float" - } - ] - }, - { - "name": "get_behavior_at", - "return_type": "Dictionary", - "rpc_mode": 0, - "signature": "func get_behavior_at(index: int) -> Dictionary", - "description": " Returns the behavior at the specified `index`, or an empty `Dictionary` if\n none was found.\n", - "arguments": [ - { - "name": "index", - "type": "int" - } - ] - }, - { - "name": "_calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _calculate_steering(blended_accel: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "blended_accel", - "type": "GSTTargetAcceleration" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTCohesion", - "path": "res://src/Behaviors/GSTCohesion.gd", - "extends_class": [ - "GSTGroupBehavior" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTCohesion", - "description": " Calculates an acceleration that attempts to move the agent towards the center\n of mass of the agents in the area defined by the `GSTProximity`.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "_center_of_mass", - "data_type": "Vector3", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _center_of_mass: Vector3", - "description": "" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, proximity: GSTProximity) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "proximity", - "type": "GSTProximity" - } - ] - }, - { - "name": "_calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - } - ] - }, - { - "name": "_report_neighbor", - "return_type": "bool", - "rpc_mode": 0, - "signature": "func _report_neighbor(neighbor: GSTSteeringAgent) -> bool", - "description": " Callback for the proximity to call when finding neighbors. Adds `neighbor`'s position\n to the center of mass of the group.\n tags: virtual\n", - "arguments": [ - { - "name": "neighbor", - "type": "GSTSteeringAgent" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTEvade", - "path": "res://src/Behaviors/GSTEvade.gd", - "extends_class": [ - "GSTPursue" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTEvade", - "description": " Calculates acceleration to take an agent away from where a target agent is\n moving.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "var", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, target: GSTSteeringAgent, predict_time_max: float = 1)", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "target", - "type": "GSTSteeringAgent" - }, - { - "name": "predict_time_max", - "type": "float", - "default_value": 1 - } - ] - }, - { - "name": "_get_modified_acceleration", - "return_type": "float", - "rpc_mode": 0, - "signature": "func _get_modified_acceleration() -> float", - "description": "", - "arguments": [ - - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTFace", - "path": "res://src/Behaviors/GSTFace.gd", - "extends_class": [ - "GSTMatchOrientation" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTFace", - "description": " Calculates angular acceleration to rotate a target to face its target's\n position. The behavior attemps to arrive with zero remaining angular velocity.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, target: GSTAgentLocation) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "target", - "type": "GSTAgentLocation" - } - ] - }, - { - "name": "_face", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _face(acceleration: GSTTargetAcceleration, target_position: Vector3) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - }, - { - "name": "target_position", - "type": "Vector3" - } - ] - }, - { - "name": "_calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTFlee", - "path": "res://src/Behaviors/GSTFlee.gd", - "extends_class": [ - "GSTSeek" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTFlee", - "description": " Calculates acceleration to take an agent directly away from a target agent.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, target: GSTAgentLocation) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "target", - "type": "GSTAgentLocation" - } - ] - }, - { - "name": "_calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTFollowPath", - "path": "res://src/Behaviors/GSTFollowPath.gd", - "extends_class": [ - "GSTArrive" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTFollowPath", - "description": " Produces a linear acceleration that moves the agent along the specified path.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "path", - "data_type": "GSTPath", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var path: GSTPath", - "description": " The path to follow and travel along.\n" - }, - { - "name": "path_offset", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var path_offset: float", - "description": " The distance along the path to generate the next target position.\n" - }, - { - "name": "is_arrive_enabled", - "data_type": "bool", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var is_arrive_enabled: bool", - "description": " Whether to use `GSTArrive` behavior on an open path.\n" - }, - { - "name": "prediction_time", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var prediction_time: float", - "description": " The amount of time in the future to predict the owning agent's position along\n the path. Setting it to 0.0 will force non-predictive path following.\n" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, path: GSTPath, path_offset: float = 0, prediction_time: float = 0) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "path", - "type": "GSTPath" - }, - { - "name": "path_offset", - "type": "float", - "default_value": 0 - }, - { - "name": "prediction_time", - "type": "float", - "default_value": 0 - } - ] - }, - { - "name": "_calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTLookWhereYouGo", - "path": "res://src/Behaviors/GSTLookWhereYouGo.gd", - "extends_class": [ - "GSTMatchOrientation" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTLookWhereYouGo", - "description": " Calculates an angular acceleration to match an agent's orientation to its\n direction of travel.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - } - ] - }, - { - "name": "_calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _calculate_steering(accel: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "accel", - "type": "GSTTargetAcceleration" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTMatchOrientation", - "path": "res://src/Behaviors/GSTMatchOrientation.gd", - "extends_class": [ - "GSTSteeringBehavior" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTMatchOrientation", - "description": " Calculates an angular acceleration to match an agent's orientation to that of\n its target. Attempts to make the agent arrive with zero remaining angular\n velocity.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "target", - "data_type": "GSTAgentLocation", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var target: GSTAgentLocation", - "description": " The target orientation for the behavior to try and match rotations to.\n" - }, - { - "name": "alignment_tolerance", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var alignment_tolerance: float", - "description": " The amount of distance in radians for the behavior to consider itself close\n enough to be matching the target agent's rotation.\n" - }, - { - "name": "deceleration_radius", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var deceleration_radius: float", - "description": " The amount of distance in radians from the goal to start slowing down.\n" - }, - { - "name": "time_to_reach", - "data_type": "float", - "default_value": 0.1, - "setter": "", - "getter": "", - "export": false, - "signature": "var time_to_reach: float = 0.1", - "description": " The amount of time to reach the target velocity\n" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, target: GSTAgentLocation) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "target", - "type": "GSTAgentLocation" - } - ] - }, - { - "name": "_match_orientation", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _match_orientation(acceleration: GSTTargetAcceleration, desired_orientation: float) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - }, - { - "name": "desired_orientation", - "type": "float" - } - ] - }, - { - "name": "_calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTPriority", - "path": "res://src/Behaviors/GSTPriority.gd", - "extends_class": [ - "GSTSteeringBehavior" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTPriority", - "description": " Container for multiple behaviors that returns the result of the first child\n behavior with non-zero acceleration.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "_behaviors", - "data_type": "Array", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _behaviors: Array", - "description": "" - }, - { - "name": "last_selected_index", - "data_type": "int", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var last_selected_index: int", - "description": " The index of the last behavior the container prioritized.\n" - }, - { - "name": "zero_threshold", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var zero_threshold: float", - "description": " If a behavior's acceleration is lower than this threshold, the container\n considers it has an acceleration of zero.\n" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, zero_threshold: float = 0.001) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "zero_threshold", - "type": "float", - "default_value": 0.001 - } - ] - }, - { - "name": "add", - "return_type": "null", - "rpc_mode": 0, - "signature": "func add(behavior: GSTSteeringBehavior) -> null", - "description": " Appends a steering behavior as a child of this container.\n", - "arguments": [ - { - "name": "behavior", - "type": "GSTSteeringBehavior" - } - ] - }, - { - "name": "get_behavior_at", - "return_type": "GSTSteeringBehavior", - "rpc_mode": 0, - "signature": "func get_behavior_at(index: int) -> GSTSteeringBehavior", - "description": " Returns the behavior at the position in the pool referred to by `index`, or\n `null` if no behavior was found.\n", - "arguments": [ - { - "name": "index", - "type": "int" - } - ] - }, - { - "name": "_calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _calculate_steering(accel: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "accel", - "type": "GSTTargetAcceleration" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTPursue", - "path": "res://src/Behaviors/GSTPursue.gd", - "extends_class": [ - "GSTSteeringBehavior" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTPursue", - "description": " Calculates an acceleration to make an agent intercept another based on the\n target agent's movement.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "target", - "data_type": "GSTSteeringAgent", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var target: GSTSteeringAgent", - "description": " The target agent that the behavior is trying to intercept.\n" - }, - { - "name": "predict_time_max", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var predict_time_max: float", - "description": " The maximum amount of time in the future the behavior predicts the target's\n location.\n" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, target: GSTSteeringAgent, predict_time_max: float = 1) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "target", - "type": "GSTSteeringAgent" - }, - { - "name": "predict_time_max", - "type": "float", - "default_value": 1 - } - ] - }, - { - "name": "_calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - } - ] - }, - { - "name": "_get_modified_acceleration", - "return_type": "float", - "rpc_mode": 0, - "signature": "func _get_modified_acceleration() -> float", - "description": "", - "arguments": [ - - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTSeek", - "path": "res://src/Behaviors/GSTSeek.gd", - "extends_class": [ - "GSTSteeringBehavior" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTSeek", - "description": " Calculates an acceleration to take an agent to a target agent's position\n directly.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "target", - "data_type": "GSTAgentLocation", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var target: GSTAgentLocation", - "description": " The target that the behavior aims to move the agent to.\n" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, target: GSTAgentLocation) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "target", - "type": "GSTAgentLocation" - } - ] - }, - { - "name": "_calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTSeparation", - "path": "res://src/Behaviors/GSTSeparation.gd", - "extends_class": [ - "GSTGroupBehavior" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTSeparation", - "description": " Calculates an acceleration that repels the agent from its neighbors in the\n given `GSTProximity`.\n\n The acceleration is an average based on all neighbors, multiplied by a\n strength decreasing by the inverse square law in relation to distance, and it\n accumulates.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "decay_coefficient", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var decay_coefficient: float", - "description": " The coefficient to calculate how fast the separation strength decays with distance.\n" - }, - { - "name": "_acceleration", - "data_type": "GSTTargetAcceleration", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _acceleration: GSTTargetAcceleration", - "description": "" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, proximity: GSTProximity) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "proximity", - "type": "GSTProximity" - } - ] - }, - { - "name": "_calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - } - ] - }, - { - "name": "_report_neighbor", - "return_type": "bool", - "rpc_mode": 0, - "signature": "func _report_neighbor(neighbor: GSTSteeringAgent) -> bool", - "description": " Callback for the proximity to call when finding neighbors. Determines the amount of\n acceleration that `neighbor` imposes based on its distance from the owner agent.\n tags: virtual\n", - "arguments": [ - { - "name": "neighbor", - "type": "GSTSteeringAgent" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTAgentLocation", - "path": "res://src/GSTAgentLocation.gd", - "extends_class": [ - - ], - "extends_file": "", - "icon": "", - "signature": "class GSTAgentLocation", - "description": " Represents an agent with only a location and an orientation.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "position", - "data_type": "Vector3", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var position: Vector3", - "description": " The agent's position in space.\n" - }, - { - "name": "orientation", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var orientation: float", - "description": " The agent's orientation on its Y axis rotation.\n" - } - ], - "signals": [ - - ], - "methods": [ - - ], - "static_functions": [ - - ] - }, - { - "name": "GSTGroupBehavior", - "path": "res://src/GSTGroupBehavior.gd", - "extends_class": [ - "GSTSteeringBehavior" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTGroupBehavior", - "description": " Base type for group-based steering behaviors.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "proximity", - "data_type": "GSTProximity", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var proximity: GSTProximity", - "description": " Container to find neighbors of the agent and calculate group behavior.\n" - }, - { - "name": "_callback", - "data_type": "FuncRef", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _callback: FuncRef", - "description": "" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, proximity: GSTProximity) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "proximity", - "type": "GSTProximity" - } - ] - }, - { - "name": "_report_neighbor", - "return_type": "bool", - "rpc_mode": 0, - "signature": "func _report_neighbor(neighbor: GSTSteeringAgent) -> bool", - "description": " Internal callback for the behavior to define whether or not a member is\n relevant\n tags: virtual\n", - "arguments": [ - { - "name": "neighbor", - "type": "GSTSteeringAgent" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTPath", - "path": "res://src/GSTPath.gd", - "extends_class": [ - "Reference" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTPath", - "description": " Represents a path made up of Vector3 waypoints, split into segments path\n follow behaviors can use.\n", - "sub_classes": [ - { - "name": "GSTSegment", - "path": "res://src/GSTPath.gd", - "extends_class": [ - - ], - "extends_file": "", - "icon": "", - "signature": "class GSTSegment", - "description": "", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "begin", - "data_type": "Vector3", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var begin: Vector3", - "description": "" - }, - { - "name": "end", - "data_type": "Vector3", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var end: Vector3", - "description": "" - }, - { - "name": "length", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var length: float", - "description": "" - }, - { - "name": "cumulative_length", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var cumulative_length: float", - "description": "" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(begin: Vector3, end: Vector3) -> null", - "description": "", - "arguments": [ - { - "name": "begin", - "type": "Vector3" - }, - { - "name": "end", - "type": "Vector3" - } - ] - } - ], - "static_functions": [ - - ] - } - ], - "constants": [ - - ], - "members": [ - { - "name": "is_open", - "data_type": "bool", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var is_open: bool", - "description": " If `false`, the path loops.\n" - }, - { - "name": "length", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var length: float", - "description": " Total length of the path.\n" - }, - { - "name": "_segments", - "data_type": "Array", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _segments: Array", - "description": "" - }, - { - "name": "_nearest_point_on_segment", - "data_type": "Vector3", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _nearest_point_on_segment: Vector3", - "description": "" - }, - { - "name": "_nearest_point_on_path", - "data_type": "Vector3", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _nearest_point_on_path: Vector3", - "description": "" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(waypoints: Array, is_open: bool = false) -> null", - "description": "", - "arguments": [ - { - "name": "waypoints", - "type": "Array" - }, - { - "name": "is_open", - "type": "bool", - "default_value": false - } - ] - }, - { - "name": "create_path", - "return_type": "null", - "rpc_mode": 0, - "signature": "func create_path(waypoints: Array) -> null", - "description": " Creates a path from a list of waypoints.\n", - "arguments": [ - { - "name": "waypoints", - "type": "Array" - } - ] - }, - { - "name": "calculate_distance", - "return_type": "float", - "rpc_mode": 0, - "signature": "func calculate_distance(agent_current_position: Vector3) -> float", - "description": " Returns the distance from `agent_current_position` to the next waypoint.\n", - "arguments": [ - { - "name": "agent_current_position", - "type": "Vector3" - } - ] - }, - { - "name": "calculate_target_position", - "return_type": "Vector3", - "rpc_mode": 0, - "signature": "func calculate_target_position(target_distance: float) -> Vector3", - "description": " Calculates a target position from the path's starting point based on the `target_distance`.\n", - "arguments": [ - { - "name": "target_distance", - "type": "float" - } - ] - }, - { - "name": "get_start_point", - "return_type": "Vector3", - "rpc_mode": 0, - "signature": "func get_start_point() -> Vector3", - "description": " Returns the position of the first point on the path.\n", - "arguments": [ - - ] - }, - { - "name": "get_end_point", - "return_type": "Vector3", - "rpc_mode": 0, - "signature": "func get_end_point() -> Vector3", - "description": " Returns the position of the last point on the path.\n", - "arguments": [ - - ] - }, - { - "name": "_calculate_point_segment_distance_squared", - "return_type": "float", - "rpc_mode": 0, - "signature": "func _calculate_point_segment_distance_squared(start: Vector3, end: Vector3, position: Vector3) -> float", - "description": "", - "arguments": [ - { - "name": "start", - "type": "Vector3" - }, - { - "name": "end", - "type": "Vector3" - }, - { - "name": "position", - "type": "Vector3" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTSteeringAgent", - "path": "res://src/GSTSteeringAgent.gd", - "extends_class": [ - "GSTAgentLocation" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTSteeringAgent", - "description": " Adds velocity, speed, and size data to `GSTAgentLocation`.\n\n It is the character's responsibility to keep this information up to date for\n the steering toolkit to work correctly.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "zero_linear_speed_threshold", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var zero_linear_speed_threshold: float", - "description": " The amount of velocity to be considered effectively not moving.\n" - }, - { - "name": "linear_speed_max", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var linear_speed_max: float", - "description": " The maximum speed at which the agent can move.\n" - }, - { - "name": "linear_acceleration_max", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var linear_acceleration_max: float", - "description": " The maximum amount of acceleration that any behavior can apply to the agent.\n" - }, - { - "name": "angular_speed_max", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var angular_speed_max: float", - "description": " The maximum amount of angular speed at which the agent can rotate.\n" - }, - { - "name": "angular_acceleration_max", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var angular_acceleration_max: float", - "description": " The maximum amount of angular acceleration that any behavior can apply to an\n agent.\n" - }, - { - "name": "linear_velocity", - "data_type": "Vector3", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var linear_velocity: Vector3", - "description": " Current velocity of the agent.\n" - }, - { - "name": "angular_velocity", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var angular_velocity: float", - "description": " Current angular velocity of the agent.\n" - }, - { - "name": "bounding_radius", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var bounding_radius: float", - "description": " The radius of the sphere that approximates the agent's size in space.\n" - }, - { - "name": "is_tagged", - "data_type": "bool", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var is_tagged: bool", - "description": " Used internally by group behaviors and proximities to mark the agent as already\n considered.\n" - } - ], - "signals": [ - - ], - "methods": [ - - ], - "static_functions": [ - - ] - }, - { - "name": "GSTSteeringBehavior", - "path": "res://src/GSTSteeringBehavior.gd", - "extends_class": [ - - ], - "extends_file": "", - "icon": "", - "signature": "class GSTSteeringBehavior", - "description": " Base class for all steering behaviors.\n\n Steering behaviors calculate the linear and the angular acceleration to be\n to the agent that owns them.\n\n The `calculate_steering` function is the entry point for all behaviors.\n Individual steering behaviors encapsulate the steering logic.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "is_enabled", - "data_type": "bool", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var is_enabled: bool", - "description": " If `false`, all calculations return zero amounts of acceleration.\n" - }, - { - "name": "agent", - "data_type": "GSTSteeringAgent", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var agent: GSTSteeringAgent", - "description": " The AI agent on which the steering behavior bases its calculations.\n" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - } - ] - }, - { - "name": "calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": " Returns the `acceleration` modified with the behavior's desired amount of\n acceleration.\n", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - } - ] - }, - { - "name": "_calculate_steering", - "return_type": "GSTTargetAcceleration", - "rpc_mode": 0, - "signature": "func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration", - "description": "", - "arguments": [ - { - "name": "acceleration", - "type": "GSTTargetAcceleration" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTTargetAcceleration", - "path": "res://src/GSTTargetAcceleration.gd", - "extends_class": [ - - ], - "extends_file": "", - "icon": "", - "signature": "class GSTTargetAcceleration", - "description": " A desired linear and angular amount of acceleration requested by the steering\n system.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "linear", - "data_type": "Vector3", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var linear: Vector3", - "description": " Linear acceleration\n" - }, - { - "name": "angular", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var angular: float", - "description": " Angular acceleration\n" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "set_zero", - "return_type": "null", - "rpc_mode": 0, - "signature": "func set_zero() -> null", - "description": " Sets the linear and angular components to 0.\n", - "arguments": [ - - ] - }, - { - "name": "add_scaled_accel", - "return_type": "null", - "rpc_mode": 0, - "signature": "func add_scaled_accel(accel: GSTTargetAcceleration, scalar: float) -> null", - "description": " Adds `accel`'s components, multiplied by `scalar`, to this one.\n", - "arguments": [ - { - "name": "accel", - "type": "GSTTargetAcceleration" - }, - { - "name": "scalar", - "type": "float" - } - ] - }, - { - "name": "get_magnitude_squared", - "return_type": "float", - "rpc_mode": 0, - "signature": "func get_magnitude_squared() -> float", - "description": " Returns the squared magnitude of the linear and angular components.\n", - "arguments": [ - - ] - }, - { - "name": "get_magnitude", - "return_type": "float", - "rpc_mode": 0, - "signature": "func get_magnitude() -> float", - "description": " Returns the magnitude of the linear and angular components.\n", - "arguments": [ - - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTUtils", - "path": "res://src/GSTUtils.gd", - "extends_class": [ - - ], - "extends_file": "", - "icon": "", - "signature": "class GSTUtils", - "description": " Math and vector utility functions.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - - ], - "signals": [ - - ], - "methods": [ - - ], - "static_functions": [ - { - "name": "clampedv3", - "return_type": "Vector3", - "rpc_mode": 0, - "signature": "func clampedv3(vector: Vector3, limit: float) -> Vector3", - "description": " Returns the `vector` with its length capped to `limit`.\n", - "arguments": [ - { - "name": "vector", - "type": "Vector3" - }, - { - "name": "limit", - "type": "float" - } - ] - }, - { - "name": "vector3_to_angle", - "return_type": "float", - "rpc_mode": 0, - "signature": "func vector3_to_angle(vector: Vector3) -> float", - "description": " Returns an angle in radians between the positive X axis and the `vector`.\n\n This assumes orientation for 2D agents or 3D agents that are upright and\n rotate around the Y axis.\n", - "arguments": [ - { - "name": "vector", - "type": "Vector3" - } - ] - }, - { - "name": "angle_to_vector2", - "return_type": "Vector2", - "rpc_mode": 0, - "signature": "func angle_to_vector2(angle: float) -> Vector2", - "description": " Returns a directional vector from the given orientation angle.\n \n This assumes orientation for 2D agents or 3D agents that are upright and\n rotate around the Y axis.\n", - "arguments": [ - { - "name": "angle", - "type": "float" - } - ] - } - ] - }, - { - "name": "GSTInfiniteProximity", - "path": "res://src/Proximities/GSTInfiniteProximity.gd", - "extends_class": [ - "GSTProximity" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTInfiniteProximity", - "description": " Determines any agent that is in the specified list as being neighbors with the\n owner agent, regardless of distance.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, agents: Array) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "agents", - "type": "Array" - } - ] - }, - { - "name": "_find_neighbors", - "return_type": "int", - "rpc_mode": 0, - "signature": "func _find_neighbors(callback: FuncRef) -> int", - "description": " Returns a number of neighbors based on a `callback` function.\n\n `_find_neighbors` calls `callback` for each agent in the `agents` array and\n adds one to the count if its `callback` returns true.\n tags: virtual\n", - "arguments": [ - { - "name": "callback", - "type": "FuncRef" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTProximity", - "path": "res://src/Proximities/GSTProximity.gd", - "extends_class": [ - "Reference" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTProximity", - "description": " Base container type that stores data to find the neighbors of an agent.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "agent", - "data_type": "GSTSteeringAgent", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var agent: GSTSteeringAgent", - "description": " The owning agent whose neighbors are found in the group\n" - }, - { - "name": "agents", - "data_type": "Array", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var agents: Array", - "description": " The agents who are part of this group and could be potential neighbors\n" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, agents: Array) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "agents", - "type": "Array" - } - ] - }, - { - "name": "_find_neighbors", - "return_type": "int", - "rpc_mode": 0, - "signature": "func _find_neighbors(callback: FuncRef) -> int", - "description": " Returns a number of neighbors based on a `callback` function.\n\n `_find_neighbors` calls `callback` for each agent in the `agents` array and\n adds one to the count if its `callback` returns true.\n tags: virtual\n", - "arguments": [ - { - "name": "callback", - "type": "FuncRef" - } - ] - } - ], - "static_functions": [ - - ] - }, - { - "name": "GSTRadiusProximity", - "path": "res://src/Proximities/GSTRadiusProximity.gd", - "extends_class": [ - "GSTProximity" - ], - "extends_file": "", - "icon": "", - "signature": "class GSTRadiusProximity", - "description": " Determines any agent that is in the specified list as being neighbors with the owner agent if\n they lie within the specified radius.\n", - "sub_classes": [ - - ], - "constants": [ - - ], - "members": [ - { - "name": "radius", - "data_type": "float", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var radius: float", - "description": " The radius around the owning agent to find neighbors in\n" - }, - { - "name": "_last_frame", - "data_type": "int", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _last_frame: int", - "description": "" - }, - { - "name": "_scene_tree", - "data_type": "SceneTree", - "default_value": null, - "setter": "", - "getter": "", - "export": false, - "signature": "var _scene_tree: SceneTree", - "description": "" - } - ], - "signals": [ - - ], - "methods": [ - { - "name": "_init", - "return_type": "null", - "rpc_mode": 0, - "signature": "func _init(agent: GSTSteeringAgent, agents: Array, radius: float) -> null", - "description": "", - "arguments": [ - { - "name": "agent", - "type": "GSTSteeringAgent" - }, - { - "name": "agents", - "type": "Array" - }, - { - "name": "radius", - "type": "float" - } - ] - }, - { - "name": "_find_neighbors", - "return_type": "int", - "rpc_mode": 0, - "signature": "func _find_neighbors(callback: FuncRef) -> int", - "description": " Returns a number of neighbors based on a `callback` function.\n\n `_find_neighbors` calls `callback` for each agent in the `agents` array that lie within\n the radius around the owning agent and adds one to the count if its `callback` returns true.\n tags: virtual\n", - "arguments": [ - { - "name": "callback", - "type": "FuncRef" - } - ] - } - ], - "static_functions": [ - - ] - } -] \ No newline at end of file diff --git a/project/src/Agents/GSTKinematicBody2DAgent.gd b/project/src/Agents/GSTKinematicBody2DAgent.gd new file mode 100644 index 0000000..4e01ba9 --- /dev/null +++ b/project/src/Agents/GSTKinematicBody2DAgent.gd @@ -0,0 +1,134 @@ +# A specialized steering agent that updates itself every frame so the user does +# not have to using a KinematicBody2D +extends GSTSpecializedAgent +class_name GSTKinematicBody2DAgent + + +# SLIDE uses `move_and_slide` +# COLLIDE uses `move_and_collide` +# POSITION changes the `global_position` directly +enum MovementType { SLIDE, COLLIDE, POSITION } + + +# The KinematicBody2D to keep track of +var body: KinematicBody2D setget _set_body + +# The type of movement the body executes +var movement_type: int + +var _last_position: Vector2 + + +func _init(body: KinematicBody2D, movement_type: int = MovementType.SLIDE) -> void: + if not body.is_inside_tree(): + yield(body, "ready") + + self.body = body + self.movement_type = movement_type + + body.get_tree().connect("physics_frame", self, "_on_SceneTree_physics_frame") + + +# Moves the agent's `body` by target `acceleration`. +# tags: virtual +func _apply_steering(acceleration: GSTTargetAcceleration, delta: float) -> void: + _applied_steering = true + match movement_type: + MovementType.COLLIDE: + _apply_collide_steering(acceleration.linear, delta) + MovementType.SLIDE: + _apply_sliding_steering(acceleration.linear) + _: + _apply_position_steering(acceleration.linear, delta) + + _apply_orientation_steering(acceleration.angular, delta) + + +func _apply_sliding_steering(accel: Vector3) -> void: + var velocity := GSTUtils.to_vector2(linear_velocity + accel).clamped(linear_speed_max) + if apply_linear_drag: + velocity = velocity.linear_interpolate(Vector2.ZERO, linear_drag_percentage) + velocity = body.move_and_slide(velocity) + if calculate_velocities: + linear_velocity = GSTUtils.to_vector3(velocity) + + +func _apply_collide_steering(accel: Vector3, delta: float) -> void: + var velocity := GSTUtils.clampedv3(linear_velocity + accel, linear_speed_max) + if apply_linear_drag: + velocity = velocity.linear_interpolate( + Vector3.ZERO, + linear_drag_percentage + ) + body.move_and_collide(GSTUtils.to_vector2(velocity) * delta) + if calculate_velocities: + linear_velocity = velocity + + +func _apply_position_steering(accel: Vector3, delta: float) -> void: + var velocity := GSTUtils.clampedv3(linear_velocity + accel, linear_speed_max) + if apply_linear_drag: + velocity = velocity.linear_interpolate( + Vector3.ZERO, + linear_drag_percentage + ) + body.global_position += GSTUtils.to_vector2(velocity) * delta + if calculate_velocities: + linear_velocity = velocity + + +func _apply_orientation_steering(angular_acceleration: float, delta: float) -> void: + var velocity = angular_velocity + angular_acceleration + if apply_angular_drag: + velocity = lerp(velocity, 0, angular_drag_percentage) + body.rotation += velocity * delta + if calculate_velocities: + angular_velocity = velocity + + +func _set_body(value: KinematicBody2D) -> void: + body = value + + _last_position = body.global_position + _last_orientation = body.rotation + + position = GSTUtils.to_vector3(_last_position) + orientation = _last_orientation + + +func _on_SceneTree_physics_frame() -> void: + var current_position: Vector2 = body.global_position + var current_orientation: float = body.rotation + + position = GSTUtils.to_vector3(current_position) + orientation = current_orientation + + if calculate_velocities: + if _applied_steering: + _applied_steering = false + else: + linear_velocity = GSTUtils.clampedv3( + GSTUtils.to_vector3(_last_position - current_position), + linear_speed_max + ) + if apply_linear_drag: + linear_velocity = linear_velocity.linear_interpolate( + Vector3.ZERO, + linear_drag_percentage + ) + + angular_velocity = clamp( + _last_orientation - current_orientation, + -angular_speed_max, + angular_speed_max + ) + + if apply_angular_drag: + angular_velocity = lerp( + angular_velocity, + 0, + angular_drag_percentage + ) + + _last_position = current_position + _last_orientation = current_orientation diff --git a/project/src/Agents/GSTKinematicBodyAgent.gd b/project/src/Agents/GSTKinematicBodyAgent.gd new file mode 100644 index 0000000..da84d23 --- /dev/null +++ b/project/src/Agents/GSTKinematicBodyAgent.gd @@ -0,0 +1,133 @@ +# A specialized steering agent that updates itself every frame so the user does +# not have to using a KinematicBody +extends GSTSpecializedAgent +class_name GSTKinematicBodyAgent + +# SLIDE uses `move_and_slide` +# COLLIDE uses `move_and_collide` +# POSITION changes the global_position directly +enum MovementType { SLIDE, COLLIDE, POSITION } + + +# The KinematicBody to keep track of +var body: KinematicBody setget _set_body + +# The type of movement the body executes +var movement_type: int + +var _last_position: Vector3 + + +func _init(body: KinematicBody, movement_type: int = MovementType.SLIDE) -> void: + if not body.is_inside_tree(): + yield(body, "ready") + + self.body = body + self.movement_type = movement_type + + body.get_tree().connect("physics_frame", self, "_on_SceneTree_physics_frame") + + +# Moves the agent's `body` by target `acceleration`. +# tags: virtual +func _apply_steering(acceleration: GSTTargetAcceleration, delta: float) -> void: + _applied_steering = true + match movement_type: + MovementType.COLLIDE: + _apply_collide_steering(acceleration.linear, delta) + MovementType.SLIDE: + _apply_sliding_steering(acceleration.linear) + _: + _apply_position_steering(acceleration.linear, delta) + + _apply_orientation_steering(acceleration.angular, delta) + + +func _apply_sliding_steering(accel: Vector3) -> void: + var velocity := GSTUtils.clampedv3(linear_velocity + accel, linear_speed_max) + if apply_linear_drag: + velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage) + velocity = body.move_and_slide(velocity) + if calculate_velocities: + linear_velocity = velocity + + +func _apply_collide_steering(accel: Vector3, delta: float) -> void: + var velocity := GSTUtils.clampedv3(linear_velocity + accel, linear_speed_max) + if apply_linear_drag: + velocity = velocity.linear_interpolate( + Vector3.ZERO, + linear_drag_percentage + ) + body.move_and_collide(velocity * delta) + if calculate_velocities: + linear_velocity = velocity + + +func _apply_position_steering(accel: Vector3, delta: float) -> void: + var velocity := GSTUtils.clampedv3(linear_velocity + accel, linear_speed_max) + if apply_linear_drag: + velocity = velocity.linear_interpolate( + Vector3.ZERO, + linear_drag_percentage + ) + body.global_position += velocity * delta + if calculate_velocities: + linear_velocity = velocity + + +func _apply_orientation_steering(angular_acceleration: float, delta: float) -> void: + var velocity = angular_velocity + angular_acceleration + if apply_angular_drag: + velocity = lerp(velocity, 0, angular_drag_percentage) + body.rotation.y += velocity * delta + if calculate_velocities: + angular_velocity = velocity + + +func _set_body(value: KinematicBody) -> void: + body = value + + _last_position = body.global_position + _last_orientation = body.rotation.y + + position = _last_position + orientation = _last_orientation + + +func _on_SceneTree_physics_frame() -> void: + var current_position: Vector3 = body.global_position + var current_orientation: float = body.rotation.y + + position = current_position + orientation = current_orientation + + if calculate_velocities: + if _applied_steering: + _applied_steering = false + else: + linear_velocity = GSTUtils.clampedv3( + _last_position - current_position, + linear_speed_max + ) + if apply_linear_drag: + linear_velocity = linear_velocity.linear_interpolate( + Vector3.ZERO, + linear_drag_percentage + ) + + angular_velocity = clamp( + _last_orientation - current_orientation, + -angular_speed_max, + angular_speed_max + ) + + if apply_angular_drag: + angular_velocity = lerp( + angular_velocity, + 0, + angular_drag_percentage + ) + + _last_position = current_position + _last_orientation = current_orientation diff --git a/project/src/Agents/GSTRigidBody2DAgent.gd b/project/src/Agents/GSTRigidBody2DAgent.gd new file mode 100644 index 0000000..43e2a6b --- /dev/null +++ b/project/src/Agents/GSTRigidBody2DAgent.gd @@ -0,0 +1,58 @@ +# A specialized steering agent that updates itself every frame so the user does +# not have to using a RigidBody2D +extends GSTSpecializedAgent +class_name GSTRigidBody2DAgent + + +# The RigidBody2D to keep track of +var body: RigidBody2D setget _set_body + +var _last_position: Vector2 + + +func _init(body: RigidBody2D) -> void: + if not body.is_inside_tree(): + yield(body, "ready") + + self.body = body + + +# Moves the agent's `body` by target `acceleration`. +# tags: virtual +func _apply_steering(acceleration: GSTTargetAcceleration, delta: float) -> void: + _applied_steering = true + body.apply_central_impulse(GSTUtils.to_vector2(acceleration.linear)) + body.apply_torque_impulse(acceleration.angular) + if calculate_velocities: + linear_velocity = GSTUtils.to_vector3(body.linear_velocity) + angular_velocity = body.angular_velocity + + +func _set_body(value: RigidBody2D) -> void: + body = value + + _last_position = body.global_position + _last_orientation = body.rotation + + position = GSTUtils.to_vector3(_last_position) + orientation = _last_orientation + + +func _on_body_ready() -> void: + body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame") + _set_body(body) + + +func _on_SceneTree_frame() -> void: + var current_position: Vector2 = body.global_position + var current_orientation: float = body.rotation + + position = GSTUtils.to_vector3(current_position) + orientation = current_orientation + + if calculate_velocities: + if _applied_steering: + _applied_steering = false + else: + linear_velocity = GSTUtils.to_vector3(body.linear_velocity) + angular_velocity = body.angular_velocity diff --git a/project/src/Agents/GSTRigidBodyAgent.gd b/project/src/Agents/GSTRigidBodyAgent.gd new file mode 100644 index 0000000..c3d189c --- /dev/null +++ b/project/src/Agents/GSTRigidBodyAgent.gd @@ -0,0 +1,60 @@ +# A specialized steering agent that updates itself every frame so the user does +# not have to using a RigidBody +extends GSTSpecializedAgent +class_name GSTRigidBodyAgent + + +# The RigidBody to keep track of +var body: RigidBody setget _set_body + +var _last_position: Vector3 + + +func _init(body: RigidBody) -> void: + if not body.is_inside_tree(): + yield(body, "ready") + + self.body = body + body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame") + + + +# Moves the agent's `body` by target `acceleration`. +# tags: virtual +func _apply_steering(acceleration: GSTTargetAcceleration, delta: float) -> void: + _applied_steering = true + body.apply_central_impulse(acceleration.linear) + body.apply_torque_impulse(Vector3.UP * acceleration.angular) + if calculate_velocities: + linear_velocity = body.linear_velocity + angular_velocity = body.angular_velocity.y + + +func _set_body(value: RigidBody) -> void: + body = value + + _last_position = body.global_position + _last_orientation = body.rotation.y + + position = _last_position + orientation = _last_orientation + + +func _on_body_ready() -> void: + body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame") + _set_body(body) + + +func _on_SceneTree_frame() -> void: + var current_position: Vector3 = body.global_position + var current_orientation: float = body.rotation.y + + position = current_position + orientation = current_orientation + + if calculate_velocities: + if _applied_steering: + _applied_steering = false + else: + linear_velocity = body.linear_velocity + angular_velocity = body.angular_velocity.y diff --git a/project/src/Agents/GSTSpecializedAgent.gd b/project/src/Agents/GSTSpecializedAgent.gd new file mode 100644 index 0000000..2f97b7d --- /dev/null +++ b/project/src/Agents/GSTSpecializedAgent.gd @@ -0,0 +1,40 @@ +# A base class for a specialized steering agent that updates itself every frame +# so the user does not have to. All other specialized agents derive from this. +# tags: abstract +extends GSTSteeringAgent +class_name GSTSpecializedAgent + + +# If `true`, calculates linear and angular velocities based on the previous +# frame. When `false`, the user must keep those values updated. +var calculate_velocities := true + +# If `true` and `calculate_velocities` is true, interpolates +# the current linear velocity towards 0 by the `linear_drag_percentage` value. +# Does not apply to `RigidBody` and `RigidBody2D` nodes. +var apply_linear_drag := true + +# If `true` and `calculate_velocities` is true, interpolates +# the current angular velocity towards 0 by the `angular_drag_percentage` value. +# Does not apply to `RigidBody` and `RigidBody2D` nodes. +var apply_angular_drag := true + +# The percentage between the current linear velocity and 0 to interpolate by if +# `calculate_velocities` and `apply_linear_drag` are true. +# Does not apply to `RigidBody` and `RigidBody2D` nodes. +var linear_drag_percentage := 0.0 + +# The percentage between the current angular velocity and 0 to interpolate by if +# `calculate_velocities` and `apply_angular_drag` are true. +# Does not apply to `RigidBody` and `RigidBody2D` nodes. +var angular_drag_percentage := 0.0 + +var _last_orientation: float +var _body_type: int +var _applied_steering := false + + +# Moves the agent's body by target `acceleration`. +# tags: virtual +func _apply_steering(acceleration: GSTTargetAcceleration, delta: float) -> void: + pass diff --git a/project/src/Behaviors/GSTArrive.gd b/project/src/Behaviors/GSTArrive.gd index 8b4a8ce..17083be 100644 --- a/project/src/Behaviors/GSTArrive.gd +++ b/project/src/Behaviors/GSTArrive.gd @@ -19,7 +19,7 @@ func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void: self.target = target -func _arrive(acceleration: GSTTargetAcceleration, target_position: Vector3) -> GSTTargetAcceleration: +func _arrive(acceleration: GSTTargetAcceleration, target_position: Vector3) -> void: var to_target := target_position - agent.position var distance := to_target.length() @@ -38,8 +38,6 @@ func _arrive(acceleration: GSTTargetAcceleration, target_position: Vector3) -> G acceleration.linear = GSTUtils.clampedv3(desired_velocity, agent.linear_acceleration_max) acceleration.angular = 0 - return acceleration - -func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: - return _arrive(acceleration, target.position) +func _calculate_steering(acceleration: GSTTargetAcceleration) -> void: + _arrive(acceleration, target.position) diff --git a/project/src/Behaviors/GSTAvoidCollisions.gd b/project/src/Behaviors/GSTAvoidCollisions.gd index d00afc0..711b744 100644 --- a/project/src/Behaviors/GSTAvoidCollisions.gd +++ b/project/src/Behaviors/GSTAvoidCollisions.gd @@ -16,7 +16,7 @@ func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent, proximity) pass -func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: +func _calculate_steering(acceleration: GSTTargetAcceleration) -> void: _shortest_time = INF _first_neighbor = null _first_minimum_separation = 0 @@ -37,8 +37,6 @@ func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAccele acceleration.linear = acceleration.linear.normalized() * -agent.linear_acceleration_max acceleration.angular = 0 - return acceleration - # Callback for the proximity to call when finding neighbors. Keeps track of every `neighbor` # that was found but only keeps the one the owning agent will most likely collide with. diff --git a/project/src/Behaviors/GSTBlend.gd b/project/src/Behaviors/GSTBlend.gd index 57daff3..db20eab 100644 --- a/project/src/Behaviors/GSTBlend.gd +++ b/project/src/Behaviors/GSTBlend.gd @@ -33,7 +33,7 @@ func get_behavior_at(index: int) -> Dictionary: return {} -func _calculate_steering(blended_accel: GSTTargetAcceleration) -> GSTTargetAcceleration: +func _calculate_steering(blended_accel: GSTTargetAcceleration) -> void: blended_accel.set_zero() for i in range(_behaviors.size()): @@ -48,5 +48,3 @@ func _calculate_steering(blended_accel: GSTTargetAcceleration) -> GSTTargetAccel -agent.angular_acceleration_max, agent.angular_acceleration_max ) - - return blended_accel diff --git a/project/src/Behaviors/GSTCohesion.gd b/project/src/Behaviors/GSTCohesion.gd index 062cc43..eb2c816 100644 --- a/project/src/Behaviors/GSTCohesion.gd +++ b/project/src/Behaviors/GSTCohesion.gd @@ -11,14 +11,13 @@ func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent, proximity) pass -func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: +func _calculate_steering(acceleration: GSTTargetAcceleration) -> void: acceleration.set_zero() _center_of_mass = Vector3.ZERO var neighbor_count = proximity._find_neighbors(_callback) if neighbor_count > 0: _center_of_mass *= 1.0 / neighbor_count acceleration.linear = (_center_of_mass - agent.position).normalized() * agent.linear_acceleration_max - return acceleration # Callback for the proximity to call when finding neighbors. Adds `neighbor`'s position diff --git a/project/src/Behaviors/GSTFace.gd b/project/src/Behaviors/GSTFace.gd index 81338a5..8a97e0b 100644 --- a/project/src/Behaviors/GSTFace.gd +++ b/project/src/Behaviors/GSTFace.gd @@ -8,17 +8,16 @@ func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent, target) -> pass -func _face(acceleration: GSTTargetAcceleration, target_position: Vector3) -> GSTTargetAcceleration: +func _face(acceleration: GSTTargetAcceleration, target_position: Vector3) -> void: var to_target := target_position - agent.position var distance_squared := to_target.length_squared() if distance_squared < agent.zero_linear_speed_threshold: acceleration.set_zero() - return acceleration else: var orientation = GSTUtils.vector3_to_angle(to_target) - return _match_orientation(acceleration, orientation) + _match_orientation(acceleration, orientation) -func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: - return _face(acceleration, target.position) +func _calculate_steering(acceleration: GSTTargetAcceleration) -> void: + _face(acceleration, target.position) diff --git a/project/src/Behaviors/GSTFlee.gd b/project/src/Behaviors/GSTFlee.gd index e5aa961..86c071b 100644 --- a/project/src/Behaviors/GSTFlee.gd +++ b/project/src/Behaviors/GSTFlee.gd @@ -7,9 +7,7 @@ func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent, target) -> pass -func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: +func _calculate_steering(acceleration: GSTTargetAcceleration) -> void: acceleration.linear = ( (agent.position - target.position).normalized() * agent.linear_acceleration_max) acceleration.angular = 0 - - return acceleration diff --git a/project/src/Behaviors/GSTFollowPath.gd b/project/src/Behaviors/GSTFollowPath.gd index 9d634c9..384d2d2 100644 --- a/project/src/Behaviors/GSTFollowPath.gd +++ b/project/src/Behaviors/GSTFollowPath.gd @@ -25,7 +25,7 @@ func _init( self.prediction_time = prediction_time -func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: +func _calculate_steering(acceleration: GSTTargetAcceleration) -> void: var location := ( agent.position if prediction_time == 0 else agent.position + (agent.linear_velocity * prediction_time)) @@ -38,13 +38,13 @@ func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAccele if is_arrive_enabled and path.is_open: if path_offset >= 0: if target_distance > path.length - deceleration_radius: - return _arrive(acceleration, target_position) + _arrive(acceleration, target_position) + return else: if target_distance < deceleration_radius: - return _arrive(acceleration, target_position) + _arrive(acceleration, target_position) + return acceleration.linear = (target_position - agent.position).normalized() acceleration.linear *= agent.linear_acceleration_max acceleration.angular = 0 - - return acceleration diff --git a/project/src/Behaviors/GSTLookWhereYouGo.gd b/project/src/Behaviors/GSTLookWhereYouGo.gd index 7229e11..9e254f3 100644 --- a/project/src/Behaviors/GSTLookWhereYouGo.gd +++ b/project/src/Behaviors/GSTLookWhereYouGo.gd @@ -8,10 +8,9 @@ func _init(agent: GSTSteeringAgent).(agent, null) -> void: pass -func _calculate_steering(accel: GSTTargetAcceleration) -> GSTTargetAcceleration: +func _calculate_steering(accel: GSTTargetAcceleration) -> void: if agent.linear_velocity.length_squared() < agent.zero_linear_speed_threshold: accel.set_zero() - return accel else: var orientation := GSTUtils.vector3_to_angle(agent.linear_velocity) - return _match_orientation(accel, orientation) + _match_orientation(accel, orientation) diff --git a/project/src/Behaviors/GSTMatchOrientation.gd b/project/src/Behaviors/GSTMatchOrientation.gd index d132280..a682d70 100644 --- a/project/src/Behaviors/GSTMatchOrientation.gd +++ b/project/src/Behaviors/GSTMatchOrientation.gd @@ -20,7 +20,7 @@ func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void: self.target = target -func _match_orientation(acceleration: GSTTargetAcceleration, desired_orientation: float) -> GSTTargetAcceleration: +func _match_orientation(acceleration: GSTTargetAcceleration, desired_orientation: float) -> void: var rotation := wrapf(desired_orientation - agent.orientation, -PI, PI) var rotation_size := abs(rotation) @@ -43,8 +43,6 @@ func _match_orientation(acceleration: GSTTargetAcceleration, desired_orientation acceleration.linear = Vector3.ZERO - return acceleration - -func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: - return _match_orientation(acceleration, target.orientation) +func _calculate_steering(acceleration: GSTTargetAcceleration) -> void: + _match_orientation(acceleration, target.orientation) diff --git a/project/src/Behaviors/GSTPriority.gd b/project/src/Behaviors/GSTPriority.gd index 184b1f1..f352461 100644 --- a/project/src/Behaviors/GSTPriority.gd +++ b/project/src/Behaviors/GSTPriority.gd @@ -31,7 +31,7 @@ func get_behavior_at(index: int) -> GSTSteeringBehavior: return null -func _calculate_steering(accel: GSTTargetAcceleration) -> GSTTargetAcceleration: +func _calculate_steering(accel: GSTTargetAcceleration) -> void: var threshold_squared := zero_threshold * zero_threshold last_selected_index = -1 @@ -48,5 +48,3 @@ func _calculate_steering(accel: GSTTargetAcceleration) -> GSTTargetAcceleration: break else: accel.set_zero() - - return accel diff --git a/project/src/Behaviors/GSTPursue.gd b/project/src/Behaviors/GSTPursue.gd index f9935ba..301bdd7 100644 --- a/project/src/Behaviors/GSTPursue.gd +++ b/project/src/Behaviors/GSTPursue.gd @@ -19,7 +19,7 @@ func _init( self.predict_time_max = predict_time_max -func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: +func _calculate_steering(acceleration: GSTTargetAcceleration) -> void: var target_position := target.position var distance_squared := (target_position - agent.position).length_squared() @@ -37,8 +37,6 @@ func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAccele acceleration.angular = 0 - return acceleration - func _get_modified_acceleration() -> float: return agent.linear_acceleration_max diff --git a/project/src/Behaviors/GSTSeek.gd b/project/src/Behaviors/GSTSeek.gd index 4371f3f..61229e4 100644 --- a/project/src/Behaviors/GSTSeek.gd +++ b/project/src/Behaviors/GSTSeek.gd @@ -12,9 +12,7 @@ func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void: self.target = target -func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: +func _calculate_steering(acceleration: GSTTargetAcceleration) -> void: acceleration.linear = ( (target.position - agent.position).normalized() * agent.linear_acceleration_max) acceleration.angular = 0 - - return acceleration diff --git a/project/src/Behaviors/GSTSeparation.gd b/project/src/Behaviors/GSTSeparation.gd index 0a3252e..87bec2a 100644 --- a/project/src/Behaviors/GSTSeparation.gd +++ b/project/src/Behaviors/GSTSeparation.gd @@ -18,11 +18,10 @@ func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent, proximity) pass -func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: +func _calculate_steering(acceleration: GSTTargetAcceleration) -> void: acceleration.set_zero() self._acceleration = acceleration proximity._find_neighbors(_callback) - return acceleration # Callback for the proximity to call when finding neighbors. Determines the amount of diff --git a/project/src/GSTSteeringBehavior.gd b/project/src/GSTSteeringBehavior.gd index c89a92f..b503d15 100644 --- a/project/src/GSTSteeringBehavior.gd +++ b/project/src/GSTSteeringBehavior.gd @@ -18,16 +18,13 @@ func _init(agent: GSTSteeringAgent) -> void: self.agent = agent -# Returns the `acceleration` modified with the behavior's desired amount of -# acceleration. -func calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: +# Sets the `acceleration` with the behavior's desired amount of acceleration. +func calculate_steering(acceleration: GSTTargetAcceleration) -> void: if is_enabled: - return _calculate_steering(acceleration) + _calculate_steering(acceleration) else: acceleration.set_zero() - return acceleration -func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: +func _calculate_steering(acceleration: GSTTargetAcceleration) -> void: acceleration.set_zero() - return acceleration diff --git a/project/src/GSTUtils.gd b/project/src/GSTUtils.gd index d3e1c89..bbe5e34 100644 --- a/project/src/GSTUtils.gd +++ b/project/src/GSTUtils.gd @@ -25,3 +25,13 @@ static func vector3_to_angle(vector: Vector3) -> float: # rotate around the Y axis. static func angle_to_vector2(angle: float) -> Vector2: return Vector2(sin(-angle), cos(angle)) + + +# Returns a vector2 with `vector`'s x and y components. +static func to_vector2(vector: Vector3) -> Vector2: + return Vector2(vector.x, vector.y) + + +# Returns a vector3 with `vector`'s x and y components and 0 in z. +static func to_vector3(vector: Vector2) -> Vector3: + return Vector3(vector.x, vector.y, 0)