Improve Bunny AI Performance Impact

This commit is contained in:
Snoweuph 2023-04-12 21:16:14 +02:00
parent 1f24357f1f
commit c0cf72a6d1
7 changed files with 81 additions and 66 deletions

View file

@ -1,12 +1,14 @@
[gd_resource type="TileSet" load_steps=4 format=3 uid="uid://bj7uu2180mie3"] [gd_resource type="TileSet" load_steps=5 format=3 uid="uid://bj7uu2180mie3"]
[ext_resource type="Texture2D" uid="uid://dl2qogjortsbo" path="res://Assets/Sprites/TileMap.png" id="1_cl3se"] [ext_resource type="Texture2D" uid="uid://dl2qogjortsbo" path="res://Assets/Sprites/TileMap.png" id="1_cl3se"]
[sub_resource type="NavigationPolygon" id="NavigationPolygon_fhapu"] [sub_resource type="NavigationPolygon" id="NavigationPolygon_l6uwm"]
vertices = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16) vertices = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)
polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3)]) polygons = Array[PackedInt32Array]([PackedInt32Array(0, 1, 2, 3)])
outlines = Array[PackedVector2Array]([PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)]) outlines = Array[PackedVector2Array]([PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16)])
[sub_resource type="NavigationPolygon" id="NavigationPolygon_dkm5b"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_mgef5"] [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_mgef5"]
texture = ExtResource("1_cl3se") texture = ExtResource("1_cl3se")
texture_region_size = Vector2i(32, 32) texture_region_size = Vector2i(32, 32)
@ -431,6 +433,7 @@ texture_region_size = Vector2i(32, 32)
9:3/0/terrains_peering_bit/top_left_corner = 0 9:3/0/terrains_peering_bit/top_left_corner = 0
9:3/0/terrains_peering_bit/top_side = 0 9:3/0/terrains_peering_bit/top_side = 0
9:3/0/terrains_peering_bit/top_right_corner = 0 9:3/0/terrains_peering_bit/top_right_corner = 0
9:3/0/navigation_layer_0/polygon = SubResource("NavigationPolygon_dkm5b")
10:3/0 = 0 10:3/0 = 0
10:3/0/terrain_set = 0 10:3/0/terrain_set = 0
10:3/0/terrain = 0 10:3/0/terrain = 0
@ -452,12 +455,21 @@ texture_region_size = Vector2i(32, 32)
11:3/0/terrains_peering_bit/left_side = 0 11:3/0/terrains_peering_bit/left_side = 0
11:3/0/terrains_peering_bit/top_left_corner = 0 11:3/0/terrains_peering_bit/top_left_corner = 0
11:3/0/terrains_peering_bit/top_side = 0 11:3/0/terrains_peering_bit/top_side = 0
10:1/next_alternative_id = 11
10:1/0 = 0 10:1/0 = 0
10:1/0/terrain_set = 0 10:1/0/terrain_set = 0
10:1/0/terrain = 1 10:1/0/terrain = 1
10:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) 10:1/0/physics_layer_0/linear_velocity = Vector2(0, 0)
10:1/0/physics_layer_0/angular_velocity = 0.0 10:1/0/physics_layer_0/angular_velocity = 0.0
10:1/0/navigation_layer_0/polygon = SubResource("NavigationPolygon_fhapu") 10:1/0/terrains_peering_bit/right_side = 1
10:1/0/terrains_peering_bit/bottom_right_corner = 1
10:1/0/terrains_peering_bit/bottom_side = 1
10:1/0/terrains_peering_bit/bottom_left_corner = 1
10:1/0/terrains_peering_bit/left_side = 1
10:1/0/terrains_peering_bit/top_left_corner = 1
10:1/0/terrains_peering_bit/top_side = 1
10:1/0/terrains_peering_bit/top_right_corner = 1
10:1/0/navigation_layer_0/polygon = SubResource("NavigationPolygon_l6uwm")
[resource] [resource]
tile_size = Vector2i(32, 32) tile_size = Vector2i(32, 32)

View file

@ -41,7 +41,7 @@
[ext_resource type="StyleBox" uid="uid://0jfr1uwuog0s" path="res://Assets/UI/Slider/v/background.tres" id="39_dl1e4"] [ext_resource type="StyleBox" uid="uid://0jfr1uwuog0s" path="res://Assets/UI/Slider/v/background.tres" id="39_dl1e4"]
[ext_resource type="FontFile" uid="uid://dqdeftjkwxe64" path="res://Assets/Fonts/Dogica/dogicapixel.ttf" id="40_bmcvq"] [ext_resource type="FontFile" uid="uid://dqdeftjkwxe64" path="res://Assets/Fonts/Dogica/dogicapixel.ttf" id="40_bmcvq"]
[sub_resource type="Image" id="Image_fjlcl"] [sub_resource type="Image" id="Image_iaqit"]
data = { data = {
"data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0), "data": PackedByteArray(255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 64, 255, 255, 255, 64, 255, 255, 255, 0),
"format": "RGBA8", "format": "RGBA8",
@ -51,7 +51,7 @@ data = {
} }
[sub_resource type="ImageTexture" id="ImageTexture_g5bup"] [sub_resource type="ImageTexture" id="ImageTexture_g5bup"]
image = SubResource("Image_fjlcl") image = SubResource("Image_iaqit")
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_sj7h5"] [sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_sj7h5"]

View file

@ -61,7 +61,6 @@ size_flags_vertical = 3
tabs_rearrange_group = 0 tabs_rearrange_group = 0
[node name="Video" type="MarginContainer" parent="Panel/MarginContainer/VBoxContainer/SettingsTabs"] [node name="Video" type="MarginContainer" parent="Panel/MarginContainer/VBoxContainer/SettingsTabs"]
visible = false
layout_mode = 2 layout_mode = 2
theme_override_constants/margin_left = 4 theme_override_constants/margin_left = 4
theme_override_constants/margin_top = 4 theme_override_constants/margin_top = 4
@ -232,6 +231,7 @@ min_value = -72.0
max_value = 0.0 max_value = 0.0
[node name="Controls" type="MarginContainer" parent="Panel/MarginContainer/VBoxContainer/SettingsTabs"] [node name="Controls" type="MarginContainer" parent="Panel/MarginContainer/VBoxContainer/SettingsTabs"]
visible = false
layout_mode = 2 layout_mode = 2
theme_override_constants/margin_left = 4 theme_override_constants/margin_left = 4
theme_override_constants/margin_top = 4 theme_override_constants/margin_top = 4

View file

@ -1,13 +1,8 @@
[gd_scene load_steps=12 format=3 uid="uid://cpl4tllohhyel"] [gd_scene load_steps=10 format=3 uid="uid://cpl4tllohhyel"]
[ext_resource type="Script" path="res://Scripts/EntitySystem/Bunny.gd" id="1_1kj2b"] [ext_resource type="Script" path="res://Scripts/EntitySystem/Bunny.gd" id="1_1kj2b"]
[ext_resource type="Texture2D" uid="uid://df2fluk0dlqar" path="res://Assets/Sprites/Bunny/bad_bunny_spritesheet.png" id="2_v8p70"] [ext_resource type="Texture2D" uid="uid://df2fluk0dlqar" path="res://Assets/Sprites/Bunny/bad_bunny_spritesheet.png" id="2_v8p70"]
[sub_resource type="CircleShape2D" id="CircleShape2D_sedmr"]
[sub_resource type="CircleShape2D" id="CircleShape2D_itvjj"]
radius = 14.0
[sub_resource type="Animation" id="Animation_6br4g"] [sub_resource type="Animation" id="Animation_6br4g"]
resource_name = "Idle" resource_name = "Idle"
tracks/0/type = "value" tracks/0/type = "value"
@ -116,9 +111,7 @@ _data = {
"RESET": SubResource("Animation_mp212") "RESET": SubResource("Animation_mp212")
} }
[node name="Bunny" type="CharacterBody2D" node_paths=PackedStringArray("animation_player", "agent")] [node name="Bunny" type="Node2D" node_paths=PackedStringArray("animation_player", "agent")]
collision_layer = 4
collision_mask = 15
script = ExtResource("1_1kj2b") script = ExtResource("1_1kj2b")
animation_player = NodePath("BunnyAnimator") animation_player = NodePath("BunnyAnimator")
agent = NodePath("NavigationAgent") agent = NodePath("NavigationAgent")
@ -129,23 +122,10 @@ texture = ExtResource("2_v8p70")
hframes = 5 hframes = 5
vframes = 4 vframes = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CircleShape2D_sedmr")
[node name="NavigationAgent" type="NavigationAgent2D" parent="."] [node name="NavigationAgent" type="NavigationAgent2D" parent="."]
path_metadata_flags = 0 path_metadata_flags = 0
[node name="Area2D" type="Area2D" parent="."]
collision_layer = 64
collision_mask = 4
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
shape = SubResource("CircleShape2D_itvjj")
[node name="BunnyAnimator" type="AnimationPlayer" parent="."] [node name="BunnyAnimator" type="AnimationPlayer" parent="."]
libraries = { libraries = {
"": SubResource("AnimationLibrary_uuf00") "": SubResource("AnimationLibrary_uuf00")
} }
[connection signal="body_entered" from="Area2D" to="." method="_on_collision"]
[connection signal="body_exited" from="Area2D" to="." method="_of_collision"]

View file

@ -1,53 +1,75 @@
extends CharacterBody2D extends Node2D
class_name Bunny class_name Bunny
@export var animation_player : AnimationPlayer @export var animation_player : AnimationPlayer
@export var min_distance_to_player := 80.0 @export var min_distance_to_player := 20.0
@export var max_distance_to_player := 800.0 @export var max_distance_to_player := 500.0
@export var agent : NavigationAgent2D @export var agent : NavigationAgent2D
@export var speed := 100.0 @export var speed := 3.0
var health : int var health : int
var team : int var team : int
var player : Node2D var player : Node2D
var on_death_callbacks : Array var on_death_callbacks : Array
var move_velocity : Vector2
var next_location : Vector2
var randomized_next_location : Vector2
var dir : Vector2 var dir : Vector2
var spread_time : float
var current_time : float var time_since_got_player := 100.0
var collisions : int var time_since_got_move_location := 100.0
var last_player_velocity := 0.0
var last_target_position : Vector2
var max_pos_check_time := 0.5
var max_pos_check_time_inactive_scalar := 10.0
var max_get_move_location_time := 0.125
var random_goal_spread_factor := 2.5
var random_move_location_spread_factor := 8.0
var random_angle_change := deg_to_rad(4.0)
func _ready(): func _ready():
seed(int(str(self))) pass
spread_time = randf() * 2 + 0.1
current_time = spread_time
func _physics_process(delta): func _physics_process(delta):
current_time -= delta randomize()
if player != null and self.global_position.distance_to(player.global_position) < max_distance_to_player and collisions <= 3:
if current_time <= 0: if abs(player.velocity.length() - last_player_velocity) > 100.0:
current_time = spread_time time_since_got_player = max_pos_check_time
agent.target_position = player.global_position if time_since_got_player >= max_pos_check_time and player.velocity.length() > 0.1:
if min_distance_to_player and agent.is_target_reachable(): time_since_got_player = randf() * max_pos_check_time * 0.5
var next_location = agent.get_next_path_position() + Vector2(randf() - 0.5 * 2, randf() - 0.5 * 2) update_target_pos()
dir = self.global_position.direction_to(next_location).normalized() if time_since_got_player >= max_pos_check_time * max_pos_check_time_inactive_scalar and player.velocity.length() < 0.1:
if self.global_position.distance_to(player.global_position) > min_distance_to_player: time_since_got_player = -(randf() * max_pos_check_time * 0.5)
self.velocity = dir * delta * 60 * speed update_target_pos()
if self.global_position.distance_to(player.global_position) < max_distance_to_player and time_since_got_move_location > max_get_move_location_time:
time_since_got_move_location = 0
if agent.is_target_reachable():
next_location = agent.get_next_path_position()
randomized_next_location = next_location + Vector2(randf() - 0.5, randf() - 0.5 ) * 2 * random_move_location_spread_factor
dir = self.global_position.direction_to(randomized_next_location).normalized().rotated((randf() - 0.5) * 2 * random_angle_change)
if self.global_position.distance_to(player.global_position) >= min_distance_to_player:
move_velocity = dir * delta * 60 * speed
update_animation() update_animation()
if delta > 0.5: if self.global_position.distance_to(next_location) < move_velocity.length():
print(delta) self.global_position = next_location
move_and_slide() time_since_got_player = 10.0
time_since_got_move_location = 10.0
else:
self.translate(move_velocity)
else: else:
animation_player.stop() animation_player.stop()
time_since_got_player += delta
time_since_got_move_location += delta
last_player_velocity = player.velocity.length()
last_target_position = agent.target_position
pass pass
func _on_collision(body): func update_target_pos():
if body != self: collisions += 1 agent.target_position = Vector2(player.global_position) + Vector2(randf() - 0.5 , randf() - 0.5) * 2 * random_goal_spread_factor
pass
func _of_collision(body):
if body != self: collisions-= 1
pass pass
func damage(damage_amount : int): func damage(damage_amount : int):
@ -69,13 +91,13 @@ func sub_on_death(callback : Callable):
pass pass
func update_animation(): func update_animation():
match self.velocity: match self.move_velocity:
Vector2.ZERO: animation_player.play("Idle") Vector2.ZERO: animation_player.play("Idle")
_: _:
var left_dot = Vector2.LEFT.dot(self.velocity) var left_dot = Vector2.LEFT.dot(self.move_velocity)
var right_dot = Vector2.RIGHT.dot(self.velocity) var right_dot = Vector2.RIGHT.dot(self.move_velocity)
var up_dot = Vector2.UP.dot(self.velocity) var up_dot = Vector2.UP.dot(self.move_velocity)
var down_dot = Vector2.DOWN.dot(self.velocity) var down_dot = Vector2.DOWN.dot(self.move_velocity)
var max_dot = maxf(left_dot, maxf(right_dot, maxf(up_dot, down_dot))) var max_dot = maxf(left_dot, maxf(right_dot, maxf(up_dot, down_dot)))
match max_dot: match max_dot:

View file

@ -17,7 +17,7 @@ func _process(_delta):
if bunnys.size() == 0 and !in_wave_gen: if bunnys.size() == 0 and !in_wave_gen:
in_wave_gen = true in_wave_gen = true
wave += 1 wave += 1
bunnys = await bunny_generator.spawn_batched_wave(5.0, 0.25, gen_data.free_tiles.duplicate(), TEAM.EVIL, wave * 10.0, 3) bunnys = await bunny_generator.spawn_batched_wave(25, 0.25, gen_data.free_tiles.duplicate(), TEAM.EVIL, wave * 250, 3)
for bunny in bunnys: for bunny in bunnys:
bunny.sub_on_death(func(bunny): bunnys.erase(bunny)) bunny.sub_on_death(func(bunny): bunnys.erase(bunny))
bunny.sub_on_death(func(bunny): bunny.queue_free()) bunny.sub_on_death(func(bunny): bunny.queue_free())

View file

@ -187,6 +187,7 @@ ui_tab_right={
2d_physics/layer_3="Bunny" 2d_physics/layer_3="Bunny"
2d_physics/layer_4="Projectile" 2d_physics/layer_4="Projectile"
2d_physics/layer_5="Layer 5" 2d_physics/layer_5="Layer 5"
2d_navigation/layer_5="Map Solid"
2d_physics/layer_7="bunny_check" 2d_physics/layer_7="bunny_check"
[rendering] [rendering]