|
|
|
|
Reply From: |
Skipperro |
Without more code I cannot say much, but I had a similar problem with pathfinding. Maybe you can adapt my solution to your problem too.
My problem was, that I had a bunch of BadGuys on the map, each calculating path to the player each frame. If there were more than 5 BadGuys, FPS dropped to single digit.
The solution was, to build a dedicated node with a script, that calculates paths from BadGuy to Player on a separate thread, and when calculation is done, it sends signal to BadGuy with updated path. This way performance is constant and if there are many BadGuys, only update-rate drops (AI have slower reaction time), not FPS.
Maybe it will help you. To say more, I would have to see the whole code.
Can you show your code so I can edit and use it
jujumumu | 2019-08-08 23:38
Sure… It’s more than a few lines and it’s not the cleanest code, as it was created with great deal of experimentation and I haven’t refactored it yet, but this should give you a glimpse of what is going on.
Focus on pathfinder
variable.
This is a controller script:
extends Spatial
export var maximum_enemies = 50
var Counter = 0
var pathfinder = Thread.new()
#var spawner = Thread.new()
var enemies_to_command = []
var threaddata
var mutex = Mutex.new()
var charge_mode = 0.0
var nav
func _ready():
nav = get_parent().get_node("Navigation")
func _physics_process(delta):
charge_mode += delta
if charge_mode > 10.0:
charge_mode = 0.0
if not pathfinder.is_active():
var PLAYER = get_parent_spatial().get_node("Player/KinematicBody")
var player_pos = PLAYER.get_global_transform().origin
enemies_to_command.clear()
for enemy in get_children():
if enemy.has_method("_UpdatePath"):
if not (enemy.dead):
if enemy.last_gps_update > 1.0:
enemy.last_gps_update = 0.0
enemies_to_command.append([enemy.name, enemy.get_node("KinematicBody").get_global_transform().origin, player_pos])
pathfinder.start(self, "_async_pathfinder", enemies_to_command, 0)
func _async_pathfinder(data):
for e in data:
var start = e[1]
var end = e[2]
var enemy_name = e[0]
var pathvect = nav.get_simple_path(start, nav.get_closest_point(end), true)
var path = []
if pathvect.size() == 0:
path = [end, end, end] # Fallback
else:
path = Array(pathvect)
call_deferred("send_to_enemy", [enemy_name, path])
call_deferred("_async_pathfinder_completed", [])
func send_to_enemy(commands):
if has_node(commands[0]):
get_node(commands[0]).call_deferred("_UpdatePath", commands[1])
func _async_pathfinder_completed(path):
var results = pathfinder.wait_to_finish()
func _on_Commander_timeout():
if pathfinder.is_active():
return false
pathfinder.start(self, "_async_pathfinder", [])
On BadGuy Nodes:
var gps_points = []
var dead = false
var last_gps_update = 5.0
func _UpdatePath(path):
if dead or disposable:
return false
if path.size() > 2:
gps_points = path
Skipperro | 2019-08-09 05:48
I found out it is not because of the intense calculations it is the number of rigidbodies.
jujumumu | 2019-08-09 17:24