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

View File

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

View File

@ -48,14 +48,14 @@ func _set_body(value: RigidBody2D) -> void:
func _on_SceneTree_frame() -> void: func _on_SceneTree_frame() -> void:
var _body: RigidBody2D = _body_ref.get_ref() var _body: RigidBody2D = _body_ref.get_ref()
if not _body: if !_body:
return return
if not _body.is_inside_tree() or _body.get_tree().paused: if !_body.is_inside_tree() or _body.get_tree().paused:
return return
var current_position := _body.global_position var current_position : Vector2 = _body.global_position
var current_orientation := _body.rotation var current_orientation : float = _body.rotation
position = GSAIUtils.to_vector3(current_position) position = GSAIUtils.to_vector3(current_position)
orientation = current_orientation orientation = current_orientation

View File

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

View File

@ -7,30 +7,30 @@ class_name GSAISpecializedAgent
# If `true`, calculates linear and angular velocities based on the previous # If `true`, calculates linear and angular velocities based on the previous
# frame. When `false`, the user must keep those values updated. # 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 # If `true`, interpolates the current linear velocity towards 0 by the
# `linear_drag_percentage` value. # `linear_drag_percentage` value.
# Does not apply to `RigidBody` and `RigidBody2D` nodes. # 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 # If `true`, interpolates the current angular velocity towards 0 by the
# `angular_drag_percentage` value. # `angular_drag_percentage` value.
# Does not apply to `RigidBody` and `RigidBody2D` nodes. # 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 # The percentage between the current linear velocity and 0 to interpolate by if
# `apply_linear_drag` is true. # `apply_linear_drag` is true.
# Does not apply to `RigidBody` and `RigidBody2D` nodes. # 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 # The percentage between the current angular velocity and 0 to interpolate by if
# `apply_angular_drag` is true. # `apply_angular_drag` is true.
# Does not apply to `RigidBody` and `RigidBody2D` nodes. # 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 _last_orientation : float = 0.0
var _applied_steering := false var _applied_steering : bool = false
# Moves the agent's body by target `acceleration`. # Moves the agent's body by target `acceleration`.

View File

@ -8,11 +8,11 @@ extends GSAISteeringBehavior
var target : GSAIAgentLocation var target : GSAIAgentLocation
# Distance from the target for the agent to be considered successfully # Distance from the target for the agent to be considered successfully
# arrived. # arrived.
var arrival_tolerance: float var arrival_tolerance : float = 0.0
# Distance from the target for the agent to begin slowing down. # 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. # 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:
@ -20,18 +20,18 @@ func _init(agent: GSAISteeringAgent, _target: GSAIAgentLocation).(agent) -> void
func _arrive(acceleration : GSAITargetAcceleration, target_position : Vector3) -> void: func _arrive(acceleration : GSAITargetAcceleration, target_position : Vector3) -> void:
var to_target := target_position - agent.position var to_target : Vector3 = target_position - agent.position
var distance := to_target.length() var distance : float = to_target.length()
if distance <= arrival_tolerance: if distance <= arrival_tolerance:
acceleration.set_zero() acceleration.set_zero()
else: else:
var desired_speed := agent.linear_speed_max var desired_speed : float = agent.linear_speed_max
if distance <= deceleration_radius: if distance <= deceleration_radius:
desired_speed *= 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) desired_velocity = ((desired_velocity - agent.linear_velocity) * 1.0 / time_to_reach)

View File

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

View File

@ -10,8 +10,8 @@
class_name GSAIBlend class_name GSAIBlend
extends GSAISteeringBehavior extends GSAISteeringBehavior
var _behaviors := [] var _behaviors : Array = Array()
var _accel := GSAITargetAcceleration.new() var _accel : GSAITargetAcceleration = GSAITargetAcceleration.new()
func _init(agent : GSAISteeringAgent).(agent) -> void: func _init(agent : GSAISteeringAgent).(agent) -> void:
@ -35,8 +35,10 @@ func add(behavior: GSAISteeringBehavior, weight: float) -> void:
func get_behavior_at(index : int) -> Dictionary: func get_behavior_at(index : int) -> Dictionary:
if _behaviors.size() > index: if _behaviors.size() > index:
return _behaviors[index] return _behaviors[index]
printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size())) printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size()))
return {}
return Dictionary()
func _calculate_steering(blended_accel: GSAITargetAcceleration) -> void: func _calculate_steering(blended_accel: GSAITargetAcceleration) -> void:
@ -49,6 +51,4 @@ func _calculate_steering(blended_accel: GSAITargetAcceleration) -> void:
blended_accel.add_scaled_accel(_accel, bw.weight) blended_accel.add_scaled_accel(_accel, bw.weight)
blended_accel.linear = GSAIUtils.clampedv3(blended_accel.linear, agent.linear_acceleration_max) blended_accel.linear = GSAIUtils.clampedv3(blended_accel.linear, agent.linear_acceleration_max)
blended_accel.angular = clamp( blended_accel.angular = clamp(blended_accel.angular, -agent.angular_acceleration_max, agent.angular_acceleration_max)
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: func _calculate_steering(acceleration: GSAITargetAcceleration) -> void:
acceleration.set_zero() acceleration.set_zero()
_center_of_mass = Vector3.ZERO _center_of_mass = Vector3.ZERO
var neighbor_count = proximity._find_neighbors(_callback) var neighbor_count = proximity._find_neighbors(_callback)
if neighbor_count > 0: if neighbor_count > 0:
_center_of_mass *= 1.0 / neighbor_count _center_of_mass *= 1.0 / neighbor_count
acceleration.linear = ( acceleration.linear = ((_center_of_mass - agent.position).normalized() * agent.linear_acceleration_max)
(_center_of_mass - agent.position).normalized()
* agent.linear_acceleration_max
)
# Callback for the proximity to call when finding neighbors. Adds `neighbor`'s position # Callback for the proximity to call when finding neighbors. Adds `neighbor`'s position

View File

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

View File

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

View File

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

View File

@ -6,38 +6,37 @@ extends GSAIArrive
# The path to follow and travel along. # The path to follow and travel along.
var path : GSAIPath var path : GSAIPath
# The distance along the path to generate the next target position. # 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. # 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 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. # 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).( func _init(agent: GSAISteeringAgent, _path: GSAIPath, _path_offset := 0.0, _prediction_time := 0.0).(agent, null) -> void:
agent, null
) -> void:
self.path = _path self.path = _path
self.path_offset = _path_offset self.path_offset = _path_offset
self.prediction_time = _prediction_time self.prediction_time = _prediction_time
func _calculate_steering(acceleration: GSAITargetAcceleration) -> void: func _calculate_steering(acceleration: GSAITargetAcceleration) -> void:
var location := ( var location : Vector3
agent.position
if prediction_time == 0
else agent.position + (agent.linear_velocity * prediction_time)
)
var distance := path.calculate_distance(location) if prediction_time == 0:
var target_distance := distance + path_offset location = agent.position
else:
location = agent.position + (agent.linear_velocity * prediction_time)
var distance : float = path.calculate_distance(location)
var target_distance : float = distance + path_offset
if prediction_time > 0 and path.is_open: if prediction_time > 0 and path.is_open:
if target_distance < path.calculate_distance(agent.position): if target_distance < path.calculate_distance(agent.position):
target_distance = path.length 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 is_arrive_enabled and path.is_open:
if path_offset >= 0: if path_offset >= 0:

View File

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

View File

@ -9,30 +9,30 @@ extends GSAISteeringBehavior
var target : GSAIAgentLocation var target : GSAIAgentLocation
# The amount of distance in radians for the behavior to consider itself close # The amount of distance in radians for the behavior to consider itself close
# enough to be matching the target agent's rotation. # 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. # 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 # 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 # 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. # 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.use_z = _use_z
self.target = _target self.target = _target
func _match_orientation(acceleration: GSAITargetAcceleration, desired_orientation: float) -> void: 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: if rotation_size <= alignment_tolerance:
acceleration.set_zero() acceleration.set_zero()
else: else:
var desired_rotation := agent.angular_speed_max var desired_rotation : float = agent.angular_speed_max
if rotation_size <= deceleration_radius: if rotation_size <= deceleration_radius:
desired_rotation *= 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) 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: if limited_acceleration > agent.angular_acceleration_max:
acceleration.angular *= (agent.angular_acceleration_max / limited_acceleration) acceleration.angular *= (agent.angular_acceleration_max / limited_acceleration)

View File

@ -4,16 +4,16 @@
class_name GSAIPriority class_name GSAIPriority
extends GSAISteeringBehavior extends GSAISteeringBehavior
var _behaviors := [] var _behaviors : Array = Array()
# The index of the last behavior the container prioritized. # 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 # If a behavior's acceleration is lower than this threshold, the container
# considers it has an acceleration of zero. # 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 self.zero_threshold = _zero_threshold
@ -27,16 +27,18 @@ func add(behavior: GSAISteeringBehavior) -> void:
func get_behavior_at(index : int) -> GSAISteeringBehavior: func get_behavior_at(index : int) -> GSAISteeringBehavior:
if _behaviors.size() > index: if _behaviors.size() > index:
return _behaviors[index] return _behaviors[index]
printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size())) printerr("Tried to get index " + str(index) + " in array of size " + str(_behaviors.size()))
return null return null
func _calculate_steering(accel : GSAITargetAcceleration) -> void: func _calculate_steering(accel : GSAITargetAcceleration) -> void:
var threshold_squared := zero_threshold * zero_threshold var threshold_squared : float = zero_threshold * zero_threshold
last_selected_index = -1 last_selected_index = -1
var size := _behaviors.size() var size : int = _behaviors.size()
if size > 0: if size > 0:
for i in range(size): for i in range(size):

View File

@ -8,20 +8,20 @@ extends GSAISteeringBehavior
var target : GSAISteeringAgent var target : GSAISteeringAgent
# The maximum amount of time in the future the behavior predicts the target's # The maximum amount of time in the future the behavior predicts the target's
# location. # 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.target = _target
self.predict_time_max = _predict_time_max self.predict_time_max = _predict_time_max
func _calculate_steering(acceleration : GSAITargetAcceleration) -> void: func _calculate_steering(acceleration : GSAITargetAcceleration) -> void:
var target_position := target.position var target_position : Vector3 = target.position
var distance_squared := (target_position - agent.position).length_squared() var distance_squared : float = (target_position - agent.position).length_squared()
var speed_squared := agent.linear_velocity.length_squared() var speed_squared : float = agent.linear_velocity.length_squared()
var predict_time := predict_time_max var predict_time : float = predict_time_max
if speed_squared > 0: if speed_squared > 0:
var predict_time_squared := distance_squared / speed_squared var predict_time_squared := distance_squared / speed_squared

View File

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

View File

@ -9,7 +9,7 @@ class_name GSAISeparation
extends GSAIGroupBehavior extends GSAIGroupBehavior
# The coefficient to calculate how fast the separation strength decays with distance. # 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
@ -29,10 +29,10 @@ func _calculate_steering(acceleration: GSAITargetAcceleration) -> void:
# acceleration that `neighbor` imposes based on its distance from the owner agent. # acceleration that `neighbor` imposes based on its distance from the owner agent.
# @tags - virtual # @tags - virtual
func _report_neighbor(neighbor : GSAISteeringAgent) -> bool: func _report_neighbor(neighbor : GSAISteeringAgent) -> bool:
var to_agent := agent.position - neighbor.position var to_agent : Vector3 = agent.position - neighbor.position
var distance_squared := to_agent.length_squared() var distance_squared : float = to_agent.length_squared()
var acceleration_max := agent.linear_acceleration_max var acceleration_max : float = agent.linear_acceleration_max
var strength := decay_coefficient / distance_squared var strength := decay_coefficient / distance_squared
if strength > acceleration_max: if strength > acceleration_max:

View File

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

View File

@ -6,7 +6,7 @@ extends GSAISteeringBehavior
# Container to find neighbors of the agent and calculate group behavior. # 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:

View File

@ -15,7 +15,7 @@ var _nearest_point_on_segment: Vector3
var _nearest_point_on_path : 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 self.is_open = _is_open
create_path(waypoints) create_path(waypoints)
_nearest_point_on_segment = waypoints[0] _nearest_point_on_segment = waypoints[0]
@ -41,7 +41,8 @@ func create_path(waypoints: Array) -> void:
break break
else: else:
current = waypoints[0] current = waypoints[0]
var segment := GSAISegment.new(previous, current)
var segment : GSAISegment = GSAISegment.new(previous, current)
length += segment.length length += segment.length
segment.cumulative_length = length segment.cumulative_length = length
_segments.append(segment) _segments.append(segment)
@ -51,23 +52,20 @@ func create_path(waypoints: Array) -> void:
func calculate_distance(agent_current_position : Vector3) -> float: func calculate_distance(agent_current_position : Vector3) -> float:
if _segments.size() == 0: if _segments.size() == 0:
return 0.0 return 0.0
var smallest_distance_squared : float = INF var smallest_distance_squared : float = INF
var nearest_segment: GSAISegment var nearest_segment : GSAISegment = null
for i in range(_segments.size()): for i in range(_segments.size()):
var segment: GSAISegment = _segments[i] var segment: GSAISegment = _segments[i]
var distance_squared := _calculate_point_segment_distance_squared( var distance_squared : float = _calculate_point_segment_distance_squared(segment.begin, segment.end, agent_current_position)
segment.begin, segment.end, agent_current_position
)
if distance_squared < smallest_distance_squared: if distance_squared < smallest_distance_squared:
_nearest_point_on_path = _nearest_point_on_segment _nearest_point_on_path = _nearest_point_on_segment
smallest_distance_squared = distance_squared smallest_distance_squared = distance_squared
nearest_segment = segment nearest_segment = segment
var length_on_path := ( var length_on_path : float = nearest_segment.cumulative_length - _nearest_point_on_path.distance_to(nearest_segment.end)
nearest_segment.cumulative_length
- _nearest_point_on_path.distance_to(nearest_segment.end)
)
return length_on_path return length_on_path
@ -94,10 +92,7 @@ func calculate_target_position(target_distance: float) -> Vector3:
var distance := desired_segment.cumulative_length - target_distance var distance := desired_segment.cumulative_length - target_distance
return ( return (((desired_segment.begin - desired_segment.end) * (distance / desired_segment.length)) + desired_segment.end)
((desired_segment.begin - desired_segment.end) * (distance / desired_segment.length))
+ desired_segment.end
)
# Returns the position of the first point on the path. # 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: func _calculate_point_segment_distance_squared(start: Vector3, end: Vector3, position: Vector3) -> float:
_nearest_point_on_segment = start _nearest_point_on_segment = start
var start_end := end - start var start_end : Vector3 = end - start
var start_end_length_squared := start_end.length_squared() var start_end_length_squared : float = start_end.length_squared()
if start_end_length_squared != 0: if start_end_length_squared != 0:
var t = (position - start).dot(start_end) / start_end_length_squared var t = (position - start).dot(start_end) / start_end_length_squared
_nearest_point_on_segment += start_end * clamp(t, 0, 1) _nearest_point_on_segment += start_end * clamp(t, 0, 1)

View File

@ -7,22 +7,22 @@ extends GSAIAgentLocation
class_name GSAISteeringAgent class_name GSAISteeringAgent
# The amount of velocity to be considered effectively not moving. # 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. # 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. # 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. # 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 # The maximum amount of angular acceleration that any behavior can apply to an
# agent. # agent.
var angular_acceleration_max := 0.0 var angular_acceleration_max : float = 0.0
# Current velocity of the agent. # Current velocity of the agent.
var linear_velocity := Vector3.ZERO var linear_velocity : Vector3 = Vector3.ZERO
# Current angular velocity of the agent. # 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. # 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 # Used internally by group behaviors and proximities to mark the agent as already
# considered. # 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. # The `calculate_steering` function is the entry point for all behaviors.
# Individual steering behaviors encapsulate the steering logic. # Individual steering behaviors encapsulate the steering logic.
# @category - Base types # @category - Base types
extends Reference
class_name GSAISteeringBehavior class_name GSAISteeringBehavior
# If `false`, all calculations return zero amounts of acceleration. # 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. # The AI agent on which the steering behavior bases its calculations.
var agent : GSAISteeringAgent var agent : GSAISteeringAgent
func _init(_agent: GSAISteeringAgent) -> void: func _init(_agent: GSAISteeringAgent) -> void:
self.agent = _agent agent = _agent
# Sets the `acceleration` with the behavior's desired amount of acceleration. # 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 # A desired linear and angular amount of acceleration requested by the steering
# system. # system.
# @category - Base types # @category - Base types
extends Reference
class_name GSAITargetAcceleration class_name GSAITargetAcceleration
# Linear acceleration # Linear acceleration
var linear := Vector3.ZERO var linear : Vector3 = Vector3.ZERO
# Angular acceleration # Angular acceleration
var angular := 0.0 var angular : float = 0.0
# Sets the linear and angular components to 0. # Sets the linear and angular components to 0.
func set_zero() -> void: func set_zero() -> void:
@ -16,18 +16,15 @@ func set_zero() -> void:
linear.z = 0.0 linear.z = 0.0
angular = 0.0 angular = 0.0
# Adds `accel`'s components, multiplied by `scalar`, to this one. # Adds `accel`'s components, multiplied by `scalar`, to this one.
func add_scaled_accel(accel: GSAITargetAcceleration, scalar: float) -> void: func add_scaled_accel(accel: GSAITargetAcceleration, scalar: float) -> void:
linear += accel.linear * scalar linear += accel.linear * scalar
angular += accel.angular * scalar angular += accel.angular * scalar
# Returns the squared magnitude of the linear and angular components. # Returns the squared magnitude of the linear and angular components.
func get_magnitude_squared() -> float: func get_magnitude_squared() -> float:
return linear.length_squared() + angular * angular return linear.length_squared() + angular * angular
# Returns the magnitude of the linear and angular components. # Returns the magnitude of the linear and angular components.
func get_magnitude() -> float: func get_magnitude() -> float:
return sqrt(get_magnitude_squared()) return sqrt(get_magnitude_squared())

View File

@ -4,10 +4,12 @@ class_name GSAIUtils
# Returns the `vector` with its length capped to `limit`. # Returns the `vector` with its length capped to `limit`.
static func clampedv3(vector: Vector3, limit: float) -> Vector3: static func clampedv3(vector: Vector3, limit: float) -> Vector3:
var length_squared := vector.length_squared() var length_squared : float = vector.length_squared()
var limit_squared := limit * limit var limit_squared : float = limit * limit
if length_squared > limit_squared: if length_squared > limit_squared:
vector *= sqrt(limit_squared / length_squared) vector *= sqrt(limit_squared / length_squared)
return vector return vector
# Returns an angle in radians between the positive X axis and the `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. # adds one to the count if its `callback` returns true.
# @tags - virtual # @tags - virtual
func _find_neighbors(callback: FuncRef) -> int: func _find_neighbors(callback: FuncRef) -> int:
var neighbor_count := 0 var neighbor_count : int = 0
var agent_count := agents.size() var agent_count : int = agents.size()
for i in range(agent_count): 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 current_agent != agent:
if callback.call_func(current_agent): if callback.call_func(current_agent):

View File

@ -7,7 +7,7 @@ class_name GSAIProximity
# The owning agent whose neighbors are found in the group # 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 # 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: func _init(_agent: GSAISteeringAgent, _agents: Array) -> void:

View File

@ -5,9 +5,9 @@ extends GSAIProximity
class_name GSAIRadiusProximity class_name GSAIRadiusProximity
# The radius around the owning agent to find neighbors in # The radius around the owning agent to find neighbors in
var radius := 0.0 var radius : float = 0.0
var _last_frame := 0 var _last_frame : int = 0
var _scene_tree : SceneTree var _scene_tree : SceneTree
@ -22,22 +22,28 @@ func _init(agent: GSAISteeringAgent, agents: Array, _radius: float).(agent, agen
# the radius around the owning agent and adds one to the count if its `callback` returns true. # the radius around the owning agent and adds one to the count if its `callback` returns true.
# @tags - virtual # @tags - virtual
func _find_neighbors(callback : FuncRef) -> int: func _find_neighbors(callback : FuncRef) -> int:
var agent_count := agents.size() var agent_count : int = agents.size()
var neighbor_count := 0 var neighbor_count : int = 0
var current_frame : int
if _scene_tree:
current_frame = _scene_tree.get_frame()
else:
current_frame = -_last_frame
var current_frame := _scene_tree.get_frame() if _scene_tree else -_last_frame
if current_frame != _last_frame: if current_frame != _last_frame:
_last_frame = current_frame _last_frame = current_frame
var owner_position := agent.position var owner_position : Vector3 = agent.position
for i in range(agent_count): 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 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 distance_squared < range_to * range_to:
if callback.call_func(current_agent): if callback.call_func(current_agent):
@ -48,7 +54,7 @@ func _find_neighbors(callback: FuncRef) -> int:
current_agent.is_tagged = false current_agent.is_tagged = false
else: else:
for i in range(agent_count): 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 current_agent != agent and current_agent.is_tagged:
if callback.call_func(current_agent): if callback.call_func(current_agent):