Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | smavanat |
I am using this context based steering algorithm for my enemies:
enum{
IDLE,
CHASE}
export var max_speed = 1000
export var steer_force = 0.1
export var look_ahead = 100
export var num_rays = 8;
#context array
var ray_directions = []
var interest = []
var danger = []
var chosen_dir = Vector2.ZERO
var velocity = Vector2.ZERO
var acceleration = Vector2.ZERO
var state = IDLE
onready var player_detection_zone = get_node("PlayerDetectionZone")
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
interest.resize(num_rays)
danger.resize(num_rays)
ray_directions.resize(num_rays)
for i in num_rays:
var angle = i * 2 * PI / num_rays
ray_directions[i] = Vector2.RIGHT.rotated(angle)
func _physics_process(delta: float):
set_interest()
set_danger()
choose_direction()
var desired_velocity = chosen_dir.rotated(rotation) * max_speed
velocity = velocity.linear_interpolate(desired_velocity, steer_force)
move_and_slide(velocity * delta)
func set_interest():
var player = player_detection_zone.player
#Set interest in each slot based on world direction
match state:
IDLE:
seek_player()
if owner and owner.has_method("get_path_direction"):
var path_direction = owner.get_path_direction(position)
for i in num_rays:
var d = ray_directions[i].rotated(rotation).dot(path_direction)
interest[i] = max(0, d)
else:
set_default_interest()
#if no world path, use default
CHASE:
if player != null:
var direction = (player.global_position - global_position).normalized()
for i in num_rays:
var d = ray_directions[i].rotated(rotation).dot(direction)
interest[i] = max(0, d)
func set_default_interest():
#default to moving forward
for i in num_rays:
var d = ray_directions[i].rotated(rotation).dot(transform.x)
interest[i] = max(0, d )
func set_danger():
#Cast rays to find danger directions
var space_state = get_world_2d().direct_space_state
for i in num_rays:
var result = space_state.intersect_ray(position,
position+ray_directions[i].rotated(rotation)*look_ahead, [self], 0x1)
danger[i] = 1.0 if result else 0.0
func choose_direction():
#Eliminate interest in slots with danger
for i in num_rays:
if danger[i] > 0.0:
interest[i] = 0.0
#Choose direction based on remaining interest
chosen_dir = Vector2.ZERO
for i in num_rays:
chosen_dir +=ray_directions[i] * interest[i]
chosen_dir = chosen_dir.normalized()
#Sees if the player enters the detection zone
func seek_player():
if player_detection_zone.can_see_player():
state = CHASE
This causes the enemy to move in the correct direction and avoid all obstacles, but the sprite is constantly jittering. I have turned off v-sync and set the display window to fullscreen, but this does not fix the issue.
The only thing that stops the stutter is if I add “rotation =velocity.angle”, however this causes the sprite to rotate, which is why I removed it from the code. Is there a way of stopping the stutter without causing the sprite to rotate?
EDIT: I have also tried using the smoothing addon by lawnjelly but this has also not fixed the issue
I have fixed the problem slightly by making the viewport smaller which causes a lower stutter which is much less noticeable
smavanat | 2022-08-19 12:39