From 4885707145bc84a94fbb16166f3b7dbedcfea7fc Mon Sep 17 00:00:00 2001 From: Francois Belair Date: Wed, 29 Jan 2020 10:04:47 -0500 Subject: [PATCH] Improved how the AI looks in Pursue VS Seek demo They were looking kind of floaty, moving not like spaceships but like they were on ice. Now they travel along their orientation, towards where the player is/will be. --- project/demos/PursueSeek/PursueVSSeekDemo.tscn | 8 +++++--- project/demos/PursueSeek/Pursuer.gd | 18 +++++++++++------- project/demos/Quickstart/Player.gd | 2 +- project/src/Behaviors/GSTFace.gd | 2 +- project/src/Behaviors/GSTLookWhereYouGo.gd | 2 +- project/src/GSTPath.gd | 1 + project/src/GSTUtils.gd | 10 +++++++++- 7 files changed, 29 insertions(+), 14 deletions(-) diff --git a/project/demos/PursueSeek/PursueVSSeekDemo.tscn b/project/demos/PursueSeek/PursueVSSeekDemo.tscn index 179c5d1..8f6c051 100644 --- a/project/demos/PursueSeek/PursueVSSeekDemo.tscn +++ b/project/demos/PursueSeek/PursueVSSeekDemo.tscn @@ -14,12 +14,13 @@ __meta__ = { } linear_speed_max = 240.0 linear_accel_max = 40.0 +predict_time = 1.1 [node name="BoundaryManager" type="Node2D" parent="."] script = ExtResource( 3 ) [node name="Player" type="KinematicBody2D" parent="BoundaryManager"] -position = Vector2( 49.2031, 556.936 ) +position = Vector2( 47.3369, 329.724 ) rotation = 1.5708 collision_mask = 2 script = ExtResource( 2 ) @@ -34,7 +35,7 @@ modulate = Color( 0.968627, 0.188235, 0.0352941, 1 ) texture = ExtResource( 6 ) [node name="Pursuer" type="KinematicBody2D" parent="BoundaryManager"] -position = Vector2( 868.495, 200 ) +position = Vector2( 980, 550 ) collision_layer = 2 script = ExtResource( 1 ) @@ -46,7 +47,8 @@ modulate = Color( 0.756863, 0.952941, 0.054902, 1 ) texture = ExtResource( 6 ) [node name="Seeker" type="KinematicBody2D" parent="BoundaryManager"] -position = Vector2( 821.24, 200 ) +position = Vector2( 980, 150 ) +rotation = 3.14159 collision_layer = 2 script = ExtResource( 1 ) use_seek = true diff --git a/project/demos/PursueSeek/Pursuer.gd b/project/demos/PursueSeek/Pursuer.gd index 70620c6..133fd57 100644 --- a/project/demos/PursueSeek/Pursuer.gd +++ b/project/demos/PursueSeek/Pursuer.gd @@ -11,6 +11,7 @@ var _linear_velocity := Vector2() var _linear_drag_coefficient := 0.025 var _angular_velocity := 0.0 var _angular_drag := 0.1 +var _direction_face := GSTAgentLocation.new() onready var agent := GSTSteeringAgent.new() onready var accel := GSTTargetAcceleration.new() @@ -24,6 +25,10 @@ func _ready() -> void: func _physics_process(delta: float) -> void: _update_agent() + accel = _behavior.calculate_steering(accel) + + _direction_face.position = agent.position + accel.linear.normalized() + accel = _orient_behavior.calculate_steering(accel) _angular_velocity += accel.angular @@ -35,8 +40,7 @@ func _physics_process(delta: float) -> void: rotation += _angular_velocity * delta - accel = _behavior.calculate_steering(accel) - _linear_velocity += Vector2(accel.linear.x, accel.linear.y) + _linear_velocity += GSTUtils.angle_to_vector2(rotation) * -agent.linear_acceleration_max _linear_velocity = _linear_velocity.clamped(agent.linear_speed_max) _linear_velocity = _linear_velocity.linear_interpolate(Vector2.ZERO, _linear_drag_coefficient) _linear_velocity = move_and_slide(_linear_velocity) @@ -48,12 +52,12 @@ func setup(predict_time: float, linear_speed_max: float, linear_accel_max: float else: _behavior = GSTPursue.new(agent, player_agent, predict_time) - _orient_behavior = GSTLookWhereYouGo.new(agent) - _orient_behavior.alignment_tolerance = 0.001 - _orient_behavior.deceleration_radius = PI/2 + _orient_behavior = GSTFace.new(agent, _direction_face) + _orient_behavior.alignment_tolerance = deg2rad(5) + _orient_behavior.deceleration_radius = deg2rad(5) - agent.angular_acceleration_max = deg2rad(10) - agent.angular_speed_max = deg2rad(45) + agent.angular_acceleration_max = deg2rad(40) + agent.angular_speed_max = deg2rad(90) agent.linear_acceleration_max = linear_accel_max agent.linear_speed_max = linear_speed_max diff --git a/project/demos/Quickstart/Player.gd b/project/demos/Quickstart/Player.gd index 403a8e1..8aed2b3 100644 --- a/project/demos/Quickstart/Player.gd +++ b/project/demos/Quickstart/Player.gd @@ -39,7 +39,7 @@ func _physics_process(delta: float) -> void: var movement := get_movement() - direction = Vector2(sin(-rotation), cos(rotation)) + direction = GSTUtils.angle_to_vector2(rotation) velocity += direction * acceleration_max * movement velocity = velocity.clamped(speed_max) diff --git a/project/src/Behaviors/GSTFace.gd b/project/src/Behaviors/GSTFace.gd index 384745c..759389d 100644 --- a/project/src/Behaviors/GSTFace.gd +++ b/project/src/Behaviors/GSTFace.gd @@ -16,7 +16,7 @@ func _face(acceleration: GSTTargetAcceleration, target_position: Vector3) -> GST acceleration.set_zero() return acceleration else: - var orientation = GSTUtils.vector_to_angle(to_target) + var orientation = GSTUtils.vector3_to_angle(to_target) return _match_orientation(acceleration, orientation) diff --git a/project/src/Behaviors/GSTLookWhereYouGo.gd b/project/src/Behaviors/GSTLookWhereYouGo.gd index bc76876..4492018 100644 --- a/project/src/Behaviors/GSTLookWhereYouGo.gd +++ b/project/src/Behaviors/GSTLookWhereYouGo.gd @@ -12,5 +12,5 @@ func _calculate_steering(accel: GSTTargetAcceleration) -> GSTTargetAcceleration: accel.set_zero() return accel else: - var orientation := GSTUtils.vector_to_angle(agent.linear_velocity) + var orientation := GSTUtils.vector3_to_angle(agent.linear_velocity) return _match_orientation(accel, orientation) diff --git a/project/src/GSTPath.gd b/project/src/GSTPath.gd index 83fc958..9cad4b6 100644 --- a/project/src/GSTPath.gd +++ b/project/src/GSTPath.gd @@ -14,6 +14,7 @@ var _segments: Array var _nearest_point_on_segment: Vector3 var _nearest_point_on_path: Vector3 + func _init(waypoints: Array, open := false) -> void: self.open = open create_path(waypoints) diff --git a/project/src/GSTUtils.gd b/project/src/GSTUtils.gd index 4a5c311..d3e1c89 100644 --- a/project/src/GSTUtils.gd +++ b/project/src/GSTUtils.gd @@ -15,5 +15,13 @@ static func clampedv3(vector: Vector3, limit: float) -> Vector3: # # This assumes orientation for 2D agents or 3D agents that are upright and # rotate around the Y axis. -static func vector_to_angle(vector: Vector3) -> float: +static func vector3_to_angle(vector: Vector3) -> float: return atan2(vector.x, -vector.y) + + +# Returns a directional vector from the given orientation angle. +# +# This assumes orientation for 2D agents or 3D agents that are upright and +# rotate around the Y axis. +static func angle_to_vector2(angle: float) -> Vector2: + return Vector2(sin(-angle), cos(angle))