mirror of
https://github.com/Relintai/godot-steering-ai-framework.git
synced 2024-11-10 00:52:10 +01:00
Add Cohesion behavior and RadiusProximity caching
This commit is contained in:
parent
ac99344633
commit
34b58a6bba
@ -20,10 +20,20 @@ _global_script_classes=[ {
|
||||
"path": "res://src/behaviors/GSTArrive.gd"
|
||||
}, {
|
||||
"base": "GSTSteeringBehavior",
|
||||
"class": "GSTAvoidCollisions",
|
||||
"language": "GDScript",
|
||||
"path": "res://src/behaviors/GSTAvoidCollisions.gd"
|
||||
}, {
|
||||
"base": "GSTSteeringBehavior",
|
||||
"class": "GSTBlend",
|
||||
"language": "GDScript",
|
||||
"path": "res://src/behaviors/GSTBlend.gd"
|
||||
}, {
|
||||
"base": "GSTSteeringBehavior",
|
||||
"class": "GSTCohesion",
|
||||
"language": "GDScript",
|
||||
"path": "res://src/behaviors/GSTCohesion.gd"
|
||||
}, {
|
||||
"base": "GSTPursue",
|
||||
"class": "GSTEvade",
|
||||
"language": "GDScript",
|
||||
@ -39,6 +49,11 @@ _global_script_classes=[ {
|
||||
"language": "GDScript",
|
||||
"path": "res://src/behaviors/GSTFlee.gd"
|
||||
}, {
|
||||
"base": "GSTArrive",
|
||||
"class": "GSTFollowPath",
|
||||
"language": "GDScript",
|
||||
"path": "res://src/behaviors/GSTFollowPath.gd"
|
||||
}, {
|
||||
"base": "GSTProximity",
|
||||
"class": "GSTInfiniteProximity",
|
||||
"language": "GDScript",
|
||||
@ -54,6 +69,11 @@ _global_script_classes=[ {
|
||||
"language": "GDScript",
|
||||
"path": "res://src/behaviors/GSTMatchOrientation.gd"
|
||||
}, {
|
||||
"base": "Reference",
|
||||
"class": "GSTPath",
|
||||
"language": "GDScript",
|
||||
"path": "res://src/GSTPath.gd"
|
||||
}, {
|
||||
"base": "GSTSteeringBehavior",
|
||||
"class": "GSTPriority",
|
||||
"language": "GDScript",
|
||||
@ -107,13 +127,17 @@ _global_script_classes=[ {
|
||||
_global_script_class_icons={
|
||||
"GSTAgentLocation": "",
|
||||
"GSTArrive": "",
|
||||
"GSTAvoidCollisions": "",
|
||||
"GSTBlend": "",
|
||||
"GSTCohesion": "",
|
||||
"GSTEvade": "",
|
||||
"GSTFace": "",
|
||||
"GSTFlee": "",
|
||||
"GSTFollowPath": "",
|
||||
"GSTInfiniteProximity": "",
|
||||
"GSTLookWhereYouGo": "",
|
||||
"GSTMatchOrientation": "",
|
||||
"GSTPath": "",
|
||||
"GSTPriority": "",
|
||||
"GSTProximity": "",
|
||||
"GSTPursue": "",
|
||||
|
@ -11,3 +11,4 @@ var max_angular_acceleration: = 0.0
|
||||
var linear_velocity: = Vector3.ZERO
|
||||
var angular_velocity: = 0.0
|
||||
var bounding_radius: = 0.0
|
||||
var tagged: = false
|
||||
|
27
project/src/behaviors/GSTCohesion.gd
Normal file
27
project/src/behaviors/GSTCohesion.gd
Normal file
@ -0,0 +1,27 @@
|
||||
extends GSTSteeringBehavior
|
||||
class_name GSTCohesion
|
||||
# Group behavior that produces linear acceleration that attempts to move the agent towards the
|
||||
# center of mass of the agents in the area defined by the defined Proximity.
|
||||
|
||||
|
||||
var center_of_mass: Vector3
|
||||
var proximity: GSTProximity
|
||||
|
||||
|
||||
func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent) -> void:
|
||||
self.proximity = proximity
|
||||
|
||||
|
||||
func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration:
|
||||
acceleration.set_zero()
|
||||
center_of_mass = Vector3.ZERO
|
||||
var neighbor_count = proximity.find_neighbors(funcref(self, "_report_neighbor"))
|
||||
if neighbor_count > 0:
|
||||
center_of_mass *= 1.0 / neighbor_count
|
||||
acceleration.linear = (center_of_mass - agent.position).normalized() * agent.max_linear_acceleration
|
||||
return acceleration
|
||||
|
||||
|
||||
func _report_neighbor(neighbor: GSTSteeringAgent) -> bool:
|
||||
center_of_mass += neighbor.position
|
||||
return true
|
@ -1,16 +1,16 @@
|
||||
extends Reference
|
||||
class_name GSTProximity
|
||||
# Defines an area that is used by group behaviors to find and process the owner's neighbors.
|
||||
|
||||
|
||||
var agent: GSTSteeringAgent
|
||||
var agents: = []
|
||||
|
||||
|
||||
func _init(agent: GSTSteeringAgent, agents: Array) -> void:
|
||||
self.agent = agent
|
||||
self.agents = agents
|
||||
|
||||
|
||||
func find_neighbors(callback: FuncRef) -> int:
|
||||
return 0
|
||||
extends Reference
|
||||
class_name GSTProximity
|
||||
# Defines an area that is used by group behaviors to find and process the owner's neighbors.
|
||||
|
||||
|
||||
var agent: GSTSteeringAgent
|
||||
var agents: = []
|
||||
|
||||
|
||||
func _init(agent: GSTSteeringAgent, agents: Array) -> void:
|
||||
self.agent = agent
|
||||
self.agents = agents
|
||||
|
||||
|
||||
func find_neighbors(callback: FuncRef) -> int:
|
||||
return 0
|
||||
|
@ -6,28 +6,46 @@ class_name GSTRadiusProximity
|
||||
|
||||
var radius: = 0.0
|
||||
|
||||
var _last_frame: = 0
|
||||
var _scene_tree: SceneTree
|
||||
|
||||
|
||||
func _init(agent: GSTSteeringAgent, agents: Array, radius: float).(agent, agents) -> void:
|
||||
self.radius = radius
|
||||
_scene_tree = Engine.get_main_loop()
|
||||
|
||||
|
||||
func find_neighbors(callback: FuncRef) -> int:
|
||||
var agent_count: = agents.size()
|
||||
var neighbor_count: = 0
|
||||
|
||||
var owner_position: = agent.position
|
||||
|
||||
for i in range(agent_count):
|
||||
var current_agent: = agents[i] as GSTSteeringAgent
|
||||
|
||||
if current_agent != agent:
|
||||
var distance_squared: = owner_position.distance_squared_to(current_agent.position)
|
||||
|
||||
var range_to: = radius + current_agent.bounding_radius
|
||||
|
||||
if distance_squared < range_to * range_to:
|
||||
var current_frame: = _scene_tree.get_frame() if _scene_tree else -_last_frame
|
||||
if current_frame != _last_frame:
|
||||
_last_frame = current_frame
|
||||
|
||||
var owner_position: = agent.position
|
||||
|
||||
for i in range(agent_count):
|
||||
var current_agent: = agents[i] as GSTSteeringAgent
|
||||
|
||||
if current_agent != agent:
|
||||
var distance_squared: = owner_position.distance_squared_to(current_agent.position)
|
||||
|
||||
var range_to: = radius + current_agent.bounding_radius
|
||||
|
||||
if distance_squared < range_to * range_to:
|
||||
if callback.call_func(current_agent) == true:
|
||||
current_agent.tagged = true
|
||||
neighbor_count += 1
|
||||
continue
|
||||
|
||||
current_agent.tagged = false
|
||||
else:
|
||||
for i in range(agent_count):
|
||||
var current_agent = agents[i] as GSTSteeringAgent
|
||||
|
||||
if current_agent != agent and current_agent.tagged:
|
||||
if callback.call_func(current_agent) == true:
|
||||
neighbor_count += 1
|
||||
continue
|
||||
|
||||
return neighbor_count
|
||||
|
Loading…
Reference in New Issue
Block a user