mirror of
https://github.com/Relintai/godot-steering-ai-framework.git
synced 2024-11-10 00:52:10 +01:00
Implement Separation behavior and add Proximity
This commit is contained in:
parent
8fb4f4c51a
commit
ac99344633
@ -39,6 +39,11 @@ _global_script_classes=[ {
|
||||
"language": "GDScript",
|
||||
"path": "res://src/behaviors/GSTFlee.gd"
|
||||
}, {
|
||||
"base": "GSTProximity",
|
||||
"class": "GSTInfiniteProximity",
|
||||
"language": "GDScript",
|
||||
"path": "res://src/proximities/GSTInfiniteProximity.gd"
|
||||
}, {
|
||||
"base": "GSTMatchOrientation",
|
||||
"class": "GSTLookWhereYouGo",
|
||||
"language": "GDScript",
|
||||
@ -54,16 +59,31 @@ _global_script_classes=[ {
|
||||
"language": "GDScript",
|
||||
"path": "res://src/behaviors/GSTPriority.gd"
|
||||
}, {
|
||||
"base": "Reference",
|
||||
"class": "GSTProximity",
|
||||
"language": "GDScript",
|
||||
"path": "res://src/proximities/GSTProximity.gd"
|
||||
}, {
|
||||
"base": "GSTSteeringBehavior",
|
||||
"class": "GSTPursue",
|
||||
"language": "GDScript",
|
||||
"path": "res://src/behaviors/GSTPursue.gd"
|
||||
}, {
|
||||
"base": "GSTProximity",
|
||||
"class": "GSTRadiusProximity",
|
||||
"language": "GDScript",
|
||||
"path": "res://src/proximities/GSTRadiusProximity.gd"
|
||||
}, {
|
||||
"base": "GSTSteeringBehavior",
|
||||
"class": "GSTSeek",
|
||||
"language": "GDScript",
|
||||
"path": "res://src/behaviors/GSTSeek.gd"
|
||||
}, {
|
||||
"base": "GSTSteeringBehavior",
|
||||
"class": "GSTSeparation",
|
||||
"language": "GDScript",
|
||||
"path": "res://src/behaviors/GSTSeparation.gd"
|
||||
}, {
|
||||
"base": "GSTAgentLocation",
|
||||
"class": "GSTSteeringAgent",
|
||||
"language": "GDScript",
|
||||
@ -91,11 +111,15 @@ _global_script_class_icons={
|
||||
"GSTEvade": "",
|
||||
"GSTFace": "",
|
||||
"GSTFlee": "",
|
||||
"GSTInfiniteProximity": "",
|
||||
"GSTLookWhereYouGo": "",
|
||||
"GSTMatchOrientation": "",
|
||||
"GSTPriority": "",
|
||||
"GSTProximity": "",
|
||||
"GSTPursue": "",
|
||||
"GSTRadiusProximity": "",
|
||||
"GSTSeek": "",
|
||||
"GSTSeparation": "",
|
||||
"GSTSteeringAgent": "",
|
||||
"GSTSteeringBehavior": "",
|
||||
"GSTTargetAcceleration": "",
|
||||
|
40
project/src/behaviors/GSTSeparation.gd
Normal file
40
project/src/behaviors/GSTSeparation.gd
Normal file
@ -0,0 +1,40 @@
|
||||
extends GSTSteeringBehavior
|
||||
class_name GSTSeparation
|
||||
# Group behavior that produces acceleration repelling from the other neighbors that are in the
|
||||
# immediate area defined by the given `GSTProximity`.
|
||||
|
||||
# # The produced acceleration is an average of all agents under consideration, multiplied by a
|
||||
# # strength decreasing by the inverse square law in relation to distance, and accumulated.
|
||||
# # In effect, all neighbors produce a single repelling force.
|
||||
|
||||
|
||||
var decay_coefficient: = 1.0
|
||||
|
||||
var acceleration: GSTTargetAcceleration
|
||||
var proximity: GSTProximity
|
||||
|
||||
|
||||
func _init(agent: GSTSteeringAgent, proximity: GSTProximity).(agent) -> void:
|
||||
self.proximity = proximity
|
||||
|
||||
|
||||
func _calculate_steering(acceleration: GSTTargetAcceleration) -> GSTTargetAcceleration:
|
||||
acceleration.set_zero()
|
||||
self.acceleration = acceleration
|
||||
proximity.find_neighbors(funcref(self, "_report_neighbor"))
|
||||
return acceleration
|
||||
|
||||
|
||||
func _report_neighbor(neighbor: GSTSteeringAgent) -> bool:
|
||||
var to_agent: = agent.position - neighbor.position
|
||||
|
||||
var distance_squared: = to_agent.length_squared()
|
||||
var max_acceleration: = agent.max_linear_acceleration
|
||||
|
||||
var strength: = decay_coefficient / distance_squared
|
||||
if strength > max_acceleration:
|
||||
strength = max_acceleration
|
||||
|
||||
acceleration.linear += to_agent * (strength / sqrt(distance_squared))
|
||||
|
||||
return true
|
20
project/src/proximities/GSTInfiniteProximity.gd
Normal file
20
project/src/proximities/GSTInfiniteProximity.gd
Normal file
@ -0,0 +1,20 @@
|
||||
extends GSTProximity
|
||||
class_name GSTInfiniteProximity
|
||||
# Specifies any agent that is in the specified list as being neighbors with the owner agent.
|
||||
|
||||
|
||||
func _init(agent: GSTSteeringAgent, agents: Array).(agent, agents) -> void:
|
||||
pass
|
||||
|
||||
|
||||
func find_neighbors(callback: FuncRef) -> int:
|
||||
var neighbor_count: = 0
|
||||
var agent_count: = agents.size()
|
||||
for i in range(agent_count):
|
||||
var current_agent: = agents[i] as GSTSteeringAgent
|
||||
|
||||
if current_agent != agent:
|
||||
if callback.call_func(current_agent):
|
||||
neighbor_count += 1
|
||||
|
||||
return neighbor_count
|
16
project/src/proximities/GSTProximity.gd
Normal file
16
project/src/proximities/GSTProximity.gd
Normal file
@ -0,0 +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
|
33
project/src/proximities/GSTRadiusProximity.gd
Normal file
33
project/src/proximities/GSTRadiusProximity.gd
Normal file
@ -0,0 +1,33 @@
|
||||
extends GSTProximity
|
||||
class_name GSTRadiusProximity
|
||||
# Specifies any agent that is in the specified list as being neighbors with the owner agent if they
|
||||
# lie within the specified radius.
|
||||
|
||||
|
||||
var radius: = 0.0
|
||||
|
||||
|
||||
func _init(agent: GSTSteeringAgent, agents: Array, radius: float).(agent, agents) -> void:
|
||||
self.radius = radius
|
||||
|
||||
|
||||
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:
|
||||
if callback.call_func(current_agent) == true:
|
||||
neighbor_count += 1
|
||||
continue
|
||||
|
||||
return neighbor_count
|
Loading…
Reference in New Issue
Block a user