Update folder structure for FoollowPath Demo

This commit is contained in:
Răzvan C. Rădulescu 2020-01-16 13:10:55 +02:00
commit f3f40848a1
75 changed files with 637 additions and 560 deletions

View File

@ -2,10 +2,7 @@
[ext_resource path="res://assets/theme/fonts/montserrat/Montserrat-Medium.ttf" type="DynamicFontData" id=1] [ext_resource path="res://assets/theme/fonts/montserrat/Montserrat-Medium.ttf" type="DynamicFontData" id=1]
[resource] [resource]
size = 20 size = 20
use_filter = true use_filter = true
font_data = ExtResource( 1 ) font_data = ExtResource( 1 )

View File

@ -2,10 +2,7 @@
[ext_resource path="res://assets/theme/fonts/montserrat/Montserrat-Bold.ttf" type="DynamicFontData" id=1] [ext_resource path="res://assets/theme/fonts/montserrat/Montserrat-Bold.ttf" type="DynamicFontData" id=1]
[resource] [resource]
size = 20 size = 20
use_filter = true use_filter = true
font_data = ExtResource( 1 ) font_data = ExtResource( 1 )

View File

@ -2,10 +2,7 @@
[ext_resource path="res://assets/theme/fonts/source_code_pro/SourceCodePro-Medium.otf" type="DynamicFontData" id=1] [ext_resource path="res://assets/theme/fonts/source_code_pro/SourceCodePro-Medium.otf" type="DynamicFontData" id=1]
[resource] [resource]
size = 20 size = 20
use_filter = true use_filter = true
font_data = ExtResource( 1 ) font_data = ExtResource( 1 )

View File

@ -1,7 +1,5 @@
[gd_resource type="StyleBoxLine" format=2] [gd_resource type="StyleBoxLine" format=2]
[resource] [resource]
color = Color( 1, 1, 1, 0.196078 ) color = Color( 1, 1, 1, 0.196078 )
thickness = 2 thickness = 2

View File

@ -0,0 +1,71 @@
extends Node2D
onready var target := $Target
onready var arriver := $Arriver
export(float, 0, 2000, 40) var max_linear_speed := 800.0 setget set_max_linear_speed
export(float, 0, 200, 1) var max_linear_acceleration := 80.0 setget set_max_linear_acceleration
export(float, 0, 100, 0.1) var arrival_tolerance := 25.0 setget set_arrival_tolerance
export(float, 0, 500, 10) var deceleration_radius := 125.0 setget set_deceleration_radius
const COLORS := {
deceleration_radius = Color(0.9, 1, 0, 0.1),
arrival_tolerance = Color(0.5, 0.7, 0.9, 0.2)
}
func _ready() -> void:
target.position = arriver.global_position
arriver.setup(
max_linear_speed,
max_linear_acceleration,
arrival_tolerance,
deceleration_radius
)
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.is_pressed():
arriver.target.position = Vector3(event.position.x, event.position.y, 0)
target.position = event.position
update()
func _draw():
draw_circle(target.position, deceleration_radius, COLORS.deceleration_radius)
draw_circle(target.position, arrival_tolerance, COLORS.arrival_tolerance)
func set_arrival_tolerance(value: float) -> void:
if not is_inside_tree():
return
arrival_tolerance = value
arriver.arrive.arrival_tolerance = value
update()
func set_deceleration_radius(value: float) -> void:
if not is_inside_tree():
return
deceleration_radius = value
arriver.arrive.deceleration_radius = value
update()
func set_max_linear_speed(value: float) -> void:
if not is_inside_tree():
return
max_linear_speed = value
arriver.agent.max_linear_speed = value
func set_max_linear_acceleration(value: float) -> void:
if not is_inside_tree():
return
max_linear_acceleration = value
arriver.agent.max_linear_acceleration = value

View File

@ -0,0 +1,49 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://demos/Arrive/Arriver.gd" type="Script" id=1]
[ext_resource path="res://assets/theme/gdquest.theme" type="Theme" id=2]
[ext_resource path="res://demos/Arrive/ArriveDemo.gd" type="Script" id=3]
[ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=4]
[sub_resource type="CircleShape2D" id=1]
radius = 16.0
[node name="ArriveDemo" type="Node2D"]
script = ExtResource( 3 )
[node name="Arriver" type="KinematicBody2D" parent="."]
show_behind_parent = true
position = Vector2( 512, 300 )
script = ExtResource( 1 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="Arriver"]
shape = SubResource( 1 )
[node name="Sprite" type="Sprite" parent="Arriver"]
modulate = Color( 0.952941, 0.172549, 0.0431373, 1 )
texture = ExtResource( 4 )
[node name="Target" type="Node2D" parent="."]
position = Vector2( 0, 1 )
[node name="GUI" type="PanelContainer" parent="."]
anchor_right = 1.0
margin_right = 1024.0
margin_bottom = 87.0
rect_min_size = Vector2( 1024, 0 )
theme = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="MarginContainer" type="MarginContainer" parent="GUI"]
margin_right = 1024.0
margin_bottom = 87.0
[node name="Label" type="Label" parent="GUI/MarginContainer"]
margin_left = 16.0
margin_top = 16.0
margin_right = 1008.0
margin_bottom = 71.0
text = "Arrive Demo
Mouse click to make the red \"Player\" move to the yellow target"

View File

@ -0,0 +1,37 @@
extends KinematicBody2D
var agent := GSTSteeringAgent.new()
var target := GSTAgentLocation.new()
var arrive := GSTArrive.new(agent, target)
var _accel := GSTTargetAcceleration.new()
var _velocity := Vector2()
var _drag := 0.1
func _physics_process(delta: float) -> void:
_update_agent()
_accel = arrive.calculate_steering(_accel)
_velocity += Vector2(_accel.linear.x, _accel.linear.y)
_velocity = _velocity.linear_interpolate(Vector2.ZERO, _drag).clamped(agent.max_linear_speed)
_velocity = move_and_slide(_velocity)
func setup(
max_linear_speed: float,
max_linear_acceleration: float,
arrival_tolerance: float,
deceleration_radius: float
) -> void:
agent.max_linear_speed = max_linear_speed
agent.max_linear_acceleration = max_linear_acceleration
agent.position = Vector3(global_position.x, global_position.y, 0)
arrive.deceleration_radius = deceleration_radius
arrive.arrival_tolerance = arrival_tolerance
target.position = agent.position
func _update_agent() -> void:
agent.position = Vector3(global_position.x, global_position.y, 0)
agent.linear_velocity = Vector3(_velocity.x, _velocity.y, 0)

View File

@ -0,0 +1,63 @@
extends Node2D
onready var player := $Player
onready var gui := $GUI
onready var turret := $Turret
export(int, 0, 359) var max_angular_speed := 90 setget set_max_angular_speed
export(int, 0, 359) var max_angular_accel := 5 setget set_max_angular_accel
export(int, 0, 180) var align_tolerance := 5 setget set_align_tolerance
export(int, 0, 359) var deceleration_radius := 45 setget set_deceleration_radius
export(float, 0, 1000) var player_speed := 600.0 setget set_player_speed
func _ready() -> void:
player.speed = player_speed
turret.setup(
player.agent,
deg2rad(align_tolerance),
deg2rad(deceleration_radius),
deg2rad(max_angular_accel),
deg2rad(max_angular_speed)
)
func set_align_tolerance(value: int) -> void:
if not is_inside_tree():
return
align_tolerance = value
turret.face.alignment_tolerance = deg2rad(value)
func set_deceleration_radius(value: int) -> void:
if not is_inside_tree():
return
deceleration_radius = value
turret.face.deceleration_radius = deg2rad(value)
func set_max_angular_accel(value: int) -> void:
if not is_inside_tree():
return
max_angular_accel = value
turret.agent.max_angular_acceleration = deg2rad(value)
func set_max_angular_speed(value: int) -> void:
if not is_inside_tree():
return
max_angular_speed = value
turret.agent.max_angular_speed = deg2rad(value)
func set_player_speed(value: float) -> void:
if not is_inside_tree():
return
player_speed = value
player.speed = player_speed

View File

@ -1,10 +1,11 @@
[gd_scene load_steps=8 format=2] [gd_scene load_steps=9 format=2]
[ext_resource path="res://demos/face/Turret.gd" type="Script" id=1] [ext_resource path="res://demos/Face/Turret.gd" type="Script" id=1]
[ext_resource path="res://demos/face/FaceDemo.gd" type="Script" id=2] [ext_resource path="res://demos/Face/FaceDemo.gd" type="Script" id=2]
[ext_resource path="res://demos/face/Player.gd" type="Script" id=3] [ext_resource path="res://demos/Face/Player.gd" type="Script" id=3]
[ext_resource path="res://assets/sprites/large_circle.png" type="Texture" id=4] [ext_resource path="res://assets/sprites/large_circle.png" type="Texture" id=4]
[ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=5] [ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=5]
[ext_resource path="res://assets/theme/gdquest.theme" type="Theme" id=6]
[sub_resource type="CircleShape2D" id=1] [sub_resource type="CircleShape2D" id=1]
radius = 16.0 radius = 16.0
@ -30,7 +31,7 @@ modulate = Color( 0.945098, 0.215686, 0.0705882, 1 )
texture = ExtResource( 5 ) texture = ExtResource( 5 )
[node name="Turret" type="KinematicBody2D" parent="."] [node name="Turret" type="KinematicBody2D" parent="."]
position = Vector2( 512, 150 ) position = Vector2( 512, 286.288 )
script = ExtResource( 1 ) script = ExtResource( 1 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="Turret"] [node name="CollisionShape2D" type="CollisionShape2D" parent="Turret"]
@ -39,3 +40,23 @@ shape = SubResource( 2 )
[node name="Sprite" type="Sprite" parent="Turret"] [node name="Sprite" type="Sprite" parent="Turret"]
modulate = Color( 0.137255, 0.866667, 0.647059, 1 ) modulate = Color( 0.137255, 0.866667, 0.647059, 1 )
texture = ExtResource( 4 ) texture = ExtResource( 4 )
[node name="GUI" type="PanelContainer" parent="."]
margin_right = 1024.0
margin_bottom = 14.0
theme = ExtResource( 6 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="MarginContainer" type="MarginContainer" parent="GUI"]
margin_right = 1024.0
margin_bottom = 87.0
[node name="Label" type="Label" parent="GUI/MarginContainer"]
margin_left = 16.0
margin_top = 16.0
margin_right = 1008.0
margin_bottom = 71.0
text = "Face Demo
Move the player around with WASD and notice the turret orient itself"

View File

@ -0,0 +1,22 @@
extends KinematicBody2D
var speed: float
onready var agent := GSTAgentLocation.new()
func _physics_process(delta: float) -> void:
var movement := _get_movement()
move_and_slide(movement * speed)
_update_agent()
func _get_movement() -> Vector2:
return Vector2(
Input.get_action_strength("sf_right") - Input.get_action_strength("sf_left"),
Input.get_action_strength("sf_down") - Input.get_action_strength("sf_up"))
func _update_agent() -> void:
agent.position = Vector3(global_position.x, global_position.y, 0)

View File

@ -0,0 +1,46 @@
extends KinematicBody2D
var face: GSTFace
var agent := GSTSteeringAgent.new()
var _accel := GSTTargetAcceleration.new()
var _angular_drag := 0.01
var _cannon: Rect2
onready var collision_shape := $CollisionShape2D
func _ready() -> void:
var radius = collision_shape.shape.radius
_cannon = Rect2(Vector2(-5, 0), Vector2(10, -radius*2))
func _physics_process(delta: float) -> void:
_accel = face.calculate_steering(_accel)
agent.angular_velocity += _accel.angular
agent.angular_velocity = lerp(agent.angular_velocity, 0, _angular_drag)
agent.orientation += agent.angular_velocity * delta
rotation = agent.orientation
func _draw() -> void:
draw_rect(_cannon, Color.cadetblue)
func setup(
player_agent: GSTAgentLocation,
align_tolerance: float,
deceleration_radius: float,
max_angular_accel: float,
max_angular_speed: float
) -> void:
face = GSTFace.new(agent, player_agent)
face.alignment_tolerance = align_tolerance
face.deceleration_radius = deceleration_radius
agent.max_angular_acceleration = max_angular_accel
agent.max_angular_speed = max_angular_speed
agent.position = Vector3(global_position.x, global_position.y, 0)

View File

@ -4,9 +4,9 @@ extends Node2D
signal path_established(points) signal path_established(points)
var active_points: = [] var active_points := []
var drawing: = false var drawing := false
var distance_threshold: = 100.0 var distance_threshold := 100.0
func _unhandled_input(event: InputEvent) -> void: func _unhandled_input(event: InputEvent) -> void:
@ -42,11 +42,11 @@ func _draw() -> void:
func _simplify() -> void: func _simplify() -> void:
var first: Vector2 = active_points.front() var first: Vector2 = active_points.front()
var last: Vector2 = active_points.back() var last: Vector2 = active_points.back()
var key: = first var key := first
var simplified_path: = [first] var simplified_path := [first]
for i in range(1, active_points.size()): for i in range(1, active_points.size()):
var point: Vector2 = active_points[i] var point: Vector2 = active_points[i]
var distance: = point.distance_to(key) var distance := point.distance_to(key)
if distance > distance_threshold: if distance > distance_threshold:
key = point key = point
simplified_path.append(key) simplified_path.append(key)

View File

@ -1,7 +1,7 @@
extends Node2D extends Node2D
onready var drawer: = $Drawer onready var drawer := $Drawer
func _ready() -> void: func _ready() -> void:

View File

@ -1,9 +1,9 @@
[gd_scene load_steps=6 format=2] [gd_scene load_steps=6 format=2]
[ext_resource path="res://demos/follow_path/Drawer.gd" type="Script" id=1] [ext_resource path="res://demos/FollowPath/Drawer.gd" type="Script" id=1]
[ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=2] [ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=2]
[ext_resource path="res://demos/follow_path/PathFollower.gd" type="Script" id=3] [ext_resource path="res://demos/FollowPath/PathFollower.gd" type="Script" id=3]
[ext_resource path="res://demos/follow_path/FollowPathDemo.gd" type="Script" id=4] [ext_resource path="res://demos/FollowPath/FollowPathDemo.gd" type="Script" id=4]
[sub_resource type="CircleShape2D" id=1] [sub_resource type="CircleShape2D" id=1]
radius = 16.0 radius = 16.0

View File

@ -1,16 +1,16 @@
extends KinematicBody2D extends KinematicBody2D
onready var agent: = GSTSteeringAgent.new() onready var agent := GSTSteeringAgent.new()
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)
], true) ], true)
onready var follow: = GSTFollowPath.new(agent, path, 20, 0) onready var follow := GSTFollowPath.new(agent, path, 20, 0)
var _velocity: = Vector2.ZERO var _velocity := Vector2.ZERO
var _accel: = GSTTargetAcceleration.new() var _accel := GSTTargetAcceleration.new()
var _valid: = false var _valid := false
func setup() -> void: func setup() -> void:
@ -36,7 +36,7 @@ func _update_agent() -> void:
func _on_Drawer_path_established(points: Array) -> void: func _on_Drawer_path_established(points: Array) -> void:
var points3: = [] var points3 := []
for p in points: for p in points:
points3.append(Vector3(p.x, p.y, 0)) points3.append(Vector3(p.x, p.y, 0))
path.create_path(points3) path.create_path(points3)

View File

@ -0,0 +1,68 @@
extends Node2D
onready var spawner := $Spawner
export var max_linear_speed := 100.0 setget set_max_linear_speed
export var max_linear_accel := 25.0 setget set_max_linear_accel
export var proximity_radius := 140.0 setget set_proximity_radius
export var show_proximity_radius := true setget set_show_proximity_radius
export var separation_decay_coefficient := 2000.0 setget set_separation_decay_coef
export var cohesion_strength := 0.3 setget set_cohesion_strength
export var separation_strength := 1.5 setget set_separation_strength
func set_max_linear_speed(value: float) -> void:
if not is_inside_tree():
return
max_linear_speed = value
spawner.set_max_linear_speed(value)
func set_max_linear_accel(value: float) -> void:
if not is_inside_tree():
return
max_linear_accel = value
spawner.set_max_linear_accel(value)
func set_proximity_radius(value: float) -> void:
if not is_inside_tree():
return
proximity_radius = value
spawner.set_proximity_radius(value)
func set_show_proximity_radius(value: bool) -> void:
if not is_inside_tree():
return
show_proximity_radius = value
spawner.set_show_proximity_radius(value)
func set_separation_decay_coef(value: float) -> void:
if not is_inside_tree():
return
separation_decay_coefficient = value
spawner.set_separation_decay_coef(value)
func set_cohesion_strength(value: float) -> void:
if not is_inside_tree():
return
cohesion_strength = value
spawner.set_cohesion_strength(value)
func set_separation_strength(value: float) -> void:
if not is_inside_tree():
return
separation_strength = value
spawner.set_separation_strength(value)

View File

@ -0,0 +1,13 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://demos/GroupBehaviors/Member.tscn" type="PackedScene" id=1]
[ext_resource path="res://demos/GroupBehaviors/Spawner.gd" type="Script" id=2]
[ext_resource path="res://demos/GroupBehaviors/GroupBehaviorsDemo.gd" type="Script" id=3]
[node name="GroupBehaviorsDemo" type="Node2D"]
script = ExtResource( 3 )
[node name="Spawner" type="Node2D" parent="."]
position = Vector2( 512, 300 )
script = ExtResource( 2 )
member = ExtResource( 1 )

View File

@ -1,16 +1,16 @@
extends KinematicBody2D extends KinematicBody2D
var agent: = GSTSteeringAgent.new() var agent := GSTSteeringAgent.new()
var separation: GSTSeparation var separation: GSTSeparation
var cohesion: GSTCohesion var cohesion: GSTCohesion
var proximity: GSTRadiusProximity var proximity: GSTRadiusProximity
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
var _color: = Color.red var _color := Color.red
var _velocity: = Vector2() var _velocity := Vector2()
func setup( func setup(
@ -53,6 +53,6 @@ func set_neighbors(neighbor: Array) -> void:
func update_agent() -> void: func update_agent() -> void:
var current_position: = global_position var current_position := global_position
agent.position.x = current_position.x agent.position.x = current_position.x
agent.position.y = current_position.y agent.position.y = current_position.y

View File

@ -1,8 +1,9 @@
[gd_scene load_steps=4 format=2] [gd_scene load_steps=4 format=2]
[ext_resource path="res://demos/group_behaviors/Member.gd" type="Script" id=1] [ext_resource path="res://demos/GroupBehaviors/Member.gd" type="Script" id=1]
[ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=2] [ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=2]
[sub_resource type="CircleShape2D" id=1] [sub_resource type="CircleShape2D" id=1]
radius = 16.0 radius = 16.0

View File

@ -5,9 +5,9 @@ export var member: PackedScene
func _ready() -> void: func _ready() -> void:
var followers: = [] var followers := []
for i in range(19): for i in range(19):
var follower: = member.instance() var follower := member.instance()
add_child(follower) add_child(follower)
follower.position += Vector2(rand_range(-60, 60), rand_range(-60, 60)) follower.position += Vector2(rand_range(-60, 60), rand_range(-60, 60))
followers.append(follower) followers.append(follower)
@ -22,7 +22,7 @@ func _ready() -> void:
if i == 0 and owner.show_proximity_radius: if i == 0 and owner.show_proximity_radius:
follower.draw_proximity = true follower.draw_proximity = true
follower.update() follower.update()
var agents: = [] var agents := []
for i in followers: for i in followers:
agents.append(i.agent) agents.append(i.agent)
for i in followers: for i in followers:

View File

@ -2,10 +2,10 @@ extends Node2D
# Wraps the ships' positions around the world border, and controls their rendering clones. # Wraps the ships' positions around the world border, and controls their rendering clones.
onready var ShipType: = preload("res://demos/pursue_vs_seek/Ship.gd") onready var ShipType := preload("res://demos/PursueSeek/Ship.gd")
onready var ships: = [$Player, $Pursuer, $Seeker] onready var ships := [$Player, $Pursuer, $Seeker]
var _clones: = {} var _clones := {}
var _world_bounds: Vector2 var _world_bounds: Vector2
@ -17,10 +17,10 @@ func _ready() -> void:
for i in range(ships.size()): for i in range(ships.size()):
var ship: Node2D = ships[i] var ship: Node2D = ships[i]
var world_pos: = ship.position var world_pos := ship.position
for i in range(3): for i in range(3):
var ship_clone: = ShipType.new() var ship_clone := ShipType.new()
ship_clone.position.x = world_pos.x if i == 1 else (world_pos.x - _world_bounds.x) ship_clone.position.x = world_pos.x if i == 1 else (world_pos.x - _world_bounds.x)
ship_clone.position.y = world_pos.y if i == 0 else (world_pos.y - _world_bounds.y) ship_clone.position.y = world_pos.y if i == 0 else (world_pos.y - _world_bounds.y)

View File

@ -1,22 +1,22 @@
extends "res://demos/pursue_vs_seek/Ship.gd" extends "res://demos/PursueSeek/Ship.gd"
# Controls the player ship's movements based on player input. # Controls the player ship's movements based on player input.
onready var agent: = GSTSteeringAgent.new() onready var agent := GSTSteeringAgent.new()
export var thruster_strength: = 250.0 export var thruster_strength := 250.0
export var side_thruster_strength: = 10.0 export var side_thruster_strength := 10.0
export var max_velocity: = 300.0 export var max_velocity := 300.0
export var max_angular_velocity: = 2.0 export var max_angular_velocity := 2.0
export var angular_drag: = 0.025 export var angular_drag := 0.025
export var linear_drag: = 0.025 export var linear_drag := 0.025
var _linear_velocity: = Vector2() var _linear_velocity := Vector2()
var _angular_velocity: = 0.0 var _angular_velocity := 0.0
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
var movement: = _get_movement() var movement := _get_movement()
_angular_velocity = _calculate_angular_velocity( _angular_velocity = _calculate_angular_velocity(
movement.x, movement.x,
_angular_velocity, _angular_velocity,
@ -50,7 +50,7 @@ func _calculate_angular_velocity(
ship_drag: float, ship_drag: float,
delta: float) -> float: delta: float) -> float:
var velocity: = clamp( var velocity := clamp(
current_velocity + thruster_strength * horizontal_movement * delta, current_velocity + thruster_strength * horizontal_movement * delta,
-max_velocity, -max_velocity,
max_velocity max_velocity
@ -70,13 +70,13 @@ func _calculate_linear_velocity(
max_speed: float, max_speed: float,
delta: float) -> Vector2: delta: float) -> Vector2:
var actual_strength: = 0.0 var actual_strength := 0.0
if vertical_movement > 0: if vertical_movement > 0:
actual_strength = strength actual_strength = strength
elif vertical_movement < 0: elif vertical_movement < 0:
actual_strength = -strength/1.5 actual_strength = -strength/1.5
var velocity: = current_velocity + facing_direction * actual_strength * delta var velocity := current_velocity + facing_direction * actual_strength * delta
velocity = velocity.linear_interpolate(Vector2.ZERO, ship_drag_coefficient) velocity = velocity.linear_interpolate(Vector2.ZERO, ship_drag_coefficient)
return velocity.clamped(max_speed) return velocity.clamped(max_speed)

View File

@ -0,0 +1,35 @@
extends Node2D
onready var pursuer := $BoundaryManager/Pursuer
onready var seeker := $BoundaryManager/Seeker
export(float, 0, 2000, 40) var max_linear_speed := 200.0 setget set_max_linear_speed
export(float, 0, 200, 1) var max_linear_accel := 10.0 setget set_max_linear_accel
export(float, 0, 5, 0.1) var predict_time := 2.0 setget set_predict_time
func set_max_linear_speed(value: float) -> void:
if not is_inside_tree():
return
max_linear_speed = value
pursuer.agent.max_linear_speed = value
seeker.agent.max_linear_speed = value
func set_max_linear_accel(value: float) -> void:
if not is_inside_tree():
return
max_linear_accel = value
pursuer.agent.max_linear_acceleration = value
seeker.agent.max_linear_acceleration = value
func set_predict_time(value: float) -> void:
if not is_inside_tree():
return
predict_time = value
pursuer._behavior.max_predict_time = value

View File

@ -1,9 +1,9 @@
[gd_scene load_steps=6 format=2] [gd_scene load_steps=6 format=2]
[ext_resource path="res://demos/pursue_vs_seek/Pursuer.gd" type="Script" id=1] [ext_resource path="res://demos/PursueSeek/Pursuer.gd" type="Script" id=1]
[ext_resource path="res://demos/pursue_vs_seek/Player.gd" type="Script" id=2] [ext_resource path="res://demos/PursueSeek/Player.gd" type="Script" id=2]
[ext_resource path="res://demos/pursue_vs_seek/BoundaryManager.gd" type="Script" id=3] [ext_resource path="res://demos/PursueSeek/BoundaryManager.gd" type="Script" id=3]
[ext_resource path="res://demos/pursue_vs_seek/PursueVSSeekDemo.gd" type="Script" id=4] [ext_resource path="res://demos/PursueSeek/PursueVSSeekDemo.gd" type="Script" id=4]
[ext_resource path="res://assets/sprites/triangle.png" type="Texture" id=6] [ext_resource path="res://assets/sprites/triangle.png" type="Texture" id=6]
[node name="PursueVSSeekDemo" type="Node2D"] [node name="PursueVSSeekDemo" type="Node2D"]

View File

@ -1,9 +1,9 @@
extends "res://demos/pursue_vs_seek/Ship.gd" extends "res://demos/PursueSeek/Ship.gd"
# Represents a ship that chases after the player. # Represents a ship that chases after the player.
onready var agent: = GSTSteeringAgent.new() onready var agent := GSTSteeringAgent.new()
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
export var use_seek: bool = false export var use_seek: bool = false
@ -11,10 +11,10 @@ export var use_seek: bool = false
var _orient_behavior: GSTSteeringBehavior var _orient_behavior: GSTSteeringBehavior
var _behavior: GSTSteeringBehavior var _behavior: GSTSteeringBehavior
var _linear_velocity: = Vector2() var _linear_velocity := Vector2()
var _linear_drag_coefficient: = 0.025 var _linear_drag_coefficient := 0.025
var _angular_velocity: = 0.0 var _angular_velocity := 0.0
var _angular_drag: = 1.0 var _angular_drag := 1.0
func _ready() -> void: func _ready() -> void:

View File

@ -6,7 +6,7 @@ var rect: Rect2
func _ready() -> void: func _ready() -> void:
var extents: = ($CollisionShape2D.shape as RectangleShape2D).extents var extents := ($CollisionShape2D.shape as RectangleShape2D).extents
rect = Rect2(-extents, extents*2) rect = Rect2(-extents, extents*2)

View File

@ -2,9 +2,9 @@ extends KinematicBody2D
# Class to control the player in basic left/right up/down movement. # Class to control the player in basic left/right up/down movement.
onready var agent: = GSTAgentLocation.new() onready var agent := GSTAgentLocation.new()
export var speed: = 200.0 export var speed := 200.0
func _get_movement() -> Vector2: func _get_movement() -> Vector2:
@ -13,7 +13,7 @@ func _get_movement() -> Vector2:
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
var movement: = _get_movement() var movement := _get_movement()
if movement.length_squared() < 0.01: if movement.length_squared() < 0.01:
return return

View File

@ -4,17 +4,17 @@ extends Node2D
enum Mode { FLEE, SEEK } enum Mode { FLEE, SEEK }
export(Mode) var behavior_mode: = Mode.SEEK setget set_behavior_mode export(Mode) var behavior_mode := Mode.SEEK setget set_behavior_mode
export(float, 0, 2000, 40) var max_linear_speed: = 200.0 setget set_max_linear_speed export(float, 0, 2000, 40) var max_linear_speed := 200.0 setget set_max_linear_speed
export(float, 0, 500, 0.5) var max_linear_accel: = 10.0 setget set_max_linear_accel export(float, 0, 500, 0.5) var max_linear_accel := 10.0 setget set_max_linear_accel
var camera_boundaries: Rect2
onready var player: KinematicBody2D = $Player onready var player: KinematicBody2D = $Player
onready var spawner: Node2D = $Spawner onready var spawner: Node2D = $Spawner
var camera_boundaries: Rect2
func _ready() -> void:
func _init() -> void:
camera_boundaries = Rect2( camera_boundaries = Rect2(
Vector2.ZERO, Vector2.ZERO,
Vector2( Vector2(
@ -22,14 +22,12 @@ func _init() -> void:
ProjectSettings["display/window/size/height"] ProjectSettings["display/window/size/height"]
) )
) )
var rng := RandomNumberGenerator.new()
func _ready() -> void:
var rng: = RandomNumberGenerator.new()
rng.randomize() rng.randomize()
for i in range(spawner.entity_count): for i in range(spawner.entity_count):
var new_pos: = Vector2( var new_pos := Vector2(
rng.randf_range(-camera_boundaries.size.x/2, camera_boundaries.size.x/2), rng.randf_range(-camera_boundaries.size.x/2, camera_boundaries.size.x/2),
rng.randf_range(-camera_boundaries.size.y/2, camera_boundaries.size.y/2) rng.randf_range(-camera_boundaries.size.y/2, camera_boundaries.size.y/2)
) )
@ -42,29 +40,32 @@ func _ready() -> void:
func set_behavior_mode(mode: int) -> void: func set_behavior_mode(mode: int) -> void:
behavior_mode = mode if not is_inside_tree():
return
if spawner: behavior_mode = mode
match mode: match mode:
Mode.SEEK: Mode.SEEK:
for child in spawner.get_children(): for child in spawner.get_children():
child.use_seek = true child.use_seek = true
Mode.FLEE: Mode.FLEE:
for child in spawner.get_children(): for child in spawner.get_children():
child.use_seek = false child.use_seek = false
func set_max_linear_speed(value: float) -> void: func set_max_linear_speed(value: float) -> void:
max_linear_speed = value if not is_inside_tree():
return
if spawner: max_linear_speed = value
for child in spawner.get_children(): for child in spawner.get_children():
child.agent.max_linear_speed = value child.agent.max_linear_speed = value
func set_max_linear_accel(value: float) -> void: func set_max_linear_accel(value: float) -> void:
max_linear_accel = value if not is_inside_tree():
return
if spawner: max_linear_accel = value
for child in spawner.get_children(): for child in spawner.get_children():
child.agent.max_linear_acceleration = value child.agent.max_linear_acceleration = value

View File

@ -1,10 +1,10 @@
[gd_scene load_steps=10 format=2] [gd_scene load_steps=10 format=2]
[ext_resource path="res://demos/seek_and_flee/Boundary.gd" type="Script" id=1] [ext_resource path="res://demos/SeekFlee/Boundary.gd" type="Script" id=1]
[ext_resource path="res://demos/seek_and_flee/Player.gd" type="Script" id=2] [ext_resource path="res://demos/SeekFlee/Player.gd" type="Script" id=2]
[ext_resource path="res://demos/seek_and_flee/SeekFleeDemo.gd" type="Script" id=3] [ext_resource path="res://demos/SeekFlee/SeekFleeDemo.gd" type="Script" id=3]
[ext_resource path="res://demos/seek_and_flee/Spawner.gd" type="Script" id=4] [ext_resource path="res://demos/SeekFlee/Spawner.gd" type="Script" id=4]
[ext_resource path="res://demos/seek_and_flee/Seeker.tscn" type="PackedScene" id=6] [ext_resource path="res://demos/SeekFlee/Seeker.tscn" type="PackedScene" id=6]
[ext_resource path="res://assets/sprites/large_circle.png" type="Texture" id=7] [ext_resource path="res://assets/sprites/large_circle.png" type="Texture" id=7]
[sub_resource type="CircleShape2D" id=1] [sub_resource type="CircleShape2D" id=1]

View File

@ -2,16 +2,16 @@ extends KinematicBody2D
# AI agent that uses the Seek behavior to hone in on the player's location as directly as possible. # AI agent that uses the Seek behavior to hone in on the player's location as directly as possible.
onready var agent: = GSTSteeringAgent.new() onready var agent := GSTSteeringAgent.new()
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)
var player_agent: GSTAgentLocation var player_agent: GSTAgentLocation
var velocity: = Vector2.ZERO var velocity := Vector2.ZERO
var start_speed: float var start_speed: float
var start_accel: float var start_accel: float
var use_seek: = true var use_seek := true
func _ready() -> void: func _ready() -> void:

View File

@ -1,8 +1,9 @@
[gd_scene load_steps=4 format=2] [gd_scene load_steps=4 format=2]
[ext_resource path="res://demos/seek_and_flee/Seeker.gd" type="Script" id=1] [ext_resource path="res://demos/SeekFlee/Seeker.gd" type="Script" id=1]
[ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=2] [ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=2]
[sub_resource type="CircleShape2D" id=1] [sub_resource type="CircleShape2D" id=1]
radius = 16.0 radius = 16.0

View File

@ -3,5 +3,5 @@ extends Node2D
export(PackedScene) var Entity: PackedScene export(PackedScene) var Entity: PackedScene
export var entity_count: = 10 export var entity_count:= 10
export var entity_color: = Color.blue export var entity_color:= Color.blue

View File

@ -1,39 +0,0 @@
extends Node2D
onready var target: = $Target
onready var arriver: = $Arriver
onready var gui: = $GUI
export(float, 0, 2000, 40) var max_linear_speed: = 200.0 setget set_max_linear_speed
export(float, 0, 200, 1) var max_linear_accel: = 25.0 setget set_max_linear_accel
export(float, 0, 100, 0.1) var arrival_tolerance: = 20.0 setget set_arrival_tolerance
export(float, 0, 500, 10) var deceleration_radius: = 200.0 setget set_deceleration_radius
func _ready() -> void:
target.position = arriver.global_position
func set_arrival_tolerance(value: float) -> void:
arrival_tolerance = value
if arriver:
arriver.arrive.arrival_tolerance = value
func set_deceleration_radius(value: float) -> void:
deceleration_radius = value
if arriver:
arriver.arrive.deceleration_radius = value
func set_max_linear_speed(value: float) -> void:
max_linear_speed = value
if arriver:
arriver.agent.max_linear_speed = value
func set_max_linear_accel(value: float) -> void:
max_linear_accel = value
if arriver:
arriver.agent.max_linear_acceleration = value

View File

@ -1,35 +0,0 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://demos/arrive/Arriver.gd" type="Script" id=1]
[ext_resource path="res://demos/arrive/ArriveDemo.gd" type="Script" id=2]
[ext_resource path="res://assets/sprites/large_circle.png" type="Texture" id=3]
[ext_resource path="res://assets/sprites/small_circle.png" type="Texture" id=4]
[sub_resource type="CircleShape2D" id=1]
radius = 16.0
[node name="ArriveDemo" type="Node2D"]
script = ExtResource( 2 )
max_linear_speed = 400.0
max_linear_accel = 50.0
arrival_tolerance = 10.0
deceleration_radius = 80.0
[node name="Arriver" type="KinematicBody2D" parent="."]
position = Vector2( 512, 300 )
script = ExtResource( 1 )
[node name="CollisionShape2D" type="CollisionShape2D" parent="Arriver"]
shape = SubResource( 1 )
[node name="Sprite" type="Sprite" parent="Arriver"]
modulate = Color( 0.952941, 0.172549, 0.0431373, 1 )
texture = ExtResource( 4 )
[node name="Target" type="Sprite" parent="."]
modulate = Color( 0.827451, 1, 0, 0.501961 )
texture = ExtResource( 3 )
[node name="Sprite" type="Sprite" parent="Target"]
scale = Vector2( 0.5, 0.5 )
texture = ExtResource( 4 )

View File

@ -1,40 +0,0 @@
extends KinematicBody2D
onready var agent: = GSTSteeringAgent.new()
onready var target: = GSTAgentLocation.new()
onready var arrive: = GSTArrive.new(agent, target)
var _accel: = GSTTargetAcceleration.new()
var _velocity: = Vector2()
var _drag: = 0.1
func _ready() -> void:
agent.max_linear_speed = owner.max_linear_speed
agent.max_linear_acceleration = owner.max_linear_accel
agent.position = Vector3(global_position.x, global_position.y, 0)
arrive.deceleration_radius = owner.deceleration_radius
arrive.arrival_tolerance = owner.arrival_tolerance
target.position = agent.position
func _unhandled_input(event: InputEvent) -> void:
if event is InputEventMouseButton:
var mb: InputEventMouseButton = event
if mb.button_index == BUTTON_LEFT and mb.pressed:
target.position = Vector3(mb.position.x, mb.position.y, 0)
owner.target.position = mb.position
func _physics_process(delta: float) -> void:
_update_agent()
_accel = arrive.calculate_steering(_accel)
_velocity += Vector2(_accel.linear.x, _accel.linear.y)
_velocity = _velocity.linear_interpolate(Vector2.ZERO, _drag).clamped(agent.max_linear_speed)
_velocity = move_and_slide(_velocity)
func _update_agent() -> void:
agent.position = Vector3(global_position.x, global_position.y, 0)
agent.linear_velocity = Vector3(_velocity.x, _velocity.y, 0)

View File

@ -1,44 +0,0 @@
extends Node2D
onready var player: = $Player
onready var gui: = $GUI
onready var turret: = $Turret
export(int, 0, 359, 1) var max_angular_speed: = 90 setget set_max_angular_speed
export(int, 0, 359, 1) var max_angular_accel: = 5 setget set_max_angular_accel
export(int, 0, 180, 1) var align_tolerance: = 5 setget set_align_tolerance
export(int, 0, 359, 1) var deceleration_radius: = 45 setget set_deceleration_radius
func _ready() -> void:
turret.setup(
deg2rad(align_tolerance),
deg2rad(deceleration_radius),
deg2rad(max_angular_accel),
deg2rad(max_angular_speed)
)
func set_align_tolerance(value: int) -> void:
align_tolerance = value
if turret:
turret._face.alignment_tolerance = deg2rad(value)
func set_deceleration_radius(value: int) -> void:
deceleration_radius = value
if turret:
turret._face.deceleration_radius = deg2rad(value)
func set_max_angular_accel(value: int) -> void:
max_angular_accel = value
if turret:
turret._agent.max_angular_acceleration = deg2rad(value)
func set_max_angular_speed(value: int) -> void:
max_angular_speed = value
if turret:
turret._agent.max_angular_speed = deg2rad(value)

View File

@ -1,21 +0,0 @@
extends KinematicBody2D
onready var agent: = GSTAgentLocation.new()
export var speed: = 125.0
func _physics_process(delta: float) -> void:
var movement: = _get_movement()
move_and_slide(movement * speed)
_update_agent()
func _get_movement() -> Vector2:
return Vector2( Input.get_action_strength("sf_right") - Input.get_action_strength("sf_left"),
Input.get_action_strength("sf_down") - Input.get_action_strength("sf_up"))
func _update_agent() -> void:
agent.position = Vector3(global_position.x, global_position.y, 0)

View File

@ -1,59 +0,0 @@
extends KinematicBody2D
onready var collision_shape: = $CollisionShape2D
var _cannon: Rect2
var _agent: = GSTSteeringAgent.new()
var _accel: = GSTTargetAcceleration.new()
var _angular_velocity: = 0.0
var _angular_drag: = 0.01
var _face: GSTFace
func _ready() -> void:
var radius = collision_shape.shape.radius
_cannon = Rect2(Vector2(-5, 0), Vector2(10, -radius*2))
func _draw() -> void:
draw_rect(_cannon, Color.blue)
func _physics_process(delta: float) -> void:
if not _face:
return
_accel = _face.calculate_steering(_accel)
_angular_velocity += _accel.angular
_angular_velocity = lerp(_angular_velocity, 0, _angular_drag)
rotation += _angular_velocity * delta
_update_agent()
func setup(
align_tolerance: float,
deceleration_radius: float,
max_angular_accel: float,
max_angular_speed: float
) -> void:
_face = GSTFace.new(_agent, owner.player.agent)
_face.alignment_tolerance = align_tolerance
_face.deceleration_radius = deceleration_radius
_agent.max_angular_acceleration = max_angular_accel
_agent.max_angular_speed = max_angular_speed
_agent.position = Vector3(global_position.x, global_position.y, 0)
_update_agent()
func _update_agent() -> void:
_agent.angular_velocity = _angular_velocity
_agent.orientation = rotation

View File

@ -1,58 +0,0 @@
extends Node2D
onready var spawner: = $Spawner
export var max_linear_speed: = 100.0 setget set_max_linear_speed
export var max_linear_accel: = 25.0 setget set_max_linear_accel
export var proximity_radius: = 140.0 setget set_proximity_radius
export var show_proximity_radius: = true setget set_show_proximity_radius
export var separation_decay_coefficient: = 2000.0 setget set_separation_decay_coef
export var cohesion_strength: = 0.3 setget set_cohesion_strength
export var separation_strength: = 1.5 setget set_separation_strength
func _ready() -> void:
pass
func set_max_linear_speed(value: float) -> void:
max_linear_speed = value
if spawner:
spawner.set_max_linear_speed(value)
func set_max_linear_accel(value: float) -> void:
max_linear_accel = value
if spawner:
spawner.set_max_linear_accel(value)
func set_proximity_radius(value: float) -> void:
proximity_radius = value
if spawner:
spawner.set_proximity_radius(value)
func set_show_proximity_radius(value: bool) -> void:
show_proximity_radius = value
if spawner:
spawner.set_show_proximity_radius(value)
func set_separation_decay_coef(value: float) -> void:
separation_decay_coefficient = value
if spawner:
spawner.set_separation_decay_coef(value)
func set_cohesion_strength(value: float) -> void:
cohesion_strength = value
if spawner:
spawner.set_cohesion_strength(value)
func set_separation_strength(value: float) -> void:
separation_strength = value
if spawner:
spawner.set_separation_strength(value)

View File

@ -1,13 +0,0 @@
[gd_scene load_steps=4 format=2]
[ext_resource path="res://demos/group_behaviors/Member.tscn" type="PackedScene" id=1]
[ext_resource path="res://demos/group_behaviors/Spawner.gd" type="Script" id=2]
[ext_resource path="res://demos/group_behaviors/GroupBehaviorsDemo.gd" type="Script" id=3]
[node name="GroupBehaviorsDemo" type="Node2D"]
script = ExtResource( 3 )
[node name="Spawner" type="Node2D" parent="."]
position = Vector2( 512, 300 )
script = ExtResource( 2 )
member = ExtResource( 1 )

View File

@ -1,31 +0,0 @@
extends Node2D
onready var pursuer: = $BoundaryManager/Pursuer
onready var seeker: = $BoundaryManager/Seeker
export(float, 0, 2000, 40) var max_linear_speed: = 200.0 setget set_max_linear_speed
export(float, 0, 200, 1) var max_linear_accel: = 10.0 setget set_max_linear_accel
export(float, 0, 5, 0.1) var predict_time: = 2.0 setget set_predict_time
func set_max_linear_speed(value: float) -> void:
max_linear_speed = value
if pursuer:
pursuer.agent.max_linear_speed = value
if seeker:
seeker.agent.max_linear_speed = value
func set_max_linear_accel(value: float) -> void:
max_linear_accel = value
if pursuer:
pursuer.agent.max_linear_acceleration = value
if seeker:
seeker.agent.max_linear_acceleration = value
func set_predict_time(value: float) -> void:
predict_time = value
if pursuer:
pursuer._behavior.max_predict_time = value

View File

@ -17,42 +17,42 @@ _global_script_classes=[ {
"base": "GSTSteeringBehavior", "base": "GSTSteeringBehavior",
"class": "GSTArrive", "class": "GSTArrive",
"language": "GDScript", "language": "GDScript",
"path": "res://src/behaviors/GSTArrive.gd" "path": "res://src/Behaviors/GSTArrive.gd"
}, { }, {
"base": "GSTGroupBehavior", "base": "GSTGroupBehavior",
"class": "GSTAvoidCollisions", "class": "GSTAvoidCollisions",
"language": "GDScript", "language": "GDScript",
"path": "res://src/behaviors/GSTAvoidCollisions.gd" "path": "res://src/Behaviors/GSTAvoidCollisions.gd"
}, { }, {
"base": "GSTSteeringBehavior", "base": "GSTSteeringBehavior",
"class": "GSTBlend", "class": "GSTBlend",
"language": "GDScript", "language": "GDScript",
"path": "res://src/behaviors/GSTBlend.gd" "path": "res://src/Behaviors/GSTBlend.gd"
}, { }, {
"base": "GSTGroupBehavior", "base": "GSTGroupBehavior",
"class": "GSTCohesion", "class": "GSTCohesion",
"language": "GDScript", "language": "GDScript",
"path": "res://src/behaviors/GSTCohesion.gd" "path": "res://src/Behaviors/GSTCohesion.gd"
}, { }, {
"base": "GSTPursue", "base": "GSTPursue",
"class": "GSTEvade", "class": "GSTEvade",
"language": "GDScript", "language": "GDScript",
"path": "res://src/behaviors/GSTEvade.gd" "path": "res://src/Behaviors/GSTEvade.gd"
}, { }, {
"base": "GSTMatchOrientation", "base": "GSTMatchOrientation",
"class": "GSTFace", "class": "GSTFace",
"language": "GDScript", "language": "GDScript",
"path": "res://src/behaviors/GSTFace.gd" "path": "res://src/Behaviors/GSTFace.gd"
}, { }, {
"base": "GSTSeek", "base": "GSTSeek",
"class": "GSTFlee", "class": "GSTFlee",
"language": "GDScript", "language": "GDScript",
"path": "res://src/behaviors/GSTFlee.gd" "path": "res://src/Behaviors/GSTFlee.gd"
}, { }, {
"base": "GSTArrive", "base": "GSTArrive",
"class": "GSTFollowPath", "class": "GSTFollowPath",
"language": "GDScript", "language": "GDScript",
"path": "res://src/behaviors/GSTFollowPath.gd" "path": "res://src/Behaviors/GSTFollowPath.gd"
}, { }, {
"base": "GSTSteeringBehavior", "base": "GSTSteeringBehavior",
"class": "GSTGroupBehavior", "class": "GSTGroupBehavior",
@ -62,17 +62,17 @@ _global_script_classes=[ {
"base": "GSTProximity", "base": "GSTProximity",
"class": "GSTInfiniteProximity", "class": "GSTInfiniteProximity",
"language": "GDScript", "language": "GDScript",
"path": "res://src/proximities/GSTInfiniteProximity.gd" "path": "res://src/Proximities/GSTInfiniteProximity.gd"
}, { }, {
"base": "GSTMatchOrientation", "base": "GSTMatchOrientation",
"class": "GSTLookWhereYouGo", "class": "GSTLookWhereYouGo",
"language": "GDScript", "language": "GDScript",
"path": "res://src/behaviors/GSTLookWhereYouGo.gd" "path": "res://src/Behaviors/GSTLookWhereYouGo.gd"
}, { }, {
"base": "GSTSteeringBehavior", "base": "GSTSteeringBehavior",
"class": "GSTMatchOrientation", "class": "GSTMatchOrientation",
"language": "GDScript", "language": "GDScript",
"path": "res://src/behaviors/GSTMatchOrientation.gd" "path": "res://src/Behaviors/GSTMatchOrientation.gd"
}, { }, {
"base": "Reference", "base": "Reference",
"class": "GSTPath", "class": "GSTPath",
@ -82,32 +82,32 @@ _global_script_classes=[ {
"base": "GSTSteeringBehavior", "base": "GSTSteeringBehavior",
"class": "GSTPriority", "class": "GSTPriority",
"language": "GDScript", "language": "GDScript",
"path": "res://src/behaviors/GSTPriority.gd" "path": "res://src/Behaviors/GSTPriority.gd"
}, { }, {
"base": "Reference", "base": "Reference",
"class": "GSTProximity", "class": "GSTProximity",
"language": "GDScript", "language": "GDScript",
"path": "res://src/proximities/GSTProximity.gd" "path": "res://src/Proximities/GSTProximity.gd"
}, { }, {
"base": "GSTSteeringBehavior", "base": "GSTSteeringBehavior",
"class": "GSTPursue", "class": "GSTPursue",
"language": "GDScript", "language": "GDScript",
"path": "res://src/behaviors/GSTPursue.gd" "path": "res://src/Behaviors/GSTPursue.gd"
}, { }, {
"base": "GSTProximity", "base": "GSTProximity",
"class": "GSTRadiusProximity", "class": "GSTRadiusProximity",
"language": "GDScript", "language": "GDScript",
"path": "res://src/proximities/GSTRadiusProximity.gd" "path": "res://src/Proximities/GSTRadiusProximity.gd"
}, { }, {
"base": "GSTSteeringBehavior", "base": "GSTSteeringBehavior",
"class": "GSTSeek", "class": "GSTSeek",
"language": "GDScript", "language": "GDScript",
"path": "res://src/behaviors/GSTSeek.gd" "path": "res://src/Behaviors/GSTSeek.gd"
}, { }, {
"base": "GSTGroupBehavior", "base": "GSTGroupBehavior",
"class": "GSTSeparation", "class": "GSTSeparation",
"language": "GDScript", "language": "GDScript",
"path": "res://src/behaviors/GSTSeparation.gd" "path": "res://src/Behaviors/GSTSeparation.gd"
}, { }, {
"base": "GSTAgentLocation", "base": "GSTAgentLocation",
"class": "GSTSteeringAgent", "class": "GSTSteeringAgent",

View File

@ -7,7 +7,7 @@ class_name GSTArrive
var target: GSTAgentLocation var target: GSTAgentLocation
var arrival_tolerance: float var arrival_tolerance: float
var deceleration_radius: float var deceleration_radius: float
var time_to_reach: = 0.1 var time_to_reach := 0.1
func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void: func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void:
@ -15,18 +15,18 @@ func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void:
func _arrive(acceleration: GSTTargetAcceleration, target_position: Vector3) -> GSTTargetAcceleration: func _arrive(acceleration: GSTTargetAcceleration, target_position: Vector3) -> GSTTargetAcceleration:
var to_target: = target_position - agent.position var to_target := target_position - agent.position
var distance: = to_target.length() var distance := to_target.length()
if distance <= arrival_tolerance: if distance <= arrival_tolerance:
acceleration.set_zero() acceleration.set_zero()
else: else:
var desired_speed: = agent.max_linear_speed var desired_speed := agent.max_linear_speed
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 := 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

@ -21,7 +21,7 @@ func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAccele
first_minimum_separation = 0 first_minimum_separation = 0
first_distance = 0 first_distance = 0
var neighbor_count: = proximity.find_neighbors(_callback) var neighbor_count := 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()
@ -39,9 +39,9 @@ func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAccele
func report_neighbor(neighbor: GSTSteeringAgent) -> bool: func report_neighbor(neighbor: GSTSteeringAgent) -> bool:
var relative_position: = neighbor.position - agent.position var relative_position := neighbor.position - agent.position
var relative_velocity: = neighbor.linear_velocity - agent.linear_velocity var relative_velocity := neighbor.linear_velocity - agent.linear_velocity
var relative_speed_squared: = relative_velocity.length_squared() var relative_speed_squared := relative_velocity.length_squared()
if relative_speed_squared == 0: if relative_speed_squared == 0:
return false return false

View File

@ -9,8 +9,8 @@ class_name GSTBlend
# `GSTSteeringBehavior` and a `weight` key with a value of type float. # `GSTSteeringBehavior` and a `weight` key with a value of type float.
var _behaviors: = [] var _behaviors := []
var _accel: = GSTTargetAcceleration.new() var _accel := GSTTargetAcceleration.new()
func _init(agent: GSTSteeringAgent).(agent) -> void: func _init(agent: GSTSteeringAgent).(agent) -> void:

View File

@ -8,7 +8,7 @@ class_name GSTEvade
func _init( func _init(
agent: GSTSteeringAgent, agent: GSTSteeringAgent,
target: GSTSteeringAgent, target: GSTSteeringAgent,
max_predict_time: = 1.0).(agent, target, max_predict_time): max_predict_time := 1.0).(agent, target, max_predict_time):
pass pass

View File

@ -9,8 +9,8 @@ func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent, target) ->
func _face(acceleration: GSTTargetAcceleration, target_position: Vector3) -> GSTTargetAcceleration: func _face(acceleration: GSTTargetAcceleration, target_position: Vector3) -> GSTTargetAcceleration:
var to_target: = target_position - agent.position var to_target := target_position - agent.position
var distance_squared: = to_target.length_squared() var distance_squared := 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()

View File

@ -4,33 +4,33 @@ class_name GSTFollowPath
var path: GSTPath var path: GSTPath
var path_offset: = 0.0 var path_offset := 0.0
var path_param: = {segment_index = 0, distance = 0} var path_param := {segment_index = 0, distance = 0}
var arrive_enabled: = true var arrive_enabled := true
var prediction_time: = 0.0 var prediction_time := 0.0
func _init( func _init(
agent: GSTSteeringAgent, agent: GSTSteeringAgent,
path: GSTPath, path: GSTPath,
path_offset: = 0.0, path_offset := 0.0,
prediction_time: = 0.0).(agent, null) -> void: prediction_time := 0.0).(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: GSTTargetAcceleration) -> GSTTargetAcceleration: func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration:
var location: = ( var location := (
agent.position if prediction_time == 0 agent.position if prediction_time == 0
else agent.position + (agent.linear_velocity * prediction_time)) else agent.position + (agent.linear_velocity * prediction_time))
var distance: = path.calculate_distance(location, path_param) var distance := path.calculate_distance(location, path_param)
var target_distance: = distance + path_offset var target_distance := distance + path_offset
var target_position: = path.calculate_target_position(path_param, target_distance) var target_position := path.calculate_target_position(path_param, target_distance)
if arrive_enabled and path.open: if arrive_enabled and path.open:
if path_offset >= 0: if path_offset >= 0:

View File

@ -12,5 +12,5 @@ func _calculate_steering(accel: GSTTargetAcceleration) -> GSTTargetAcceleration:
accel.set_zero() accel.set_zero()
return accel return accel
else: else:
var orientation: = atan2(agent.linear_velocity.x, -agent.linear_velocity.y) var orientation := atan2(agent.linear_velocity.x, -agent.linear_velocity.y)
return _match_orientation(accel, orientation) return _match_orientation(accel, orientation)

View File

@ -15,14 +15,14 @@ func _init(agent: GSTSteeringAgent, target: GSTAgentLocation).(agent) -> void:
func _match_orientation(acceleration: GSTTargetAcceleration, desired_orientation: float) -> GSTTargetAcceleration: func _match_orientation(acceleration: GSTTargetAcceleration, desired_orientation: float) -> GSTTargetAcceleration:
var rotation: = wrapf(desired_orientation - agent.orientation, -PI, PI) var rotation := wrapf(desired_orientation - agent.orientation, -PI, PI)
var rotation_size: = abs(rotation) var rotation_size := abs(rotation)
if rotation_size <= alignment_tolerance: if rotation_size <= alignment_tolerance:
acceleration.set_zero() acceleration.set_zero()
else: else:
var desired_rotation: = agent.max_angular_speed var desired_rotation := agent.max_angular_speed
if rotation_size <= deceleration_radius: if rotation_size <= deceleration_radius:
desired_rotation *= rotation_size / deceleration_radius desired_rotation *= rotation_size / deceleration_radius
@ -31,7 +31,7 @@ func _match_orientation(acceleration: GSTTargetAcceleration, desired_orientation
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 := abs(acceleration.angular)
if limited_acceleration > agent.max_angular_acceleration: if limited_acceleration > agent.max_angular_acceleration:
acceleration.angular *= agent.max_angular_acceleration / limited_acceleration acceleration.angular *= agent.max_angular_acceleration / limited_acceleration

View File

@ -4,13 +4,13 @@ class_name GSTPriority
# acceleration. # acceleration.
var _behaviors: = [] var _behaviors := []
var last_selected_index: int var last_selected_index: int
var threshold_for_zero: float var threshold_for_zero: float
func _init(agent: GSTSteeringAgent, threshold_for_zero: = 0.001).(agent) -> void: func _init(agent: GSTSteeringAgent, threshold_for_zero := 0.001).(agent) -> void:
self.threshold_for_zero = threshold_for_zero self.threshold_for_zero = threshold_for_zero
@ -26,11 +26,11 @@ func get_behavior_at(index: int) -> GSTSteeringBehavior:
func _calculate_steering(accel: GSTTargetAcceleration) -> GSTTargetAcceleration: func _calculate_steering(accel: GSTTargetAcceleration) -> GSTTargetAcceleration:
var threshold_squared: = threshold_for_zero * threshold_for_zero var threshold_squared := threshold_for_zero * threshold_for_zero
last_selected_index = -1 last_selected_index = -1
var size: = _behaviors.size() var size := _behaviors.size()
if size > 0: if size > 0:
for i in range(size): for i in range(size):

View File

@ -12,20 +12,20 @@ var max_predict_time: float
func _init( func _init(
agent: GSTSteeringAgent, agent: GSTSteeringAgent,
target: GSTSteeringAgent, target: GSTSteeringAgent,
max_predict_time: = 1.0).(agent) -> void: max_predict_time := 1.0).(agent) -> void:
self.target = target self.target = target
self.max_predict_time = max_predict_time self.max_predict_time = max_predict_time
func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration: func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration:
var target_position: = target.position var target_position := target.position
var distance_squared: = (target_position - agent.position).length_squared() var distance_squared := (target_position - agent.position).length_squared()
var speed_squared: = agent.linear_velocity.length_squared() var speed_squared := agent.linear_velocity.length_squared()
var predict_time: = max_predict_time var predict_time := max_predict_time
if speed_squared > 0: if speed_squared > 0:
var predict_time_squared: = distance_squared / speed_squared var predict_time_squared := distance_squared / speed_squared
if predict_time_squared < max_predict_time * max_predict_time: if predict_time_squared < max_predict_time * max_predict_time:
predict_time = sqrt(predict_time_squared) predict_time = sqrt(predict_time_squared)

View File

@ -8,7 +8,7 @@ class_name GSTSeparation
# # In effect, all neighbors produce a single repelling force. # # In effect, all neighbors produce a single repelling force.
var decay_coefficient: = 1.0 var decay_coefficient := 1.0
var acceleration: GSTTargetAcceleration var acceleration: GSTTargetAcceleration
@ -25,12 +25,12 @@ func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAccele
func report_neighbor(neighbor: GSTSteeringAgent) -> bool: func report_neighbor(neighbor: GSTSteeringAgent) -> bool:
var to_agent: = agent.position - neighbor.position var to_agent := agent.position - neighbor.position
var distance_squared: = to_agent.length_squared() var distance_squared := to_agent.length_squared()
var max_acceleration: = agent.max_linear_acceleration var max_acceleration := agent.max_linear_acceleration
var strength: = decay_coefficient / distance_squared var strength := decay_coefficient / distance_squared
if strength > max_acceleration: if strength > max_acceleration:
strength = max_acceleration strength = max_acceleration

View File

@ -2,5 +2,5 @@ class_name GSTAgentLocation
# Data type to represent an agent with a location and an orientation # Data type to represent an agent with a location and an orientation
var position: = Vector3.ZERO var position := Vector3.ZERO
var orientation: = 0.0 var orientation := 0.0

View File

@ -5,7 +5,7 @@ class_name GSTGroupBehavior
var proximity: GSTProximity var proximity: GSTProximity
var _callback: = funcref(self, "report_neighbor") var _callback := funcref(self, "report_neighbor")
func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent) -> void: func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent) -> void:

View File

@ -15,8 +15,8 @@ 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, open := false) -> void:
open = is_open self.open = open
create_path(waypoints) create_path(waypoints)
_nearest_point_on_segment = waypoints[0] _nearest_point_on_segment = waypoints[0]
_nearest_point_on_path = waypoints[0] _nearest_point_on_path = waypoints[0]
@ -39,8 +39,8 @@ func create_path(waypoints: Array) -> void:
elif open: elif open:
break break
else: else:
current = waypoints.front() current = waypoints[0]
var segment: = GSTSegment.new(previous, current) var segment := GSTSegment.new(previous, current)
length += segment.length length += segment.length
segment.cumulative_length = length segment.cumulative_length = length
_segments.append(segment) _segments.append(segment)
@ -53,7 +53,7 @@ func calculate_distance(agent_current_position: Vector3, path_parameter: Diction
var nearest_segment: GSTSegment var nearest_segment: GSTSegment
for i in range(_segments.size()): for i in range(_segments.size()):
var segment: GSTSegment = _segments[i] var segment: GSTSegment = _segments[i]
var distance_squared: = _calculate_point_segment_distance_squared( var distance_squared := _calculate_point_segment_distance_squared(
segment.begin, segment.begin,
segment.end, segment.end,
agent_current_position agent_current_position
@ -65,7 +65,7 @@ func calculate_distance(agent_current_position: Vector3, path_parameter: Diction
nearest_segment = segment nearest_segment = segment
path_parameter.segment_index = i path_parameter.segment_index = i
var length_on_path: = ( var length_on_path := (
nearest_segment.cumulative_length - nearest_segment.cumulative_length -
_nearest_point_on_path.distance_to(nearest_segment.end)) _nearest_point_on_path.distance_to(nearest_segment.end))
@ -93,7 +93,7 @@ func calculate_target_position(param: Dictionary, target_distance: float) -> Vec
if not desired_segment: if not desired_segment:
desired_segment = _segments.back() desired_segment = _segments.back()
var distance: = desired_segment.cumulative_length - target_distance var distance := desired_segment.cumulative_length - target_distance
return ( return (
(desired_segment.begin - desired_segment.end) * (desired_segment.begin - desired_segment.end) *
@ -110,8 +110,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 := end - start
var start_end_length_squared: = start_end.length_squared() var start_end_length_squared := 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

@ -3,12 +3,12 @@ class_name GSTSteeringAgent
# Extended agent data type that adds velocity, speed, and size data # Extended agent data type that adds velocity, speed, and size data
var zero_linear_speed_threshold: = 0.01 var zero_linear_speed_threshold := 0.01
var max_linear_speed: = 0.0 var max_linear_speed := 0.0
var max_linear_acceleration: = 0.0 var max_linear_acceleration := 0.0
var max_angular_speed: = 0.0 var max_angular_speed := 0.0
var max_angular_acceleration: = 0.0 var max_angular_acceleration := 0.0
var linear_velocity: = Vector3.ZERO var linear_velocity := Vector3.ZERO
var angular_velocity: = 0.0 var angular_velocity := 0.0
var bounding_radius: = 0.0 var bounding_radius := 0.0
var tagged: = false var tagged := false

View File

@ -2,7 +2,7 @@ class_name GSTSteeringBehavior
# Base class to calculate how an AI agent steers itself. # Base class to calculate how an AI agent steers itself.
var enabled: = true var enabled := true
var agent: GSTSteeringAgent var agent: GSTSteeringAgent

View File

@ -2,8 +2,8 @@ class_name GSTTargetAcceleration
# A linear and angular amount of acceleration. # A linear and angular amount of acceleration.
var linear: = Vector3.ZERO var linear := Vector3.ZERO
var angular: = 0.0 var angular := 0.0
func set_zero() -> void: func set_zero() -> void:

View File

@ -3,8 +3,8 @@ class_name GSTUtils
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 := vector.length_squared()
var limit_squared: = limit * limit var limit_squared := 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

View File

@ -8,10 +8,10 @@ func _init(agent: GSTSteeringAgent, agents: Array).(agent, agents) -> void:
func find_neighbors(callback: FuncRef) -> int: func find_neighbors(callback: FuncRef) -> int:
var neighbor_count: = 0 var neighbor_count := 0
var agent_count: = agents.size() var agent_count := agents.size()
for i in range(agent_count): for i in range(agent_count):
var current_agent: = agents[i] as GSTSteeringAgent var current_agent := agents[i] as GSTSteeringAgent
if current_agent != agent: if current_agent != agent:
if callback.call_func(current_agent): if callback.call_func(current_agent):

View File

@ -5,7 +5,7 @@ class_name GSTProximity
var agent: GSTSteeringAgent var agent: GSTSteeringAgent
var agents: = [] var agents := []
func _init(agent: GSTSteeringAgent, agents: Array) -> void: func _init(agent: GSTSteeringAgent, agents: Array) -> void:

View File

@ -4,9 +4,9 @@ class_name GSTRadiusProximity
# they lie within the specified radius. # they lie within the specified radius.
var radius: = 0.0 var radius := 0.0
var _last_frame: = 0 var _last_frame := 0
var _scene_tree: SceneTree var _scene_tree: SceneTree
@ -16,22 +16,22 @@ func _init(agent: GSTSteeringAgent, agents: Array, radius: float).(agent, agents
func find_neighbors(callback: FuncRef) -> int: func find_neighbors(callback: FuncRef) -> int:
var agent_count: = agents.size() var agent_count := agents.size()
var neighbor_count: = 0 var neighbor_count := 0
var current_frame: = _scene_tree.get_frame() if _scene_tree else -_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 := agent.position
for i in range(agent_count): for i in range(agent_count):
var current_agent: = agents[i] as GSTSteeringAgent var current_agent := agents[i] as GSTSteeringAgent
if current_agent != agent: if current_agent != agent:
var distance_squared: = owner_position.distance_squared_to(current_agent.position) var distance_squared := owner_position.distance_squared_to(current_agent.position)
var range_to: = radius + current_agent.bounding_radius var range_to := 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):