mirror of
https://github.com/Relintai/godot-steering-ai-framework.git
synced 2024-11-14 04:57:19 +01:00
Split agent types into specialized classes
This commit is contained in:
parent
7311b75456
commit
2ae06d3da3
@ -1,7 +1,7 @@
|
|||||||
extends KinematicBody2D
|
extends KinematicBody2D
|
||||||
|
|
||||||
|
|
||||||
var agent := GSTNode2DAgent.new(self)
|
var agent := GSTKinematicBody2DAgent.new(self)
|
||||||
var target := GSTAgentLocation.new()
|
var target := GSTAgentLocation.new()
|
||||||
var arrive := GSTArrive.new(agent, target)
|
var arrive := GSTArrive.new(agent, target)
|
||||||
var _accel := GSTTargetAcceleration.new()
|
var _accel := GSTTargetAcceleration.new()
|
||||||
|
@ -13,7 +13,7 @@ var _drag := 0.1
|
|||||||
var _color := Color(0.4, 1.0, 0.89, 0.3)
|
var _color := Color(0.4, 1.0, 0.89, 0.3)
|
||||||
|
|
||||||
onready var collision := $CollisionShape2D
|
onready var collision := $CollisionShape2D
|
||||||
onready var agent := GSTNode2DAgent.new(self)
|
onready var agent := GSTKinematicBody2DAgent.new(self)
|
||||||
onready var proximity := GSTRadiusProximity.new(agent, [], 140)
|
onready var proximity := GSTRadiusProximity.new(agent, [], 140)
|
||||||
onready var avoid := GSTAvoidCollisions.new(agent, proximity)
|
onready var avoid := GSTAvoidCollisions.new(agent, proximity)
|
||||||
onready var target := GSTAgentLocation.new()
|
onready var target := GSTAgentLocation.new()
|
||||||
|
@ -2,7 +2,7 @@ extends KinematicBody2D
|
|||||||
|
|
||||||
|
|
||||||
var face: GSTFace
|
var face: GSTFace
|
||||||
var agent := GSTNode2DAgent.new(self)
|
var agent := GSTKinematicBody2DAgent.new(self)
|
||||||
|
|
||||||
var _accel := GSTTargetAcceleration.new()
|
var _accel := GSTTargetAcceleration.new()
|
||||||
var _angular_drag := 0.1
|
var _angular_drag := 0.1
|
||||||
|
@ -6,7 +6,7 @@ var _accel := GSTTargetAcceleration.new()
|
|||||||
var _valid := false
|
var _valid := false
|
||||||
var _drag := 0.1
|
var _drag := 0.1
|
||||||
|
|
||||||
onready var agent := GSTNode2DAgent.new(self)
|
onready var agent := GSTKinematicBody2DAgent.new(self)
|
||||||
onready var path := GSTPath.new([
|
onready var path := GSTPath.new([
|
||||||
Vector3(global_position.x, global_position.y, 0),
|
Vector3(global_position.x, global_position.y, 0),
|
||||||
Vector3(global_position.x, global_position.y, 0)
|
Vector3(global_position.x, global_position.y, 0)
|
||||||
|
@ -4,7 +4,7 @@ extends KinematicBody2D
|
|||||||
var separation: GSTSeparation
|
var separation: GSTSeparation
|
||||||
var cohesion: GSTCohesion
|
var cohesion: GSTCohesion
|
||||||
var proximity: GSTRadiusProximity
|
var proximity: GSTRadiusProximity
|
||||||
var agent := GSTNode2DAgent.new(self)
|
var agent := GSTKinematicBody2DAgent.new(self)
|
||||||
var blend := GSTBlend.new(agent)
|
var blend := GSTBlend.new(agent)
|
||||||
var acceleration := GSTTargetAcceleration.new()
|
var acceleration := GSTTargetAcceleration.new()
|
||||||
var draw_proximity := false
|
var draw_proximity := false
|
||||||
|
@ -12,6 +12,5 @@ script = ExtResource( 1 )
|
|||||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||||
shape = SubResource( 1 )
|
shape = SubResource( 1 )
|
||||||
script = ExtResource( 3 )
|
script = ExtResource( 3 )
|
||||||
inner_color = Color( 0, 0, 0, 1 )
|
|
||||||
outer_color = Color( 0.301961, 0.65098, 1, 1 )
|
outer_color = Color( 0.301961, 0.65098, 1, 1 )
|
||||||
stroke = 4.0
|
stroke = 4.0
|
||||||
|
@ -10,7 +10,7 @@ var _linear_drag_coefficient := 0.025
|
|||||||
var _angular_drag := 0.1
|
var _angular_drag := 0.1
|
||||||
var _direction_face := GSTAgentLocation.new()
|
var _direction_face := GSTAgentLocation.new()
|
||||||
|
|
||||||
onready var agent := GSTNode2DAgent.new(self)
|
onready var agent := GSTKinematicBody2DAgent.new(self)
|
||||||
onready var accel := GSTTargetAcceleration.new()
|
onready var accel := GSTTargetAcceleration.new()
|
||||||
onready var player_agent: GSTSteeringAgent = owner.find_node("Player", true, false).agent
|
onready var player_agent: GSTSteeringAgent = owner.find_node("Player", true, false).agent
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ var start_speed: float
|
|||||||
var start_accel: float
|
var start_accel: float
|
||||||
var use_seek := true
|
var use_seek := true
|
||||||
|
|
||||||
onready var agent := GSTNode2DAgent.new(self)
|
onready var agent := GSTKinematicBody2DAgent.new(self)
|
||||||
onready var accel := GSTTargetAcceleration.new()
|
onready var accel := GSTTargetAcceleration.new()
|
||||||
onready var seek := GSTSeek.new(agent, player_agent)
|
onready var seek := GSTSeek.new(agent, player_agent)
|
||||||
onready var flee := GSTFlee.new(agent, player_agent)
|
onready var flee := GSTFlee.new(agent, player_agent)
|
||||||
|
@ -64,6 +64,16 @@ _global_script_classes=[ {
|
|||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://src/Proximities/GSTInfiniteProximity.gd"
|
"path": "res://src/Proximities/GSTInfiniteProximity.gd"
|
||||||
}, {
|
}, {
|
||||||
|
"base": "GSTSpecializedAgent",
|
||||||
|
"class": "GSTKinematicBody2DAgent",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://src/Agents/GSTKinematicBody2DAgent.gd"
|
||||||
|
}, {
|
||||||
|
"base": "GSTSpecializedAgent",
|
||||||
|
"class": "GSTKinematicBodyAgent",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://src/Agents/GSTKinematicBodyAgent.gd"
|
||||||
|
}, {
|
||||||
"base": "GSTMatchOrientation",
|
"base": "GSTMatchOrientation",
|
||||||
"class": "GSTLookWhereYouGo",
|
"class": "GSTLookWhereYouGo",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
@ -74,16 +84,6 @@ _global_script_classes=[ {
|
|||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://src/Behaviors/GSTMatchOrientation.gd"
|
"path": "res://src/Behaviors/GSTMatchOrientation.gd"
|
||||||
}, {
|
}, {
|
||||||
"base": "GSTNodeAgent",
|
|
||||||
"class": "GSTNode2DAgent",
|
|
||||||
"language": "GDScript",
|
|
||||||
"path": "res://src/Agents/GSTNode2DAgent.gd"
|
|
||||||
}, {
|
|
||||||
"base": "GSTSteeringAgent",
|
|
||||||
"class": "GSTNodeAgent",
|
|
||||||
"language": "GDScript",
|
|
||||||
"path": "res://src/Agents/GSTNodeAgent.gd"
|
|
||||||
}, {
|
|
||||||
"base": "Reference",
|
"base": "Reference",
|
||||||
"class": "GSTPath",
|
"class": "GSTPath",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
@ -109,6 +109,16 @@ _global_script_classes=[ {
|
|||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://src/Proximities/GSTRadiusProximity.gd"
|
"path": "res://src/Proximities/GSTRadiusProximity.gd"
|
||||||
}, {
|
}, {
|
||||||
|
"base": "GSTSpecializedAgent",
|
||||||
|
"class": "GSTRigidBody2DAgent",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://src/Agents/GSTRigidBody2DAgent.gd"
|
||||||
|
}, {
|
||||||
|
"base": "GSTSpecializedAgent",
|
||||||
|
"class": "GSTRigidBodyAgent",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://src/Agents/GSTRigidBodyAgent.gd"
|
||||||
|
}, {
|
||||||
"base": "GSTSteeringBehavior",
|
"base": "GSTSteeringBehavior",
|
||||||
"class": "GSTSeek",
|
"class": "GSTSeek",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
@ -119,10 +129,10 @@ _global_script_classes=[ {
|
|||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://src/Behaviors/GSTSeparation.gd"
|
"path": "res://src/Behaviors/GSTSeparation.gd"
|
||||||
}, {
|
}, {
|
||||||
"base": "GSTNodeAgent",
|
"base": "GSTSteeringAgent",
|
||||||
"class": "GSTSpatialAgent",
|
"class": "GSTSpecializedAgent",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://src/Agents/GSTSpatialAgent.gd"
|
"path": "res://src/Agents/GSTSpecializedAgent.gd"
|
||||||
}, {
|
}, {
|
||||||
"base": "GSTAgentLocation",
|
"base": "GSTAgentLocation",
|
||||||
"class": "GSTSteeringAgent",
|
"class": "GSTSteeringAgent",
|
||||||
@ -156,18 +166,20 @@ _global_script_class_icons={
|
|||||||
"GSTFollowPath": "",
|
"GSTFollowPath": "",
|
||||||
"GSTGroupBehavior": "",
|
"GSTGroupBehavior": "",
|
||||||
"GSTInfiniteProximity": "",
|
"GSTInfiniteProximity": "",
|
||||||
|
"GSTKinematicBody2DAgent": "",
|
||||||
|
"GSTKinematicBodyAgent": "",
|
||||||
"GSTLookWhereYouGo": "",
|
"GSTLookWhereYouGo": "",
|
||||||
"GSTMatchOrientation": "",
|
"GSTMatchOrientation": "",
|
||||||
"GSTNode2DAgent": "",
|
|
||||||
"GSTNodeAgent": "",
|
|
||||||
"GSTPath": "",
|
"GSTPath": "",
|
||||||
"GSTPriority": "",
|
"GSTPriority": "",
|
||||||
"GSTProximity": "",
|
"GSTProximity": "",
|
||||||
"GSTPursue": "",
|
"GSTPursue": "",
|
||||||
"GSTRadiusProximity": "",
|
"GSTRadiusProximity": "",
|
||||||
|
"GSTRigidBody2DAgent": "",
|
||||||
|
"GSTRigidBodyAgent": "",
|
||||||
"GSTSeek": "",
|
"GSTSeek": "",
|
||||||
"GSTSeparation": "",
|
"GSTSeparation": "",
|
||||||
"GSTSpatialAgent": "",
|
"GSTSpecializedAgent": "",
|
||||||
"GSTSteeringAgent": "",
|
"GSTSteeringAgent": "",
|
||||||
"GSTSteeringBehavior": "",
|
"GSTSteeringBehavior": "",
|
||||||
"GSTTargetAcceleration": "",
|
"GSTTargetAcceleration": "",
|
||||||
|
@ -1,16 +1,26 @@
|
|||||||
# A specialized steering agent that updates itself every frame so the user does
|
# A specialized steering agent that updates itself every frame so the user does
|
||||||
# not have to.
|
# not have to using a KinematicBody2D
|
||||||
extends GSTNodeAgent
|
extends GSTSpecializedAgent
|
||||||
class_name GSTNode2DAgent
|
class_name GSTKinematicBody2DAgent
|
||||||
|
|
||||||
|
|
||||||
# The Node2D to keep track of
|
enum KinematicMovementType { SLIDE, COLLIDE, POSITION }
|
||||||
var body: Node2D setget _set_body
|
|
||||||
|
|
||||||
|
# The KinematicBody2D to keep track of
|
||||||
|
var body: KinematicBody2D setget _set_body
|
||||||
|
|
||||||
|
# The type of movement the body executes
|
||||||
|
#
|
||||||
|
# SLIDE uses use move_and_slide
|
||||||
|
# COLLIDE uses move_and_collide
|
||||||
|
# POSITION changes the global_position directly
|
||||||
|
var kinematic_movement_type: int = KinematicMovementType.SLIDE
|
||||||
|
|
||||||
var _last_position: Vector2
|
var _last_position: Vector2
|
||||||
|
|
||||||
|
|
||||||
func _init(body: Node2D) -> void:
|
func _init(body: KinematicBody2D) -> void:
|
||||||
self.body = body
|
self.body = body
|
||||||
if body.is_inside_tree():
|
if body.is_inside_tree():
|
||||||
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame")
|
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame")
|
||||||
@ -22,29 +32,15 @@ func _init(body: Node2D) -> void:
|
|||||||
# tags: virtual
|
# tags: virtual
|
||||||
func _apply_steering(acceleration: GSTTargetAcceleration, delta: float) -> void:
|
func _apply_steering(acceleration: GSTTargetAcceleration, delta: float) -> void:
|
||||||
_applied_steering = true
|
_applied_steering = true
|
||||||
match _body_type:
|
match kinematic_movement_type:
|
||||||
BodyType.RIGID:
|
KinematicMovementType.COLLIDE:
|
||||||
_apply_rigid_steering(acceleration)
|
_apply_collide_steering(acceleration.linear, delta)
|
||||||
BodyType.KINEMATIC:
|
KinematicMovementType.SLIDE:
|
||||||
match kinematic_movement_type:
|
_apply_sliding_steering(acceleration.linear)
|
||||||
MovementType.COLLIDE:
|
_:
|
||||||
_apply_collide_steering(acceleration.linear, delta)
|
|
||||||
MovementType.SLIDE:
|
|
||||||
_apply_sliding_steering(acceleration.linear)
|
|
||||||
MovementType.POSITION:
|
|
||||||
_apply_normal_steering(acceleration.linear, delta)
|
|
||||||
BodyType.NODE:
|
|
||||||
_apply_normal_steering(acceleration.linear, delta)
|
_apply_normal_steering(acceleration.linear, delta)
|
||||||
if not _body_type == BodyType.RIGID:
|
|
||||||
_apply_orientation_steering(acceleration.angular, delta)
|
|
||||||
|
|
||||||
|
_apply_orientation_steering(acceleration.angular, delta)
|
||||||
func _apply_rigid_steering(accel: GSTTargetAcceleration) -> void:
|
|
||||||
body.apply_central_impulse(GSTUtils.to_vector2(accel.linear))
|
|
||||||
body.apply_torque_impulse(accel.angular)
|
|
||||||
if calculate_velocities:
|
|
||||||
linear_velocity = GSTUtils.to_vector3(body.linear_velocity)
|
|
||||||
angular_velocity = body.angular_velocity
|
|
||||||
|
|
||||||
|
|
||||||
func _apply_sliding_steering(accel: Vector3) -> void:
|
func _apply_sliding_steering(accel: Vector3) -> void:
|
||||||
@ -89,31 +85,11 @@ func _apply_orientation_steering(angular_acceleration: float, delta: float) -> v
|
|||||||
angular_velocity = velocity
|
angular_velocity = velocity
|
||||||
|
|
||||||
|
|
||||||
func _set_use_physics(value: bool) -> void:
|
func _set_body(value: KinematicBody2D) -> void:
|
||||||
if use_physics and not value:
|
|
||||||
body.get_tree().disconnect("idle_frame", self, "_on_SceneTree_frame")
|
|
||||||
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame")
|
|
||||||
elif not use_physics and value:
|
|
||||||
body.get_tree().disconnect("physics_frame", self, "_on_SceneTree_frame")
|
|
||||||
body.get_tree().connect("idle_frame", self, "_on_SceneTree_frame")
|
|
||||||
use_physics = value
|
|
||||||
|
|
||||||
|
|
||||||
func _set_body(value: Node2D) -> void:
|
|
||||||
body = value
|
body = value
|
||||||
if body is RigidBody2D:
|
|
||||||
_body_type = BodyType.RIGID
|
|
||||||
elif body is KinematicBody2D:
|
|
||||||
_body_type = BodyType.KINEMATIC
|
|
||||||
else:
|
|
||||||
_body_type = BodyType.NODE
|
|
||||||
|
|
||||||
if _body_type == BodyType.RIGID:
|
_last_position = body.global_position
|
||||||
linear_velocity = GSTUtils.to_vector3(body.linear_velocity)
|
_last_orientation = body.rotation
|
||||||
angular_velocity = body.angular_velocity
|
|
||||||
else:
|
|
||||||
_last_position = body.global_position
|
|
||||||
_last_orientation = body.rotation
|
|
||||||
|
|
||||||
position = GSTUtils.to_vector3(_last_position)
|
position = GSTUtils.to_vector3(_last_position)
|
||||||
orientation = _last_orientation
|
orientation = _last_orientation
|
||||||
@ -135,31 +111,28 @@ func _on_SceneTree_frame() -> void:
|
|||||||
if _applied_steering:
|
if _applied_steering:
|
||||||
_applied_steering = false
|
_applied_steering = false
|
||||||
else:
|
else:
|
||||||
match _body_type:
|
linear_velocity = GSTUtils.clampedv3(
|
||||||
BodyType.RIGID:
|
GSTUtils.to_vector3(_last_position - current_position),
|
||||||
linear_velocity = GSTUtils.to_vector3(body.linear_velocity)
|
linear_speed_max
|
||||||
angular_velocity = body.angular_velocity
|
)
|
||||||
_:
|
if apply_linear_drag:
|
||||||
linear_velocity = GSTUtils.clampedv3(
|
linear_velocity = linear_velocity.linear_interpolate(
|
||||||
GSTUtils.to_vector3(_last_position - current_position),
|
Vector3.ZERO,
|
||||||
linear_speed_max
|
linear_drag_percentage
|
||||||
)
|
)
|
||||||
if apply_linear_drag:
|
|
||||||
linear_velocity = linear_velocity.linear_interpolate(
|
angular_velocity = clamp(
|
||||||
Vector3.ZERO,
|
_last_orientation - current_orientation,
|
||||||
linear_drag_percentage
|
-angular_speed_max,
|
||||||
)
|
angular_speed_max
|
||||||
angular_velocity = clamp(
|
)
|
||||||
_last_orientation - current_orientation,
|
|
||||||
-angular_speed_max,
|
if apply_angular_drag:
|
||||||
angular_speed_max
|
angular_velocity = lerp(
|
||||||
)
|
angular_velocity,
|
||||||
if apply_angular_drag:
|
0,
|
||||||
angular_velocity = lerp(
|
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
|
138
project/src/Agents/GSTKinematicBodyAgent.gd
Normal file
138
project/src/Agents/GSTKinematicBodyAgent.gd
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
# A specialized steering agent that updates itself every frame so the user does
|
||||||
|
# not have to using a KinematicBody
|
||||||
|
extends GSTSpecializedAgent
|
||||||
|
class_name GSTKinematicBodyAgent
|
||||||
|
|
||||||
|
|
||||||
|
enum KinematicMovementType { SLIDE, COLLIDE, POSITION }
|
||||||
|
|
||||||
|
|
||||||
|
# The KinematicBody to keep track of
|
||||||
|
var body: KinematicBody setget _set_body
|
||||||
|
|
||||||
|
# The type of movement the body executes
|
||||||
|
#
|
||||||
|
# SLIDE uses use move_and_slide
|
||||||
|
# COLLIDE uses move_and_collide
|
||||||
|
# POSITION changes the global_position directly
|
||||||
|
var kinematic_movement_type: int = KinematicMovementType.SLIDE
|
||||||
|
|
||||||
|
var _last_position: Vector3
|
||||||
|
|
||||||
|
|
||||||
|
func _init(body: KinematicBody) -> void:
|
||||||
|
self.body = body
|
||||||
|
if body.is_inside_tree():
|
||||||
|
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame")
|
||||||
|
else:
|
||||||
|
body.connect("ready", self, "_on_body_ready")
|
||||||
|
|
||||||
|
|
||||||
|
# Moves the agent's `body` by target `acceleration`.
|
||||||
|
# tags: virtual
|
||||||
|
func _apply_steering(acceleration: GSTTargetAcceleration, delta: float) -> void:
|
||||||
|
_applied_steering = true
|
||||||
|
match kinematic_movement_type:
|
||||||
|
KinematicMovementType.COLLIDE:
|
||||||
|
_apply_collide_steering(acceleration.linear, delta)
|
||||||
|
KinematicMovementType.SLIDE:
|
||||||
|
_apply_sliding_steering(acceleration.linear)
|
||||||
|
_:
|
||||||
|
_apply_normal_steering(acceleration.linear, delta)
|
||||||
|
|
||||||
|
_apply_orientation_steering(acceleration.angular, delta)
|
||||||
|
|
||||||
|
|
||||||
|
func _apply_sliding_steering(accel: Vector3) -> void:
|
||||||
|
var velocity := GSTUtils.clampedv3(linear_velocity + accel, linear_speed_max)
|
||||||
|
if apply_linear_drag:
|
||||||
|
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage)
|
||||||
|
velocity = body.move_and_slide(velocity)
|
||||||
|
if calculate_velocities:
|
||||||
|
linear_velocity = velocity
|
||||||
|
|
||||||
|
|
||||||
|
func _apply_collide_steering(accel: Vector3, delta: float) -> void:
|
||||||
|
var velocity := GSTUtils.clampedv3(linear_velocity + accel, linear_speed_max)
|
||||||
|
if apply_linear_drag:
|
||||||
|
velocity = velocity.linear_interpolate(
|
||||||
|
Vector3.ZERO,
|
||||||
|
linear_drag_percentage
|
||||||
|
)
|
||||||
|
body.move_and_collide(velocity * delta)
|
||||||
|
if calculate_velocities:
|
||||||
|
linear_velocity = velocity
|
||||||
|
|
||||||
|
|
||||||
|
func _apply_normal_steering(accel: Vector3, delta: float) -> void:
|
||||||
|
var velocity := GSTUtils.clampedv3(linear_velocity + accel, linear_speed_max)
|
||||||
|
if apply_linear_drag:
|
||||||
|
velocity = velocity.linear_interpolate(
|
||||||
|
Vector3.ZERO,
|
||||||
|
linear_drag_percentage
|
||||||
|
)
|
||||||
|
body.global_position += velocity * delta
|
||||||
|
if calculate_velocities:
|
||||||
|
linear_velocity = velocity
|
||||||
|
|
||||||
|
|
||||||
|
func _apply_orientation_steering(angular_acceleration: float, delta: float) -> void:
|
||||||
|
var velocity = angular_velocity + angular_acceleration
|
||||||
|
if apply_angular_drag:
|
||||||
|
velocity = lerp(velocity, 0, angular_drag_percentage)
|
||||||
|
body.rotation.y += velocity * delta
|
||||||
|
if calculate_velocities:
|
||||||
|
angular_velocity = velocity
|
||||||
|
|
||||||
|
|
||||||
|
func _set_body(value: KinematicBody) -> void:
|
||||||
|
body = value
|
||||||
|
|
||||||
|
_last_position = body.global_position
|
||||||
|
_last_orientation = body.rotation.y
|
||||||
|
|
||||||
|
position = _last_position
|
||||||
|
orientation = _last_orientation
|
||||||
|
|
||||||
|
|
||||||
|
func _on_body_ready() -> void:
|
||||||
|
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame")
|
||||||
|
_set_body(body)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_SceneTree_frame() -> void:
|
||||||
|
var current_position: Vector3 = body.global_position
|
||||||
|
var current_orientation: float = body.rotation.y
|
||||||
|
|
||||||
|
position = current_position
|
||||||
|
orientation = current_orientation
|
||||||
|
|
||||||
|
if calculate_velocities:
|
||||||
|
if _applied_steering:
|
||||||
|
_applied_steering = false
|
||||||
|
else:
|
||||||
|
linear_velocity = GSTUtils.clampedv3(
|
||||||
|
_last_position - current_position,
|
||||||
|
linear_speed_max
|
||||||
|
)
|
||||||
|
if apply_linear_drag:
|
||||||
|
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:
|
||||||
|
angular_velocity = lerp(
|
||||||
|
angular_velocity,
|
||||||
|
0,
|
||||||
|
angular_drag_percentage
|
||||||
|
)
|
||||||
|
|
||||||
|
_last_position = current_position
|
||||||
|
_last_orientation = current_orientation
|
@ -1,79 +0,0 @@
|
|||||||
# A base class for a specialized steering agent that updates itself every frame
|
|
||||||
# so the user does not have to.
|
|
||||||
extends GSTSteeringAgent
|
|
||||||
class_name GSTNodeAgent
|
|
||||||
|
|
||||||
|
|
||||||
enum MovementType { SLIDE, COLLIDE, POSITION }
|
|
||||||
|
|
||||||
enum BodyType { NODE, KINEMATIC, RIGID }
|
|
||||||
|
|
||||||
|
|
||||||
# If `true`, will update before `_physics_process` is called. If `false`, will
|
|
||||||
# update before `_process` is called.
|
|
||||||
#
|
|
||||||
# `KinematicBody`, `KinematicBody2D`, `RigidBody`, and `RigidBody2D` should
|
|
||||||
# always use `_physics_process`.
|
|
||||||
var use_physics := true setget _set_use_physics
|
|
||||||
|
|
||||||
# If `true`, will calculate linear and angular velocities based on the previous
|
|
||||||
# frame. When `false`, the user must keep those values updated.
|
|
||||||
var calculate_velocities := true
|
|
||||||
|
|
||||||
# If `true` and velocities and `calculate_velocities` is true, will interpolate
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# If `true` and velocities and `calculate_velocities` is true, will interpolate
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# The percentage between the current linear velocity and 0 to interpolate by if
|
|
||||||
# `calculate_velocities` and `apply_linear_drag` are true.
|
|
||||||
# Does not apply to `RigidBody` and `RigidBody2D` nodes.
|
|
||||||
var linear_drag_percentage := 0.0
|
|
||||||
|
|
||||||
# The percentage between the current angular velocity and 0 to interpolate by if
|
|
||||||
# `calculate_velocities` and `apply_angular_drag` are true.
|
|
||||||
# Does not apply to `RigidBody` and `RigidBody2D` nodes.
|
|
||||||
var angular_drag_percentage := 0.0
|
|
||||||
|
|
||||||
# Determines how linear movement occurs if the body is a `KinematicBody` or
|
|
||||||
# `KinematicBody2D`.
|
|
||||||
#
|
|
||||||
# SLIDE uses `move_and_slide`
|
|
||||||
# COLLIDE uses `move_and_collide`
|
|
||||||
# POSITION changes global position directly
|
|
||||||
var kinematic_movement_type: int = MovementType.SLIDE
|
|
||||||
|
|
||||||
var _last_orientation: float
|
|
||||||
var _body_type: int
|
|
||||||
var _applied_steering := false
|
|
||||||
|
|
||||||
|
|
||||||
# Moves the agent's body by target `acceleration`.
|
|
||||||
# tags: virtual
|
|
||||||
func _apply_steering(acceleration: GSTTargetAcceleration, delta: float) -> void:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
func _apply_sliding_steering(accel: Vector3) -> void:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
func _apply_collide_steering(accel: Vector3, delta: float) -> void:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
func _apply_normal_steering(accel: Vector3, delta: float) -> void:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
func _apply_orientation_steering(angular_acceleration: float, delta: float) -> void:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
func _set_use_physics(value: bool) -> void:
|
|
||||||
use_physics = value
|
|
59
project/src/Agents/GSTRigidBody2DAgent.gd
Normal file
59
project/src/Agents/GSTRigidBody2DAgent.gd
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# A specialized steering agent that updates itself every frame so the user does
|
||||||
|
# not have to using a RigidBody2D
|
||||||
|
extends GSTSpecializedAgent
|
||||||
|
class_name GSTRigidBody2DAgent
|
||||||
|
|
||||||
|
|
||||||
|
# The RigidBody2D to keep track of
|
||||||
|
var body: RigidBody2D setget _set_body
|
||||||
|
|
||||||
|
var _last_position: Vector2
|
||||||
|
|
||||||
|
|
||||||
|
func _init(body: RigidBody2D) -> void:
|
||||||
|
self.body = body
|
||||||
|
if body.is_inside_tree():
|
||||||
|
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame")
|
||||||
|
else:
|
||||||
|
body.connect("ready", self, "_on_body_ready")
|
||||||
|
|
||||||
|
|
||||||
|
# Moves the agent's `body` by target `acceleration`.
|
||||||
|
# tags: virtual
|
||||||
|
func _apply_steering(acceleration: GSTTargetAcceleration, delta: float) -> void:
|
||||||
|
_applied_steering = true
|
||||||
|
body.apply_central_impulse(GSTUtils.to_vector2(acceleration.linear))
|
||||||
|
body.apply_torque_impulse(acceleration.angular)
|
||||||
|
if calculate_velocities:
|
||||||
|
linear_velocity = GSTUtils.to_vector3(body.linear_velocity)
|
||||||
|
angular_velocity = body.angular_velocity
|
||||||
|
|
||||||
|
|
||||||
|
func _set_body(value: RigidBody2D) -> void:
|
||||||
|
body = value
|
||||||
|
|
||||||
|
_last_position = body.global_position
|
||||||
|
_last_orientation = body.rotation
|
||||||
|
|
||||||
|
position = GSTUtils.to_vector3(_last_position)
|
||||||
|
orientation = _last_orientation
|
||||||
|
|
||||||
|
|
||||||
|
func _on_body_ready() -> void:
|
||||||
|
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame")
|
||||||
|
_set_body(body)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_SceneTree_frame() -> void:
|
||||||
|
var current_position: Vector2 = body.global_position
|
||||||
|
var current_orientation: float = body.rotation
|
||||||
|
|
||||||
|
position = GSTUtils.to_vector3(current_position)
|
||||||
|
orientation = current_orientation
|
||||||
|
|
||||||
|
if calculate_velocities:
|
||||||
|
if _applied_steering:
|
||||||
|
_applied_steering = false
|
||||||
|
else:
|
||||||
|
linear_velocity = GSTUtils.to_vector3(body.linear_velocity)
|
||||||
|
angular_velocity = body.angular_velocity
|
59
project/src/Agents/GSTRigidBodyAgent.gd
Normal file
59
project/src/Agents/GSTRigidBodyAgent.gd
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# A specialized steering agent that updates itself every frame so the user does
|
||||||
|
# not have to using a RigidBody
|
||||||
|
extends GSTSpecializedAgent
|
||||||
|
class_name GSTRigidBodyAgent
|
||||||
|
|
||||||
|
|
||||||
|
# The RigidBody to keep track of
|
||||||
|
var body: RigidBody setget _set_body
|
||||||
|
|
||||||
|
var _last_position: Vector3
|
||||||
|
|
||||||
|
|
||||||
|
func _init(body: RigidBody) -> void:
|
||||||
|
self.body = body
|
||||||
|
if body.is_inside_tree():
|
||||||
|
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame")
|
||||||
|
else:
|
||||||
|
body.connect("ready", self, "_on_body_ready")
|
||||||
|
|
||||||
|
|
||||||
|
# Moves the agent's `body` by target `acceleration`.
|
||||||
|
# tags: virtual
|
||||||
|
func _apply_steering(acceleration: GSTTargetAcceleration, delta: float) -> void:
|
||||||
|
_applied_steering = true
|
||||||
|
body.apply_central_impulse(acceleration.linear)
|
||||||
|
body.apply_torque_impulse(Vector3.UP * acceleration.angular)
|
||||||
|
if calculate_velocities:
|
||||||
|
linear_velocity = body.linear_velocity
|
||||||
|
angular_velocity = body.angular_velocity.y
|
||||||
|
|
||||||
|
|
||||||
|
func _set_body(value: RigidBody) -> void:
|
||||||
|
body = value
|
||||||
|
|
||||||
|
_last_position = body.global_position
|
||||||
|
_last_orientation = body.rotation.y
|
||||||
|
|
||||||
|
position = _last_position
|
||||||
|
orientation = _last_orientation
|
||||||
|
|
||||||
|
|
||||||
|
func _on_body_ready() -> void:
|
||||||
|
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame")
|
||||||
|
_set_body(body)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_SceneTree_frame() -> void:
|
||||||
|
var current_position: Vector3 = body.global_position
|
||||||
|
var current_orientation: float = body.rotation.y
|
||||||
|
|
||||||
|
position = current_position
|
||||||
|
orientation = current_orientation
|
||||||
|
|
||||||
|
if calculate_velocities:
|
||||||
|
if _applied_steering:
|
||||||
|
_applied_steering = false
|
||||||
|
else:
|
||||||
|
linear_velocity = body.linear_velocity
|
||||||
|
angular_velocity = body.angular_velocity.y
|
@ -1,166 +0,0 @@
|
|||||||
# A specialized steering agent that updates itself every frame so the user does
|
|
||||||
# not have to.
|
|
||||||
extends GSTNodeAgent
|
|
||||||
class_name GSTSpatialAgent
|
|
||||||
|
|
||||||
|
|
||||||
# The Spatial to keep track of
|
|
||||||
var body: Spatial setget _set_body
|
|
||||||
|
|
||||||
var _last_position: Vector3
|
|
||||||
|
|
||||||
|
|
||||||
func _init(body: Spatial) -> void:
|
|
||||||
self.body = body
|
|
||||||
if body.is_inside_tree():
|
|
||||||
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame")
|
|
||||||
else:
|
|
||||||
body.connect("ready", self, "_on_body_ready")
|
|
||||||
|
|
||||||
|
|
||||||
# Moves the agent's `body` by target `acceleration`.
|
|
||||||
# tags: virtual
|
|
||||||
func _apply_steering(acceleration: GSTTargetAcceleration, delta: float) -> void:
|
|
||||||
_applied_steering = true
|
|
||||||
match _body_type:
|
|
||||||
BodyType.RIGID:
|
|
||||||
_apply_rigid_steering(acceleration)
|
|
||||||
BodyType.KINEMATIC:
|
|
||||||
match kinematic_movement_type:
|
|
||||||
MovementType.COLLIDE:
|
|
||||||
_apply_collide_steering(acceleration.linear, delta)
|
|
||||||
MovementType.SLIDE:
|
|
||||||
_apply_sliding_steering(acceleration.linear)
|
|
||||||
MovementType.POSITION:
|
|
||||||
_apply_normal_steering(acceleration.linear, delta)
|
|
||||||
BodyType.NODE:
|
|
||||||
_apply_normal_steering(acceleration.linear, delta)
|
|
||||||
if not _body_type == BodyType.RIGID:
|
|
||||||
_apply_orientation_steering(acceleration.angular, delta)
|
|
||||||
|
|
||||||
|
|
||||||
func _apply_rigid_steering(accel: GSTTargetAcceleration) -> void:
|
|
||||||
body.apply_central_impulse(GSTUtils.to_Vector3(accel.linear))
|
|
||||||
body.apply_torque_impulse(accel.angular)
|
|
||||||
if calculate_velocities:
|
|
||||||
linear_velocity = body.linear_velocity
|
|
||||||
angular_velocity = body.angular_velocity.y
|
|
||||||
|
|
||||||
|
|
||||||
func _apply_sliding_steering(accel: Vector3) -> void:
|
|
||||||
var velocity := GSTUtils.clampedv3(linear_velocity + accel, linear_speed_max)
|
|
||||||
if apply_linear_drag:
|
|
||||||
velocity = velocity.linear_interpolate(Vector3.ZERO, linear_drag_percentage)
|
|
||||||
velocity = body.move_and_slide(velocity)
|
|
||||||
if calculate_velocities:
|
|
||||||
linear_velocity = velocity
|
|
||||||
|
|
||||||
|
|
||||||
func _apply_collide_steering(accel: Vector3, delta: float) -> void:
|
|
||||||
var velocity := GSTUtils.clampedv3(linear_velocity + accel, linear_speed_max)
|
|
||||||
if apply_linear_drag:
|
|
||||||
velocity = velocity.linear_interpolate(
|
|
||||||
Vector3.ZERO,
|
|
||||||
linear_drag_percentage
|
|
||||||
)
|
|
||||||
body.move_and_collide(velocity * delta)
|
|
||||||
if calculate_velocities:
|
|
||||||
linear_velocity = velocity
|
|
||||||
|
|
||||||
|
|
||||||
func _apply_normal_steering(accel: Vector3, delta: float) -> void:
|
|
||||||
var velocity := GSTUtils.clampedv3(linear_velocity + accel, linear_speed_max)
|
|
||||||
if apply_linear_drag:
|
|
||||||
velocity = velocity.linear_interpolate(
|
|
||||||
Vector3.ZERO,
|
|
||||||
linear_drag_percentage
|
|
||||||
)
|
|
||||||
body.global_position += velocity * delta
|
|
||||||
if calculate_velocities:
|
|
||||||
linear_velocity = velocity
|
|
||||||
|
|
||||||
|
|
||||||
func _apply_orientation_steering(angular_acceleration: float, delta: float) -> void:
|
|
||||||
var velocity = angular_velocity + angular_acceleration
|
|
||||||
if apply_angular_drag:
|
|
||||||
velocity = lerp(velocity, 0, angular_drag_percentage)
|
|
||||||
body.rotation += velocity * delta
|
|
||||||
if calculate_velocities:
|
|
||||||
angular_velocity = velocity
|
|
||||||
|
|
||||||
|
|
||||||
func _set_use_physics(value: bool) -> void:
|
|
||||||
if use_physics and not value:
|
|
||||||
body.get_tree().disconnect("idle_frame", self, "_on_SceneTree_frame")
|
|
||||||
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame")
|
|
||||||
elif not use_physics and value:
|
|
||||||
body.get_tree().disconnect("physics_frame", self, "_on_SceneTree_frame")
|
|
||||||
body.get_tree().connect("idle_frame", self, "_on_SceneTree_frame")
|
|
||||||
use_physics = value
|
|
||||||
|
|
||||||
|
|
||||||
func _set_body(value: Spatial) -> void:
|
|
||||||
body = value
|
|
||||||
if body is RigidBody:
|
|
||||||
_body_type = BodyType.RIGID
|
|
||||||
elif body is KinematicBody:
|
|
||||||
_body_type = BodyType.KINEMATIC
|
|
||||||
else:
|
|
||||||
_body_type = BodyType.NODE
|
|
||||||
|
|
||||||
if _body_type == BodyType.RIGID:
|
|
||||||
linear_velocity = body.linear_velocity
|
|
||||||
angular_velocity = body.angular_velocity
|
|
||||||
else:
|
|
||||||
_last_position = body.global_position
|
|
||||||
_last_orientation = body.rotation.y
|
|
||||||
|
|
||||||
position = _last_position
|
|
||||||
orientation = _last_orientation
|
|
||||||
|
|
||||||
|
|
||||||
func _on_body_ready() -> void:
|
|
||||||
body.get_tree().connect("physics_frame", self, "_on_SceneTree_frame")
|
|
||||||
body.disconnect("ready", self, "_on_body_ready")
|
|
||||||
_set_body(body)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_SceneTree_frame() -> void:
|
|
||||||
var current_position: Vector3 = body.global_position
|
|
||||||
var current_orientation: float = body.rotation.y
|
|
||||||
|
|
||||||
position = current_position
|
|
||||||
orientation = current_orientation
|
|
||||||
|
|
||||||
if calculate_velocities:
|
|
||||||
if _applied_steering:
|
|
||||||
_applied_steering = false
|
|
||||||
else:
|
|
||||||
match _body_type:
|
|
||||||
BodyType.RIGID:
|
|
||||||
linear_velocity = GSTUtils.to_vector3(body.linear_velocity)
|
|
||||||
angular_velocity = body.angular_velocity
|
|
||||||
_:
|
|
||||||
linear_velocity = GSTUtils.clampedv3(
|
|
||||||
_last_position - current_position,
|
|
||||||
linear_speed_max
|
|
||||||
)
|
|
||||||
if apply_linear_drag:
|
|
||||||
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:
|
|
||||||
angular_velocity = lerp(
|
|
||||||
angular_velocity,
|
|
||||||
0,
|
|
||||||
angular_drag_percentage
|
|
||||||
)
|
|
||||||
|
|
||||||
_last_position = current_position
|
|
||||||
_last_orientation = current_orientation
|
|
40
project/src/Agents/GSTSpecializedAgent.gd
Normal file
40
project/src/Agents/GSTSpecializedAgent.gd
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# A base class for a specialized steering agent that updates itself every frame
|
||||||
|
# so the user does not have to. All other specialized agents derive from this.
|
||||||
|
# tags: abstract
|
||||||
|
extends GSTSteeringAgent
|
||||||
|
class_name GSTSpecializedAgent
|
||||||
|
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# If `true` and velocities and `calculate_velocities` is 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
|
||||||
|
|
||||||
|
# If `true` and velocities and `calculate_velocities` is 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
|
||||||
|
|
||||||
|
# The percentage between the current linear velocity and 0 to interpolate by if
|
||||||
|
# `calculate_velocities` and `apply_linear_drag` are true.
|
||||||
|
# Does not apply to `RigidBody` and `RigidBody2D` nodes.
|
||||||
|
var linear_drag_percentage := 0.0
|
||||||
|
|
||||||
|
# The percentage between the current angular velocity and 0 to interpolate by if
|
||||||
|
# `calculate_velocities` and `apply_angular_drag` are true.
|
||||||
|
# Does not apply to `RigidBody` and `RigidBody2D` nodes.
|
||||||
|
var angular_drag_percentage := 0.0
|
||||||
|
|
||||||
|
var _last_orientation: float
|
||||||
|
var _body_type: int
|
||||||
|
var _applied_steering := false
|
||||||
|
|
||||||
|
|
||||||
|
# Moves the agent's body by target `acceleration`.
|
||||||
|
# tags: virtual
|
||||||
|
func _apply_steering(acceleration: GSTTargetAcceleration, delta: float) -> void:
|
||||||
|
pass
|
Loading…
Reference in New Issue
Block a user