2020-02-06 20:54:12 +01:00
|
|
|
# A specialized steering agent that updates itself every frame so the user does
|
2020-02-06 22:29:48 +01:00
|
|
|
# not have to using a KinematicBody2D
|
2020-04-03 02:31:59 +02:00
|
|
|
# @category - Specialized agents
|
2020-02-11 18:33:25 +01:00
|
|
|
extends GSAISpecializedAgent
|
|
|
|
class_name GSAIKinematicBody2DAgent
|
2020-02-06 20:54:12 +01:00
|
|
|
|
2020-02-07 15:15:03 +01:00
|
|
|
# SLIDE uses `move_and_slide`
|
|
|
|
# COLLIDE uses `move_and_collide`
|
|
|
|
# POSITION changes the `global_position` directly
|
2023-01-13 13:09:18 +01:00
|
|
|
enum MovementType {
|
|
|
|
SLIDE,
|
|
|
|
COLLIDE,
|
|
|
|
POSITION
|
|
|
|
}
|
2020-02-06 22:29:48 +01:00
|
|
|
|
|
|
|
# The KinematicBody2D to keep track of
|
|
|
|
var body: KinematicBody2D setget _set_body
|
|
|
|
|
|
|
|
# The type of movement the body executes
|
2023-01-13 13:09:18 +01:00
|
|
|
var movement_type : int = 0
|
2020-02-06 20:54:12 +01:00
|
|
|
|
2023-01-13 13:09:18 +01:00
|
|
|
var _last_position : Vector2
|
|
|
|
var _body_ref : WeakRef
|
2020-02-06 20:54:12 +01:00
|
|
|
|
|
|
|
|
2020-02-11 20:36:06 +01:00
|
|
|
func _init(_body: KinematicBody2D, _movement_type: int = MovementType.SLIDE) -> void:
|
2023-01-13 13:09:18 +01:00
|
|
|
if !_body.is_inside_tree():
|
2020-02-11 20:36:06 +01:00
|
|
|
yield(_body, "ready")
|
2020-02-14 17:35:18 +01:00
|
|
|
|
2020-05-24 19:00:40 +02:00
|
|
|
self.body = _body
|
2020-02-11 20:36:06 +01:00
|
|
|
self.movement_type = _movement_type
|
2020-02-14 17:35:18 +01:00
|
|
|
|
2020-02-11 20:36:06 +01:00
|
|
|
# warning-ignore:return_value_discarded
|
2020-02-20 16:58:00 +01:00
|
|
|
_body.get_tree().connect("physics_frame", self, "_on_SceneTree_physics_frame")
|
2020-02-06 20:54:12 +01:00
|
|
|
|
|
|
|
|
|
|
|
# Moves the agent's `body` by target `acceleration`.
|
2020-04-03 02:31:59 +02:00
|
|
|
# @tags - virtual
|
2020-02-11 18:33:25 +01:00
|
|
|
func _apply_steering(acceleration: GSAITargetAcceleration, delta: float) -> void:
|
2020-02-06 20:54:12 +01:00
|
|
|
_applied_steering = true
|
2023-01-13 13:09:18 +01:00
|
|
|
|
|
|
|
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)
|
2020-02-14 17:35:18 +01:00
|
|
|
|
2020-02-06 22:29:48 +01:00
|
|
|
_apply_orientation_steering(acceleration.angular, delta)
|
2020-02-06 20:54:12 +01:00
|
|
|
|
|
|
|
|
2020-03-03 20:45:18 +01:00
|
|
|
func _apply_sliding_steering(accel: Vector3, delta: float) -> void:
|
2020-02-20 16:58:00 +01:00
|
|
|
var _body: KinematicBody2D = _body_ref.get_ref()
|
2023-01-13 13:09:18 +01:00
|
|
|
|
|
|
|
if !_body:
|
2020-02-20 16:58:00 +01:00
|
|
|
return
|
2021-09-02 16:44:08 +02:00
|
|
|
|
2023-01-13 13:09:18 +01:00
|
|
|
if !_body.is_inside_tree() or _body.get_tree().paused:
|
2021-09-02 16:44:08 +02:00
|
|
|
return
|
2020-02-20 16:58:00 +01:00
|
|
|
|
2023-01-13 13:09:18 +01:00
|
|
|
var velocity : Vector2 = GSAIUtils.to_vector2(linear_velocity + accel * delta).clamped(linear_speed_max)
|
|
|
|
|
2020-02-06 20:54:12 +01:00
|
|
|
if apply_linear_drag:
|
|
|
|
velocity = velocity.linear_interpolate(Vector2.ZERO, linear_drag_percentage)
|
2023-01-13 13:09:18 +01:00
|
|
|
|
2020-02-20 16:58:00 +01:00
|
|
|
velocity = _body.move_and_slide(velocity)
|
2023-01-13 13:09:18 +01:00
|
|
|
|
2020-02-06 20:54:12 +01:00
|
|
|
if calculate_velocities:
|
2020-02-11 18:33:25 +01:00
|
|
|
linear_velocity = GSAIUtils.to_vector3(velocity)
|
2020-02-06 20:54:12 +01:00
|
|
|
|
|
|
|
|
|
|
|
func _apply_collide_steering(accel: Vector3, delta: float) -> void:
|
2020-02-20 16:58:00 +01:00
|
|
|
var _body: KinematicBody2D = _body_ref.get_ref()
|
2023-01-13 13:09:18 +01:00
|
|
|
if !_body:
|
2020-02-20 16:58:00 +01:00
|
|
|
return
|
|
|
|
|
2023-01-13 13:09:18 +01:00
|
|
|
var velocity : Vector3 = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max)
|
2020-02-06 20:54:12 +01:00
|
|
|
if apply_linear_drag:
|
2020-02-14 17:35:18 +01:00
|
|
|
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage)
|
2023-01-13 13:09:18 +01:00
|
|
|
|
2020-02-11 20:36:06 +01:00
|
|
|
# warning-ignore:return_value_discarded
|
2020-02-20 16:58:00 +01:00
|
|
|
_body.move_and_collide(GSAIUtils.to_vector2(velocity) * delta)
|
2023-01-13 13:09:18 +01:00
|
|
|
|
2020-02-06 20:54:12 +01:00
|
|
|
if calculate_velocities:
|
|
|
|
linear_velocity = velocity
|
|
|
|
|
|
|
|
|
2020-02-07 11:29:45 +01:00
|
|
|
func _apply_position_steering(accel: Vector3, delta: float) -> void:
|
2020-02-20 16:58:00 +01:00
|
|
|
var _body: KinematicBody2D = _body_ref.get_ref()
|
2023-01-13 13:09:18 +01:00
|
|
|
if !_body:
|
2020-02-20 16:58:00 +01:00
|
|
|
return
|
|
|
|
|
2023-01-13 13:09:18 +01:00
|
|
|
var velocity : Vector3 = GSAIUtils.clampedv3(linear_velocity + accel * delta, linear_speed_max)
|
|
|
|
|
2020-02-06 20:54:12 +01:00
|
|
|
if apply_linear_drag:
|
2020-02-14 17:35:18 +01:00
|
|
|
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage)
|
2023-01-13 13:09:18 +01:00
|
|
|
|
2020-02-20 16:58:00 +01:00
|
|
|
_body.global_position += GSAIUtils.to_vector2(velocity) * delta
|
2023-01-13 13:09:18 +01:00
|
|
|
|
2020-02-06 20:54:12 +01:00
|
|
|
if calculate_velocities:
|
|
|
|
linear_velocity = velocity
|
|
|
|
|
|
|
|
|
|
|
|
func _apply_orientation_steering(angular_acceleration: float, delta: float) -> void:
|
2020-02-20 16:58:00 +01:00
|
|
|
var _body: KinematicBody2D = _body_ref.get_ref()
|
2023-01-13 13:09:18 +01:00
|
|
|
|
|
|
|
if !_body:
|
2020-02-20 16:58:00 +01:00
|
|
|
return
|
|
|
|
|
2023-01-13 13:09:18 +01:00
|
|
|
var velocity = clamp(angular_velocity + angular_acceleration * delta, -angular_speed_max, angular_speed_max)
|
|
|
|
|
2020-02-06 20:54:12 +01:00
|
|
|
if apply_angular_drag:
|
|
|
|
velocity = lerp(velocity, 0, angular_drag_percentage)
|
2023-01-13 13:09:18 +01:00
|
|
|
|
2020-02-20 16:58:00 +01:00
|
|
|
_body.rotation += velocity * delta
|
2023-01-13 13:09:18 +01:00
|
|
|
|
2020-02-06 20:54:12 +01:00
|
|
|
if calculate_velocities:
|
|
|
|
angular_velocity = velocity
|
|
|
|
|
|
|
|
|
2020-02-06 22:29:48 +01:00
|
|
|
func _set_body(value: KinematicBody2D) -> void:
|
2020-05-08 18:40:48 +02:00
|
|
|
body = value
|
2020-02-20 16:58:00 +01:00
|
|
|
_body_ref = weakref(body)
|
2020-02-14 17:35:18 +01:00
|
|
|
|
2020-02-20 16:58:00 +01:00
|
|
|
_last_position = value.global_position
|
|
|
|
_last_orientation = value.rotation
|
2020-02-14 17:35:18 +01:00
|
|
|
|
2020-02-11 18:33:25 +01:00
|
|
|
position = GSAIUtils.to_vector3(_last_position)
|
2020-02-06 20:54:12 +01:00
|
|
|
orientation = _last_orientation
|
|
|
|
|
|
|
|
|
2020-02-07 11:29:45 +01:00
|
|
|
func _on_SceneTree_physics_frame() -> void:
|
2020-02-20 16:58:00 +01:00
|
|
|
var _body: KinematicBody2D = _body_ref.get_ref()
|
2023-01-13 13:09:18 +01:00
|
|
|
if !_body:
|
2020-02-20 16:58:00 +01:00
|
|
|
return
|
|
|
|
|
2023-01-13 13:09:18 +01:00
|
|
|
var current_position : Vector2 = _body.global_position
|
|
|
|
var current_orientation : float = _body.rotation
|
2020-02-14 17:35:18 +01:00
|
|
|
|
2020-02-11 18:33:25 +01:00
|
|
|
position = GSAIUtils.to_vector3(current_position)
|
2020-02-06 20:54:12 +01:00
|
|
|
orientation = current_orientation
|
2020-02-14 17:35:18 +01:00
|
|
|
|
2020-02-06 20:54:12 +01:00
|
|
|
if calculate_velocities:
|
|
|
|
if _applied_steering:
|
|
|
|
_applied_steering = false
|
|
|
|
else:
|
2023-01-13 13:09:18 +01:00
|
|
|
linear_velocity = GSAIUtils.clampedv3(GSAIUtils.to_vector3(current_position - _last_position), linear_speed_max)
|
|
|
|
|
2020-02-06 22:29:48 +01:00
|
|
|
if apply_linear_drag:
|
2023-01-13 13:09:18 +01:00
|
|
|
linear_velocity = linear_velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage)
|
2020-02-14 17:35:18 +01:00
|
|
|
|
2023-01-13 13:09:18 +01:00
|
|
|
angular_velocity = clamp(_last_orientation - current_orientation, -angular_speed_max, angular_speed_max)
|
2020-02-14 17:35:18 +01:00
|
|
|
|
2020-02-06 22:29:48 +01:00
|
|
|
if apply_angular_drag:
|
2020-02-14 17:35:18 +01:00
|
|
|
angular_velocity = lerp(angular_velocity, 0, angular_drag_percentage)
|
|
|
|
|
2020-02-06 20:54:12 +01:00
|
|
|
_last_position = current_position
|
|
|
|
_last_orientation = current_orientation
|