Style changes to make c++ conversion easier later.

This commit is contained in:
Relintai 2023-01-13 13:09:18 +01:00
parent 7388234a6e
commit 99f515f868
29 changed files with 291 additions and 311 deletions

View File

@ -7,20 +7,24 @@ class_name GSAIKinematicBody2DAgent
# SLIDE uses `move_and_slide`
# COLLIDE uses `move_and_collide`
# POSITION changes the `global_position` directly
enum MovementType { SLIDE, COLLIDE, POSITION }
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 movement_type : int = 0
var _last_position: Vector2
var _body_ref: WeakRef
var _last_position : Vector2
var _body_ref : WeakRef
func _init(_body: KinematicBody2D, _movement_type: int = MovementType.SLIDE) -> void:
if not _body.is_inside_tree():
if !_body.is_inside_tree():
yield(_body, "ready")
self.body = _body
@ -34,73 +38,82 @@ func _init(_body: KinematicBody2D, _movement_type: int = MovementType.SLIDE) ->
# @tags - virtual
func _apply_steering(acceleration: GSAITargetAcceleration, delta: float) -> void:
_applied_steering = true
match movement_type:
MovementType.COLLIDE:
_apply_collide_steering(acceleration.linear, delta)
MovementType.SLIDE:
_apply_sliding_steering(acceleration.linear, delta)
_:
_apply_position_steering(acceleration.linear, delta)
if movement_type == MovementType.COLLIDE:
_apply_collide_steering(acceleration.linear, delta)
elif movement_type == MovementType.SLIDE:
_apply_sliding_steering(acceleration.linear, delta)
else:
_apply_position_steering(acceleration.linear, delta)
_apply_orientation_steering(acceleration.angular, delta)
func _apply_sliding_steering(accel: Vector3, delta: float) -> void:
var _body: KinematicBody2D = _body_ref.get_ref()
if not _body:
if !_body:
return
if not _body.is_inside_tree() or _body.get_tree().paused:
if !_body.is_inside_tree() or _body.get_tree().paused:
return
var velocity := GSAIUtils.to_vector2(linear_velocity + accel * delta).clamped(linear_speed_max)
var velocity : Vector2 = GSAIUtils.to_vector2(linear_velocity + accel * delta).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 = GSAIUtils.to_vector3(velocity)
func _apply_collide_steering(accel: Vector3, delta: float) -> void:
var _body: KinematicBody2D = _body_ref.get_ref()
if not _body:
if !_body:
return
var velocity := GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max)
var velocity : Vector3 = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max)
if apply_linear_drag:
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage)
# warning-ignore:return_value_discarded
_body.move_and_collide(GSAIUtils.to_vector2(velocity) * delta)
if calculate_velocities:
linear_velocity = velocity
func _apply_position_steering(accel: Vector3, delta: float) -> void:
var _body: KinematicBody2D = _body_ref.get_ref()
if not _body:
if !_body:
return
var velocity := GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max)
var velocity : Vector3 = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max)
if apply_linear_drag:
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage)
_body.global_position += GSAIUtils.to_vector2(velocity) * delta
if calculate_velocities:
linear_velocity = velocity
func _apply_orientation_steering(angular_acceleration: float, delta: float) -> void:
var _body: KinematicBody2D = _body_ref.get_ref()
if not _body:
if !_body:
return
var velocity = clamp(
angular_velocity + angular_acceleration * delta,
-angular_speed_max,
angular_speed_max
)
var velocity = clamp(angular_velocity + angular_acceleration * delta, -angular_speed_max, angular_speed_max)
if apply_angular_drag:
velocity = lerp(velocity, 0, angular_drag_percentage)
_body.rotation += velocity * delta
if calculate_velocities:
angular_velocity = velocity
@ -118,11 +131,11 @@ func _set_body(value: KinematicBody2D) -> void:
func _on_SceneTree_physics_frame() -> void:
var _body: KinematicBody2D = _body_ref.get_ref()
if not _body:
if !_body:
return
var current_position := _body.global_position
var current_orientation := _body.rotation
var current_position : Vector2 = _body.global_position
var current_orientation : float = _body.rotation
position = GSAIUtils.to_vector3(current_position)
orientation = current_orientation
@ -131,17 +144,12 @@ func _on_SceneTree_physics_frame() -> void:
if _applied_steering:
_applied_steering = false
else:
linear_velocity = GSAIUtils.clampedv3(
GSAIUtils.to_vector3(current_position - _last_position), linear_speed_max
)
linear_velocity = GSAIUtils.clampedv3(GSAIUtils.to_vector3(current_position - _last_position), linear_speed_max)
if apply_linear_drag:
linear_velocity = linear_velocity.linear_interpolate(
Vector3.ZERO, linear_drag_percentage
)
linear_velocity = linear_velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage)
angular_velocity = clamp(
_last_orientation - current_orientation, -angular_speed_max, angular_speed_max
)
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)

View File

@ -7,41 +7,42 @@ class_name GSAIKinematicBody3DAgent
# SLIDE uses `move_and_slide`
# COLLIDE uses `move_and_collide`
# POSITION changes the global_position directly
enum MovementType { SLIDE, COLLIDE, POSITION }
enum MovementType {
SLIDE,
COLLIDE,
POSITION
}
# The KinematicBody to keep track of
var body: KinematicBody setget _set_body
var body : KinematicBody setget _set_body
# The type of movement the body executes
var movement_type: int
var movement_type : int = 0
var _last_position: Vector3
var _body_ref: WeakRef
var _last_position : Vector3
var _body_ref : WeakRef
func _init(_body: KinematicBody, _movement_type: int = MovementType.SLIDE) -> void:
if not _body.is_inside_tree():
if !_body.is_inside_tree():
yield(_body, "ready")
self.body = _body
self.movement_type = _movement_type
# warning-ignore:return_value_discarded
_body.get_tree().connect(
"physics_frame", self, "_on_SceneTree_physics_frame"
)
_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: GSAITargetAcceleration, delta: float) -> void:
_applied_steering = true
match movement_type:
MovementType.COLLIDE:
if movement_type == MovementType.COLLIDE:
_apply_collide_steering(acceleration.linear, delta)
MovementType.SLIDE:
elif movement_type == MovementType.SLIDE:
_apply_sliding_steering(acceleration.linear, delta)
_:
else:
_apply_position_steering(acceleration.linear, delta)
_apply_orientation_steering(acceleration.angular, delta)
@ -49,16 +50,14 @@ func _apply_steering(acceleration: GSAITargetAcceleration, delta: float) -> void
func _apply_sliding_steering(accel: Vector3, delta: float) -> void:
var _body: KinematicBody = _body_ref.get_ref()
if not _body:
if !_body:
return
var velocity := GSAIUtils.clampedv3(
linear_velocity + accel * delta, linear_speed_max
)
var velocity : Vector3 = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max)
if apply_linear_drag:
velocity = velocity.linear_interpolate(
Vector3.ZERO, linear_drag_percentage
)
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage)
velocity = _body.move_and_slide(velocity)
if calculate_velocities:
linear_velocity = velocity
@ -66,16 +65,14 @@ func _apply_sliding_steering(accel: Vector3, delta: float) -> void:
func _apply_collide_steering(accel: Vector3, delta: float) -> void:
var _body: KinematicBody = _body_ref.get_ref()
if not _body:
if !_body:
return
var velocity := GSAIUtils.clampedv3(
linear_velocity + accel * delta, linear_speed_max
)
var velocity : Vector3 = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max)
if apply_linear_drag:
velocity = velocity.linear_interpolate(
Vector3.ZERO, linear_drag_percentage
)
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage)
# warning-ignore:return_value_discarded
_body.move_and_collide(velocity * delta)
if calculate_velocities:
@ -84,34 +81,32 @@ func _apply_collide_steering(accel: Vector3, delta: float) -> void:
func _apply_position_steering(accel: Vector3, delta: float) -> void:
var _body: KinematicBody = _body_ref.get_ref()
if not _body:
if !_body:
return
var velocity := GSAIUtils.clampedv3(
linear_velocity + accel * delta, linear_speed_max
)
var velocity : Vector3 = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max)
if apply_linear_drag:
velocity = velocity.linear_interpolate(
Vector3.ZERO, linear_drag_percentage
)
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage)
_body.global_transform.origin += velocity * delta
if calculate_velocities:
linear_velocity = velocity
func _apply_orientation_steering(angular_acceleration: float, delta: float) -> void:
var _body: KinematicBody = _body_ref.get_ref()
if not _body:
if !_body:
return
var velocity = clamp(
angular_velocity + angular_acceleration * delta,
-angular_speed_max,
angular_speed_max
)
var velocity = clamp(angular_velocity + angular_acceleration * delta,-angular_speed_max,angular_speed_max)
if apply_angular_drag:
velocity = lerp(velocity, 0, angular_drag_percentage)
_body.rotation.y += velocity * delta
if calculate_velocities:
angular_velocity = velocity
@ -128,15 +123,16 @@ func _set_body(value: KinematicBody) -> void:
func _on_SceneTree_physics_frame() -> void:
var _body: KinematicBody = _body_ref.get_ref()
if not _body:
var _body : KinematicBody = _body_ref.get_ref()
if !_body:
return
if not _body.is_inside_tree() or _body.get_tree().paused:
if !_body.is_inside_tree() || _body.get_tree().paused:
return
var current_position := _body.transform.origin
var current_orientation := _body.rotation.y
var current_position : Vector3 = _body.transform.origin
var current_orientation : float = _body.rotation.y
position = current_position
orientation = current_orientation
@ -145,24 +141,15 @@ func _on_SceneTree_physics_frame() -> void:
if _applied_steering:
_applied_steering = false
else:
linear_velocity = GSAIUtils.clampedv3(
current_position - _last_position, linear_speed_max
)
linear_velocity = GSAIUtils.clampedv3(current_position - _last_position, linear_speed_max)
if apply_linear_drag:
linear_velocity = linear_velocity.linear_interpolate(
Vector3.ZERO, linear_drag_percentage
)
linear_velocity = linear_velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage)
angular_velocity = clamp(
_last_orientation - current_orientation,
-angular_speed_max,
angular_speed_max
)
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
)
angular_velocity = lerp(angular_velocity, 0, angular_drag_percentage)
_last_position = current_position
_last_orientation = current_orientation

View File

@ -5,13 +5,13 @@ extends GSAISpecializedAgent
class_name GSAIRigidBody2DAgent
# The RigidBody2D to keep track of
var body: RigidBody2D setget _set_body
var body : RigidBody2D setget _set_body
var _last_position: Vector2
var _body_ref: WeakRef
var _last_position : Vector2
var _body_ref : WeakRef
func _init(_body: RigidBody2D) -> void:
func _init(_body : RigidBody2D) -> void:
if not _body.is_inside_tree():
yield(_body, "ready")
self.body = _body
@ -22,7 +22,7 @@ func _init(_body: RigidBody2D) -> void:
# Moves the agent's `body` by target `acceleration`.
# @tags - virtual
func _apply_steering(acceleration: GSAITargetAcceleration, _delta: float) -> void:
func _apply_steering(acceleration : GSAITargetAcceleration, _delta : float) -> void:
var _body: RigidBody2D = _body_ref.get_ref()
if not _body:
return
@ -48,14 +48,14 @@ func _set_body(value: RigidBody2D) -> void:
func _on_SceneTree_frame() -> void:
var _body: RigidBody2D = _body_ref.get_ref()
if not _body:
if !_body:
return
if not _body.is_inside_tree() or _body.get_tree().paused:
if !_body.is_inside_tree() or _body.get_tree().paused:
return
var current_position := _body.global_position
var current_orientation := _body.rotation
var current_position : Vector2 = _body.global_position
var current_orientation : float = _body.rotation
position = GSAIUtils.to_vector3(current_position)
orientation = current_orientation

View File

@ -23,7 +23,7 @@ func _init(_body: RigidBody) -> void:
# @tags - virtual
func _apply_steering(acceleration: GSAITargetAcceleration, _delta: float) -> void:
var _body: RigidBody = _body_ref.get_ref()
if not _body:
if !_body:
return
_applied_steering = true
@ -53,8 +53,8 @@ func _on_SceneTree_frame() -> void:
if not _body.is_inside_tree() or _body.get_tree().paused:
return
var current_position := _body.transform.origin
var current_orientation := _body.rotation.y
var current_position : Vector3 = _body.transform.origin
var current_orientation : float = _body.rotation.y
position = current_position
orientation = current_orientation

View File

@ -7,33 +7,33 @@ class_name GSAISpecializedAgent
# 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
var calculate_velocities : bool = true
# If `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
var apply_linear_drag : bool = true
# If `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
var apply_angular_drag : bool = true
# The percentage between the current linear velocity and 0 to interpolate by if
# `apply_linear_drag` is true.
# Does not apply to `RigidBody` and `RigidBody2D` nodes.
var linear_drag_percentage := 0.0
var linear_drag_percentage : float = 0.0
# The percentage between the current angular velocity and 0 to interpolate by if
# `apply_angular_drag` is true.
# Does not apply to `RigidBody` and `RigidBody2D` nodes.
var angular_drag_percentage := 0.0
var angular_drag_percentage : float = 0.0
var _last_orientation: float
var _applied_steering := false
var _last_orientation : float = 0.0
var _applied_steering : bool = false
# Moves the agent's body by target `acceleration`.
# @tags - virtual
func _apply_steering(_acceleration: GSAITargetAcceleration, _delta: float) -> void:
func _apply_steering(_acceleration : GSAITargetAcceleration, _delta : float) -> void:
pass

View File

@ -5,33 +5,33 @@ class_name GSAIArrive
extends GSAISteeringBehavior
# Target agent to arrive to.
var target: GSAIAgentLocation
var target : GSAIAgentLocation
# Distance from the target for the agent to be considered successfully
# arrived.
var arrival_tolerance: float
var arrival_tolerance : float = 0.0
# Distance from the target for the agent to begin slowing down.
var deceleration_radius: float
var deceleration_radius : float = 0.0
# Represents the time it takes to change acceleration.
var time_to_reach := 0.1
var time_to_reach : float = 0.1
func _init(agent: GSAISteeringAgent, _target: GSAIAgentLocation).(agent) -> void:
func _init(agent : GSAISteeringAgent, _target : GSAIAgentLocation).(agent) -> void:
self.target = _target
func _arrive(acceleration: GSAITargetAcceleration, target_position: Vector3) -> void:
var to_target := target_position - agent.position
var distance := to_target.length()
func _arrive(acceleration : GSAITargetAcceleration, target_position : Vector3) -> void:
var to_target : Vector3 = target_position - agent.position
var distance : float = to_target.length()
if distance <= arrival_tolerance:
acceleration.set_zero()
else:
var desired_speed := agent.linear_speed_max
var desired_speed : float = agent.linear_speed_max
if distance <= deceleration_radius:
desired_speed *= distance / deceleration_radius
var desired_velocity := to_target * desired_speed / distance
var desired_velocity : Vector3 = to_target * desired_speed / distance
desired_velocity = ((desired_velocity - agent.linear_velocity) * 1.0 / time_to_reach)

View File

@ -5,11 +5,11 @@ class_name GSAIAvoidCollisions
extends GSAIGroupBehavior
var _first_neighbor: GSAISteeringAgent
var _shortest_time: float
var _first_minimum_separation: float
var _first_distance: float
var _first_relative_position: Vector3
var _first_relative_velocity: Vector3
var _shortest_time : float = 0.0
var _first_minimum_separation : float = 0.0
var _first_distance : float = 0.0
var _first_relative_position : Vector3
var _first_relative_velocity : Vector3
func _init(agent: GSAISteeringAgent, proximity: GSAIProximity).(agent, proximity) -> void:
@ -22,21 +22,15 @@ func _calculate_steering(acceleration: GSAITargetAcceleration) -> void:
_first_minimum_separation = 0
_first_distance = 0
var neighbor_count := proximity._find_neighbors(_callback)
var neighbor_count : int = proximity._find_neighbors(_callback)
if neighbor_count == 0 or not _first_neighbor:
acceleration.set_zero()
else:
if (
_first_minimum_separation <= 0
or _first_distance < agent.bounding_radius + _first_neighbor.bounding_radius
):
if (_first_minimum_separation <= 0 || _first_distance < agent.bounding_radius + _first_neighbor.bounding_radius):
acceleration.linear = _first_neighbor.position - agent.position
else:
acceleration.linear = (
_first_relative_position
+ (_first_relative_velocity * _shortest_time)
)
acceleration.linear = (_first_relative_position+ (_first_relative_velocity * _shortest_time))
acceleration.linear = (acceleration.linear.normalized() * -agent.linear_acceleration_max)
acceleration.angular = 0
@ -46,23 +40,21 @@ func _calculate_steering(acceleration: GSAITargetAcceleration) -> void:
# that was found but only keeps the one the owning agent will most likely collide with.
# @tags - virtual
func _report_neighbor(neighbor: GSAISteeringAgent) -> bool:
var relative_position := neighbor.position - agent.position
var relative_velocity := neighbor.linear_velocity - agent.linear_velocity
var relative_speed_squared := relative_velocity.length_squared()
var relative_position : Vector3 = neighbor.position - agent.position
var relative_velocity : Vector3 = neighbor.linear_velocity - agent.linear_velocity
var relative_speed_squared : float = relative_velocity.length_squared()
if relative_speed_squared == 0:
return false
else:
var time_to_collision = -relative_position.dot(relative_velocity) / relative_speed_squared
var time_to_collision : float = -relative_position.dot(relative_velocity) / relative_speed_squared
if time_to_collision <= 0 or time_to_collision >= _shortest_time:
if time_to_collision <= 0 || time_to_collision >= _shortest_time:
return false
else:
var distance = relative_position.length()
var minimum_separation: float = (
distance
- sqrt(relative_speed_squared) * time_to_collision
)
var minimum_separation: float = (distance - sqrt(relative_speed_squared) * time_to_collision)
if minimum_separation > agent.bounding_radius + neighbor.bounding_radius:
return false
else:

View File

@ -10,16 +10,16 @@
class_name GSAIBlend
extends GSAISteeringBehavior
var _behaviors := []
var _accel := GSAITargetAcceleration.new()
var _behaviors : Array = Array()
var _accel : GSAITargetAcceleration = GSAITargetAcceleration.new()
func _init(agent: GSAISteeringAgent).(agent) -> void:
func _init(agent : GSAISteeringAgent).(agent) -> void:
pass
# Appends a behavior to the internal array along with its `weight`.
func add(behavior: GSAISteeringBehavior, weight: float) -> void:
func add(behavior : GSAISteeringBehavior, weight : float) -> void:
behavior.agent = agent
var dict : Dictionary = Dictionary()
@ -32,23 +32,23 @@ func add(behavior: GSAISteeringBehavior, weight: float) -> void:
# Returns the behavior at the specified `index`, or an empty `Dictionary` if
# none was found.
func get_behavior_at(index: int) -> Dictionary:
func get_behavior_at(index : int) -> Dictionary:
if _behaviors.size() > index:
return _behaviors[index]
printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size()))
return {}
return Dictionary()
func _calculate_steering(blended_accel: GSAITargetAcceleration) -> void:
blended_accel.set_zero()
for i in range(_behaviors.size()):
var bw: Dictionary = _behaviors[i]
var bw : Dictionary = _behaviors[i]
bw.behavior.calculate_steering(_accel)
blended_accel.add_scaled_accel(_accel, bw.weight)
blended_accel.linear = GSAIUtils.clampedv3(blended_accel.linear, agent.linear_acceleration_max)
blended_accel.angular = clamp(
blended_accel.angular, -agent.angular_acceleration_max, agent.angular_acceleration_max
)
blended_accel.angular = clamp(blended_accel.angular, -agent.angular_acceleration_max, agent.angular_acceleration_max)

View File

@ -14,13 +14,11 @@ func _init(agent: GSAISteeringAgent, proximity: GSAIProximity).(agent, proximity
func _calculate_steering(acceleration: GSAITargetAcceleration) -> 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
)
acceleration.linear = ((_center_of_mass - agent.position).normalized() * agent.linear_acceleration_max)
# Callback for the proximity to call when finding neighbors. Adds `neighbor`'s position

View File

@ -5,9 +5,7 @@ class_name GSAIEvade
extends GSAIPursue
func _init(agent: GSAISteeringAgent, target: GSAISteeringAgent, predict_time_max := 1.0).(
agent, target, predict_time_max
):
func _init(agent: GSAISteeringAgent, target: GSAISteeringAgent, predict_time_max : float = 1.0).(agent, target, predict_time_max):
pass

View File

@ -5,24 +5,23 @@ class_name GSAIFace
extends GSAIMatchOrientation
func _init(agent: GSAISteeringAgent, target: GSAIAgentLocation, use_z := false).(
agent, target, use_z
) -> void:
func _init(agent: GSAISteeringAgent, target: GSAIAgentLocation, use_z := false).(agent, target, use_z) -> void:
pass
func _face(acceleration: GSAITargetAcceleration, target_position: Vector3) -> void:
var to_target := target_position - agent.position
var distance_squared := to_target.length_squared()
var to_target : Vector3 = target_position - agent.position
var distance_squared : float = to_target.length_squared()
if distance_squared < agent.zero_linear_speed_threshold:
acceleration.set_zero()
else:
var orientation = (
GSAIUtils.vector3_to_angle(to_target)
if use_z
else GSAIUtils.vector2_to_angle(GSAIUtils.to_vector2(to_target))
)
var orientation : float
if use_z:
orientation = GSAIUtils.vector3_to_angle(to_target)
else:
orientation = GSAIUtils.vector2_to_angle(GSAIUtils.to_vector2(to_target))
_match_orientation(acceleration, orientation)

View File

@ -9,8 +9,5 @@ func _init(agent: GSAISteeringAgent, target: GSAIAgentLocation).(agent, target)
func _calculate_steering(acceleration: GSAITargetAcceleration) -> void:
acceleration.linear = (
(agent.position - target.position).normalized()
* agent.linear_acceleration_max
)
acceleration.linear = ((agent.position - target.position).normalized() * agent.linear_acceleration_max)
acceleration.angular = 0

View File

@ -4,40 +4,39 @@ class_name GSAIFollowPath
extends GSAIArrive
# The path to follow and travel along.
var path: GSAIPath
var path : GSAIPath
# The distance along the path to generate the next target position.
var path_offset := 0.0
var path_offset : float = 0.0
# Whether to use `GSAIArrive` behavior on an open path.
var is_arrive_enabled := true
var is_arrive_enabled : bool = true
# The amount of time in the future to predict the owning agent's position along
# the path. Setting it to 0.0 will force non-predictive path following.
var prediction_time := 0.0
var prediction_time : float = 0.0
func _init(agent: GSAISteeringAgent, _path: GSAIPath, _path_offset := 0.0, _prediction_time := 0.0).(
agent, null
) -> void:
func _init(agent: GSAISteeringAgent, _path: GSAIPath, _path_offset := 0.0, _prediction_time := 0.0).(agent, null) -> void:
self.path = _path
self.path_offset = _path_offset
self.prediction_time = _prediction_time
func _calculate_steering(acceleration: GSAITargetAcceleration) -> void:
var location := (
agent.position
if prediction_time == 0
else agent.position + (agent.linear_velocity * prediction_time)
)
var location : Vector3
if prediction_time == 0:
location = agent.position
else:
location = agent.position + (agent.linear_velocity * prediction_time)
var distance := path.calculate_distance(location)
var target_distance := distance + path_offset
var distance : float = path.calculate_distance(location)
var target_distance : float = distance + path_offset
if prediction_time > 0 and path.is_open:
if target_distance < path.calculate_distance(agent.position):
target_distance = path.length
var target_position := path.calculate_target_position(target_distance)
var target_position : Vector3 = path.calculate_target_position(target_distance)
if is_arrive_enabled and path.is_open:
if path_offset >= 0:

View File

@ -5,7 +5,7 @@ class_name GSAILookWhereYouGo
extends GSAIMatchOrientation
func _init(agent: GSAISteeringAgent, use_z := false).(agent, null, use_z) -> void:
func _init(agent: GSAISteeringAgent, use_z : bool = false).(agent, null, use_z) -> void:
pass
@ -13,9 +13,11 @@ func _calculate_steering(accel: GSAITargetAcceleration) -> void:
if agent.linear_velocity.length_squared() < agent.zero_linear_speed_threshold:
accel.set_zero()
else:
var orientation := (
GSAIUtils.vector3_to_angle(agent.linear_velocity)
if use_z
else GSAIUtils.vector2_to_angle(GSAIUtils.to_vector2(agent.linear_velocity))
)
var orientation : float
if use_z:
orientation = GSAIUtils.vector3_to_angle(agent.linear_velocity)
else:
orientation = GSAIUtils.vector2_to_angle(GSAIUtils.to_vector2(agent.linear_velocity))
_match_orientation(accel, orientation)

View File

@ -6,33 +6,33 @@ class_name GSAIMatchOrientation
extends GSAISteeringBehavior
# The target orientation for the behavior to try and match rotations to.
var target: GSAIAgentLocation
var target : GSAIAgentLocation
# The amount of distance in radians for the behavior to consider itself close
# enough to be matching the target agent's rotation.
var alignment_tolerance: float
var alignment_tolerance : float = 0.0
# The amount of distance in radians from the goal to start slowing down.
var deceleration_radius: float
var deceleration_radius : float = 0.0
# The amount of time to reach the target velocity
var time_to_reach: float = 0.1
var time_to_reach : float = 0.1
# Whether to use the X and Z components instead of X and Y components when
# determining angles. X and Z should be used in 3D.
var use_z: bool
var use_z : bool = false
func _init(agent: GSAISteeringAgent, _target: GSAIAgentLocation, _use_z := false).(agent) -> void:
func _init(agent: GSAISteeringAgent, _target: GSAIAgentLocation, _use_z : bool = false).(agent) -> void:
self.use_z = _use_z
self.target = _target
func _match_orientation(acceleration: GSAITargetAcceleration, desired_orientation: float) -> void:
var rotation := wrapf(desired_orientation - agent.orientation, -PI, PI)
var rotation : float = wrapf(desired_orientation - agent.orientation, -PI, PI)
var rotation_size := abs(rotation)
var rotation_size : float = abs(rotation)
if rotation_size <= alignment_tolerance:
acceleration.set_zero()
else:
var desired_rotation := agent.angular_speed_max
var desired_rotation : float = agent.angular_speed_max
if rotation_size <= deceleration_radius:
desired_rotation *= rotation_size / deceleration_radius
@ -41,7 +41,7 @@ func _match_orientation(acceleration: GSAITargetAcceleration, desired_orientatio
acceleration.angular = ((desired_rotation - agent.angular_velocity) / time_to_reach)
var limited_acceleration := abs(acceleration.angular)
var limited_acceleration : float = abs(acceleration.angular)
if limited_acceleration > agent.angular_acceleration_max:
acceleration.angular *= (agent.angular_acceleration_max / limited_acceleration)

View File

@ -4,16 +4,16 @@
class_name GSAIPriority
extends GSAISteeringBehavior
var _behaviors := []
var _behaviors : Array = Array()
# The index of the last behavior the container prioritized.
var last_selected_index: int
var last_selected_index : int = 0
# If a behavior's acceleration is lower than this threshold, the container
# considers it has an acceleration of zero.
var zero_threshold: float
var zero_threshold : float = 0.0
func _init(agent: GSAISteeringAgent, _zero_threshold := 0.001).(agent) -> void:
func _init(agent: GSAISteeringAgent, _zero_threshold : float = 0.001).(agent) -> void:
self.zero_threshold = _zero_threshold
@ -24,19 +24,21 @@ func add(behavior: GSAISteeringBehavior) -> void:
# Returns the behavior at the position in the pool referred to by `index`, or
# `null` if no behavior was found.
func get_behavior_at(index: int) -> GSAISteeringBehavior:
func get_behavior_at(index : int) -> GSAISteeringBehavior:
if _behaviors.size() > index:
return _behaviors[index]
printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size()))
return null
func _calculate_steering(accel: GSAITargetAcceleration) -> void:
var threshold_squared := zero_threshold * zero_threshold
func _calculate_steering(accel : GSAITargetAcceleration) -> void:
var threshold_squared : float = zero_threshold * zero_threshold
last_selected_index = -1
var size := _behaviors.size()
var size : int = _behaviors.size()
if size > 0:
for i in range(size):

View File

@ -5,23 +5,23 @@ class_name GSAIPursue
extends GSAISteeringBehavior
# The target agent that the behavior is trying to intercept.
var target: GSAISteeringAgent
var target : GSAISteeringAgent
# The maximum amount of time in the future the behavior predicts the target's
# location.
var predict_time_max: float
var predict_time_max : float = 0
func _init(agent: GSAISteeringAgent, _target: GSAISteeringAgent, _predict_time_max := 1.0).(agent) -> void:
func _init(agent : GSAISteeringAgent, _target : GSAISteeringAgent, _predict_time_max : float = 1.0).(agent) -> void:
self.target = _target
self.predict_time_max = _predict_time_max
func _calculate_steering(acceleration: GSAITargetAcceleration) -> void:
var target_position := target.position
var distance_squared := (target_position - agent.position).length_squared()
func _calculate_steering(acceleration : GSAITargetAcceleration) -> void:
var target_position : Vector3 = target.position
var distance_squared : float = (target_position - agent.position).length_squared()
var speed_squared := agent.linear_velocity.length_squared()
var predict_time := predict_time_max
var speed_squared : float = agent.linear_velocity.length_squared()
var predict_time : float = predict_time_max
if speed_squared > 0:
var predict_time_squared := distance_squared / speed_squared

View File

@ -5,16 +5,13 @@ class_name GSAISeek
extends GSAISteeringBehavior
# The target that the behavior aims to move the agent to.
var target: GSAIAgentLocation
var target : GSAIAgentLocation
func _init(agent: GSAISteeringAgent, _target: GSAIAgentLocation).(agent) -> void:
func _init(agent : GSAISteeringAgent, _target : GSAIAgentLocation).(agent) -> void:
self.target = _target
func _calculate_steering(acceleration: GSAITargetAcceleration) -> void:
acceleration.linear = (
(target.position - agent.position).normalized()
* agent.linear_acceleration_max
)
acceleration.linear = ((target.position - agent.position).normalized() * agent.linear_acceleration_max)
acceleration.angular = 0

View File

@ -9,16 +9,16 @@ class_name GSAISeparation
extends GSAIGroupBehavior
# The coefficient to calculate how fast the separation strength decays with distance.
var decay_coefficient := 1.0
var decay_coefficient : float = 1.0
var _acceleration: GSAITargetAcceleration
var _acceleration : GSAITargetAcceleration
func _init(agent: GSAISteeringAgent, proximity: GSAIProximity).(agent, proximity) -> void:
func _init(agent : GSAISteeringAgent, proximity : GSAIProximity).(agent, proximity) -> void:
pass
func _calculate_steering(acceleration: GSAITargetAcceleration) -> void:
func _calculate_steering(acceleration : GSAITargetAcceleration) -> void:
acceleration.set_zero()
self._acceleration = acceleration
# warning-ignore:return_value_discarded
@ -28,11 +28,11 @@ func _calculate_steering(acceleration: GSAITargetAcceleration) -> void:
# Callback for the proximity to call when finding neighbors. Determines the amount of
# acceleration that `neighbor` imposes based on its distance from the owner agent.
# @tags - virtual
func _report_neighbor(neighbor: GSAISteeringAgent) -> bool:
var to_agent := agent.position - neighbor.position
func _report_neighbor(neighbor : GSAISteeringAgent) -> bool:
var to_agent : Vector3 = agent.position - neighbor.position
var distance_squared := to_agent.length_squared()
var acceleration_max := agent.linear_acceleration_max
var distance_squared : float = to_agent.length_squared()
var acceleration_max : float = agent.linear_acceleration_max
var strength := decay_coefficient / distance_squared
if strength > acceleration_max:

View File

@ -3,6 +3,6 @@
class_name GSAIAgentLocation
# The agent's position in space.
var position := Vector3.ZERO
var position : Vector3 = Vector3.ZERO
# The agent's orientation on its Y axis rotation.
var orientation := 0.0
var orientation : float = 0.0

View File

@ -4,17 +4,17 @@ class_name GSAIGroupBehavior
extends GSAISteeringBehavior
# Container to find neighbors of the agent and calculate group behavior.
var proximity: GSAIProximity
var proximity : GSAIProximity
var _callback := funcref(self, "_report_neighbor")
var _callback : FuncRef = funcref(self, "_report_neighbor")
func _init(agent: GSAISteeringAgent, _proximity: GSAIProximity).(agent) -> void:
func _init(agent : GSAISteeringAgent, _proximity : GSAIProximity).(agent) -> void:
self.proximity = _proximity
# Internal callback for the behavior to define whether or not a member is
# relevant
# @tags - virtual
func _report_neighbor(_neighbor: GSAISteeringAgent) -> bool:
func _report_neighbor(_neighbor : GSAISteeringAgent) -> bool:
return false

View File

@ -5,17 +5,17 @@ class_name GSAIPath
extends Reference
# If `false`, the path loops.
var is_open: bool
var is_open : bool
# Total length of the path.
var length: float
var length : float
var _segments: Array
var _segments : Array
var _nearest_point_on_segment: Vector3
var _nearest_point_on_path: Vector3
var _nearest_point_on_segment : Vector3
var _nearest_point_on_path : Vector3
func _init(waypoints: Array, _is_open := false) -> void:
func _init(waypoints : Array, _is_open : bool = false) -> void:
self.is_open = _is_open
create_path(waypoints)
_nearest_point_on_segment = waypoints[0]
@ -23,15 +23,15 @@ func _init(waypoints: Array, _is_open := false) -> void:
# Creates a path from a list of waypoints.
func create_path(waypoints: Array) -> 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 = []
length = 0
var current: Vector3 = waypoints.front()
var previous: Vector3
var current : Vector3 = waypoints.front()
var previous : Vector3
for i in range(1, waypoints.size(), 1):
previous = current
@ -41,33 +41,31 @@ func create_path(waypoints: Array) -> void:
break
else:
current = waypoints[0]
var segment := GSAISegment.new(previous, current)
var segment : GSAISegment = GSAISegment.new(previous, current)
length += segment.length
segment.cumulative_length = length
_segments.append(segment)
# Returns the distance from `agent_current_position` to the next waypoint.
func calculate_distance(agent_current_position: Vector3) -> float:
func calculate_distance(agent_current_position : Vector3) -> float:
if _segments.size() == 0:
return 0.0
var smallest_distance_squared: float = INF
var nearest_segment: GSAISegment
var smallest_distance_squared : float = INF
var nearest_segment : GSAISegment = null
for i in range(_segments.size()):
var segment: GSAISegment = _segments[i]
var distance_squared := _calculate_point_segment_distance_squared(
segment.begin, segment.end, agent_current_position
)
var distance_squared : float = _calculate_point_segment_distance_squared(segment.begin, segment.end, agent_current_position)
if distance_squared < smallest_distance_squared:
_nearest_point_on_path = _nearest_point_on_segment
smallest_distance_squared = distance_squared
nearest_segment = segment
var length_on_path := (
nearest_segment.cumulative_length
- _nearest_point_on_path.distance_to(nearest_segment.end)
)
var length_on_path : float = nearest_segment.cumulative_length - _nearest_point_on_path.distance_to(nearest_segment.end)
return length_on_path
@ -94,10 +92,7 @@ func calculate_target_position(target_distance: float) -> Vector3:
var distance := desired_segment.cumulative_length - target_distance
return (
((desired_segment.begin - desired_segment.end) * (distance / desired_segment.length))
+ desired_segment.end
)
return (((desired_segment.begin - desired_segment.end) * (distance / desired_segment.length)) + desired_segment.end)
# Returns the position of the first point on the path.
@ -112,8 +107,8 @@ func get_end_point() -> Vector3:
func _calculate_point_segment_distance_squared(start: Vector3, end: Vector3, position: Vector3) -> float:
_nearest_point_on_segment = start
var start_end := end - start
var start_end_length_squared := start_end.length_squared()
var start_end : Vector3 = end - start
var start_end_length_squared : float = start_end.length_squared()
if start_end_length_squared != 0:
var t = (position - start).dot(start_end) / start_end_length_squared
_nearest_point_on_segment += start_end * clamp(t, 0, 1)

View File

@ -7,22 +7,22 @@ extends GSAIAgentLocation
class_name GSAISteeringAgent
# The amount of velocity to be considered effectively not moving.
var zero_linear_speed_threshold := 0.01
var zero_linear_speed_threshold : float = 0.01
# The maximum speed at which the agent can move.
var linear_speed_max := 0.0
var linear_speed_max : float = 0.0
# The maximum amount of acceleration that any behavior can apply to the agent.
var linear_acceleration_max := 0.0
var linear_acceleration_max : float = 0.0
# The maximum amount of angular speed at which the agent can rotate.
var angular_speed_max := 0.0
var angular_speed_max : float = 0.0
# The maximum amount of angular acceleration that any behavior can apply to an
# agent.
var angular_acceleration_max := 0.0
var angular_acceleration_max : float = 0.0
# Current velocity of the agent.
var linear_velocity := Vector3.ZERO
var linear_velocity : Vector3 = Vector3.ZERO
# Current angular velocity of the agent.
var angular_velocity := 0.0
var angular_velocity : float = 0.0
# The radius of the sphere that approximates the agent's size in space.
var bounding_radius := 0.0
var bounding_radius : float = 0.0
# Used internally by group behaviors and proximities to mark the agent as already
# considered.
var is_tagged := false
var is_tagged : bool = false

View File

@ -6,16 +6,17 @@
# The `calculate_steering` function is the entry point for all behaviors.
# Individual steering behaviors encapsulate the steering logic.
# @category - Base types
extends Reference
class_name GSAISteeringBehavior
# If `false`, all calculations return zero amounts of acceleration.
var is_enabled := true
var is_enabled : bool = true
# The AI agent on which the steering behavior bases its calculations.
var agent: GSAISteeringAgent
var agent : GSAISteeringAgent
func _init(_agent: GSAISteeringAgent) -> void:
self.agent = _agent
agent = _agent
# Sets the `acceleration` with the behavior's desired amount of acceleration.

View File

@ -1,13 +1,13 @@
# A desired linear and angular amount of acceleration requested by the steering
# system.
# @category - Base types
extends Reference
class_name GSAITargetAcceleration
# Linear acceleration
var linear := Vector3.ZERO
var linear : Vector3 = Vector3.ZERO
# Angular acceleration
var angular := 0.0
var angular : float = 0.0
# Sets the linear and angular components to 0.
func set_zero() -> void:
@ -16,18 +16,15 @@ func set_zero() -> void:
linear.z = 0.0
angular = 0.0
# Adds `accel`'s components, multiplied by `scalar`, to this one.
func add_scaled_accel(accel: GSAITargetAcceleration, scalar: float) -> void:
linear += accel.linear * scalar
angular += accel.angular * scalar
# Returns the squared magnitude of the linear and angular components.
func get_magnitude_squared() -> float:
return linear.length_squared() + angular * angular
# Returns the magnitude of the linear and angular components.
func get_magnitude() -> float:
return sqrt(get_magnitude_squared())

View File

@ -4,10 +4,12 @@ class_name GSAIUtils
# Returns the `vector` with its length capped to `limit`.
static func clampedv3(vector: Vector3, limit: float) -> Vector3:
var length_squared := vector.length_squared()
var limit_squared := limit * limit
var length_squared : float = vector.length_squared()
var limit_squared : float = limit * limit
if length_squared > limit_squared:
vector *= sqrt(limit_squared / length_squared)
return vector
# Returns an angle in radians between the positive X axis and the `vector`.

View File

@ -15,10 +15,10 @@ func _init(agent: GSAISteeringAgent, agents: Array).(agent, agents) -> void:
# adds one to the count if its `callback` returns true.
# @tags - virtual
func _find_neighbors(callback: FuncRef) -> int:
var neighbor_count := 0
var agent_count := agents.size()
var neighbor_count : int = 0
var agent_count : int = agents.size()
for i in range(agent_count):
var current_agent := agents[i] as GSAISteeringAgent
var current_agent : GSAISteeringAgent = agents[i] as GSAISteeringAgent
if current_agent != agent:
if callback.call_func(current_agent):

View File

@ -5,9 +5,9 @@ extends Reference
class_name GSAIProximity
# The owning agent whose neighbors are found in the group
var agent: GSAISteeringAgent
var agent : GSAISteeringAgent
# The agents who are part of this group and could be potential neighbors
var agents := []
var agents : Array = Array()
func _init(_agent: GSAISteeringAgent, _agents: Array) -> void:

View File

@ -5,10 +5,10 @@ extends GSAIProximity
class_name GSAIRadiusProximity
# The radius around the owning agent to find neighbors in
var radius := 0.0
var radius : float = 0.0
var _last_frame := 0
var _scene_tree: SceneTree
var _last_frame : int = 0
var _scene_tree : SceneTree
func _init(agent: GSAISteeringAgent, agents: Array, _radius: float).(agent, agents) -> void:
@ -21,23 +21,29 @@ func _init(agent: GSAISteeringAgent, agents: Array, _radius: float).(agent, agen
# `_find_neighbors` calls `callback` for each agent in the `agents` array that lie within
# the radius around the owning agent and adds one to the count if its `callback` returns true.
# @tags - virtual
func _find_neighbors(callback: FuncRef) -> int:
var agent_count := agents.size()
var neighbor_count := 0
func _find_neighbors(callback : FuncRef) -> int:
var agent_count : int = agents.size()
var neighbor_count : int = 0
var current_frame := _scene_tree.get_frame() if _scene_tree else -_last_frame
var current_frame : int
if _scene_tree:
current_frame = _scene_tree.get_frame()
else:
current_frame = -_last_frame
if current_frame != _last_frame:
_last_frame = current_frame
var owner_position := agent.position
var owner_position : Vector3 = agent.position
for i in range(agent_count):
var current_agent := agents[i] as GSAISteeringAgent
var current_agent : GSAISteeringAgent = agents[i] as GSAISteeringAgent
if current_agent != agent:
var distance_squared := owner_position.distance_squared_to(current_agent.position)
var distance_squared : float = owner_position.distance_squared_to(current_agent.position)
var range_to := radius + current_agent.bounding_radius
var range_to : float = radius + current_agent.bounding_radius
if distance_squared < range_to * range_to:
if callback.call_func(current_agent):
@ -48,7 +54,7 @@ func _find_neighbors(callback: FuncRef) -> int:
current_agent.is_tagged = false
else:
for i in range(agent_count):
var current_agent = agents[i] as GSAISteeringAgent
var current_agent : GSAISteeringAgent = agents[i] as GSAISteeringAgent
if current_agent != agent and current_agent.is_tagged:
if callback.call_func(current_agent):