0 votes

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

Godot version 3.4.4 stable mono
in Engine by (14 points)
edited by

I have fixed the problem slightly by making the viewport smaller which causes a lower stutter which is much less noticeable

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.