2020-01-29 17:04:04 +01:00
|
|
|
# Calculates an angular acceleration to match an agent's orientation to that of
|
|
|
|
# its target. Attempts to make the agent arrive with zero remaining angular
|
|
|
|
# velocity.
|
2020-02-22 18:48:58 +01:00
|
|
|
# category: Individual behaviors
|
2020-02-11 18:33:25 +01:00
|
|
|
class_name GSAIMatchOrientation
|
|
|
|
extends GSAISteeringBehavior
|
2019-12-16 17:22:03 +01:00
|
|
|
|
2020-01-29 17:04:04 +01:00
|
|
|
# The target orientation for the behavior to try and match rotations to.
|
2020-02-11 18:33:25 +01:00
|
|
|
var target: GSAIAgentLocation
|
2020-01-29 17:04:04 +01:00
|
|
|
# The amount of distance in radians for the behavior to consider itself close
|
|
|
|
# enough to be matching the target agent's rotation.
|
2019-12-16 17:22:03 +01:00
|
|
|
var alignment_tolerance: float
|
2020-01-29 17:04:04 +01:00
|
|
|
# The amount of distance in radians from the goal to start slowing down.
|
2019-12-16 17:22:03 +01:00
|
|
|
var deceleration_radius: float
|
2020-01-29 05:56:10 +01:00
|
|
|
# The amount of time to reach the target velocity
|
2019-12-19 20:04:08 +01:00
|
|
|
var time_to_reach: float = 0.1
|
2020-02-13 09:33:03 +01:00
|
|
|
# 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
|
2019-12-16 17:22:03 +01:00
|
|
|
|
|
|
|
|
2020-02-13 09:33:03 +01:00
|
|
|
func _init(agent: GSAISteeringAgent, _target: GSAIAgentLocation, _use_z := false).(agent) -> void:
|
|
|
|
self.use_z = _use_z
|
2020-02-11 20:36:06 +01:00
|
|
|
self.target = _target
|
2019-12-16 17:22:03 +01:00
|
|
|
|
|
|
|
|
2020-02-11 18:33:25 +01:00
|
|
|
func _match_orientation(acceleration: GSAITargetAcceleration, desired_orientation: float) -> void:
|
2020-01-16 09:44:44 +01:00
|
|
|
var rotation := wrapf(desired_orientation - agent.orientation, -PI, PI)
|
2019-12-16 17:22:03 +01:00
|
|
|
|
2020-01-16 09:44:44 +01:00
|
|
|
var rotation_size := abs(rotation)
|
2019-12-16 17:22:03 +01:00
|
|
|
|
|
|
|
if rotation_size <= alignment_tolerance:
|
2019-12-19 21:24:40 +01:00
|
|
|
acceleration.set_zero()
|
|
|
|
else:
|
2020-01-22 17:55:49 +01:00
|
|
|
var desired_rotation := agent.angular_speed_max
|
2020-01-29 17:04:04 +01:00
|
|
|
|
2019-12-19 21:24:40 +01:00
|
|
|
if rotation_size <= deceleration_radius:
|
|
|
|
desired_rotation *= rotation_size / deceleration_radius
|
2020-01-29 17:04:04 +01:00
|
|
|
|
2019-12-19 21:24:40 +01:00
|
|
|
desired_rotation *= rotation / rotation_size
|
2020-01-29 17:04:04 +01:00
|
|
|
|
2020-02-14 17:35:18 +01:00
|
|
|
acceleration.angular = ((desired_rotation - agent.angular_velocity) / time_to_reach)
|
2020-01-29 17:04:04 +01:00
|
|
|
|
2020-01-16 09:44:44 +01:00
|
|
|
var limited_acceleration := abs(acceleration.angular)
|
2020-01-22 17:55:49 +01:00
|
|
|
if limited_acceleration > agent.angular_acceleration_max:
|
2020-02-14 17:35:18 +01:00
|
|
|
acceleration.angular *= (agent.angular_acceleration_max / limited_acceleration)
|
2020-01-29 17:04:04 +01:00
|
|
|
|
2019-12-20 19:17:27 +01:00
|
|
|
acceleration.linear = Vector3.ZERO
|
2020-01-29 17:04:04 +01:00
|
|
|
|
2019-12-16 17:22:03 +01:00
|
|
|
|
2020-02-11 18:33:25 +01:00
|
|
|
func _calculate_steering(acceleration: GSAITargetAcceleration) -> void:
|
2020-02-06 20:46:21 +01:00
|
|
|
_match_orientation(acceleration, target.orientation)
|