Godot Version
4.3
Question
how can i make mob not to slide, i want it to avoind the wall.
i try to avoid it using steering. can someone tell me what i did wrong?
extends CharacterBody2D
@onready var ray_cast_2d: RayCast2D = $RayCast2D
@export var navi : NavigationAgent2D
@export var max_speed = 100
#@export var steer_force = 1.1
@export var look_ahead = 30
@export var anim : AnimationTree
@export var num_rays = 8
# context array
var ray_directions = []
var interest = []
var danger = []
var chosen_dir = Vector2.ZERO
@export var acceleration : float = 10
var mouse_pos : Vector2
var ray_arr : Array[RayCast2D]
var desired_dir : Vector2
var desired_dir_with_speed : Vector2
var steer : Vector2
@export var mass : float
var new_navi_dir : Vector2
func _ready():
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)
var _new_ray : RayCast2D = RayCast2D.new()
_new_ray.target_position = Vector2.RIGHT.rotated( angle ) * look_ahead
add_child( _new_ray)
ray_arr.append( _new_ray )
func _physics_process(delta):
navi_dir()
set_interest()
set_danger()
choose_direction()
seek_steering()
move_and_slide()
anim.set("parameters/walk/blend_position", desired_dir)
ray_cast_2d.look_at(mouse_pos)
#velocity = velocity.move_toward( chosen_dir * max_speed , 10 )
func _process(delta: float) -> void:
queue_redraw()
func _draw() -> void:
draw_circle( desired_dir_with_speed ,5 , Color.ALICE_BLUE)
draw_circle( velocity ,5 , Color.ALICE_BLUE)
draw_line( to_local(position), velocity , Color.GREEN , 4)
draw_line( to_local(position), desired_dir_with_speed , Color.AQUA , 4)
draw_line( velocity , desired_dir_with_speed , Color.BLUE , 4)
func seek_steering():
desired_dir = chosen_dir#( mouse_pos - global_position ).normalized()
desired_dir_with_speed = desired_dir * max_speed
steer = (desired_dir_with_speed - velocity) / mass
velocity = velocity.move_toward(velocity + steer , acceleration )#velocity + steer + chosen_dir +
func set_interest():
for i in num_rays:
var dir_to_target :Vector2 = new_navi_dir#mouse_pos - global_position
var normalize_it : Vector2 = dir_to_target.normalized()
var dot_p : float = normalize_it.dot( ray_directions[i] )
interest[i] = max(0,dot_p)
func set_danger():
# Cast rays to find danger directions
var space_state = get_world_2d().direct_space_state
for i in num_rays:
if ray_arr[i].get_collider() != null:
danger[i] = 1.0
else :
danger[i] = 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()
######################################################## navi
func navi_dir():
var new_dir : Vector2 = to_local( navi.get_next_path_position()).normalized()
#var distance_to_player : float = mouse_pos.distance_to( global_position )
new_navi_dir = new_dir
#input_nd.new_move_dir_facing_pos( new_dir)
func _input(event: InputEvent) -> void:
if event.is_action_pressed("L_mouse"):
mouse_pos = get_global_mouse_position()
navi.target_position = mouse_pos