Learning Vectors and Dot Product
Asked Answered
M

1

0

I'm trying to learn vectors by experimenting. I have this character (enemy) who follows a designated path, but if the player enters (area), the code calculates the dot product to determine if the character can see the player.

If the enemy sees the player, it stops and the animation shifts so that it "follows" the player. I accomplished this by using a variable called direction looking which is set when the animation shifts.

Question: Is there a better way to perform this operation? I feel like the following code has become convoluted and unnecessarily complicated.

Thanks!

extends PathFollow2D

@onready var enemy_sprite = $CharacterBody2D/AnimatedSprite2D
var speed: float = .03
var current_move_vector: Vector2
var last_move_vector = Vector2.ZERO

var animation
var direction_looking: Vector2

var is_attacking: bool = false
var player_in_area: bool = false
var is_walking: bool = true

func _physics_process(delta):
	if player_in_area:
		handle_player_in_area(delta)
	else:
		handle_player_not_in_area(delta)

func handle_player_in_area(delta: float):
	var line_of_sight = global_position.direction_to(Globals.player_position)

	var dotProduct = line_of_sight.dot(direction_looking)

	if dotProduct >= 0:
		speed = 0
		is_walking = false
		# face player
		var angle_of_lineofsight = (rad_to_deg(line_of_sight.angle())) + 90

		enemy_animation(angle_of_lineofsight)
	else:
		handle_player_not_in_area(delta)

func handle_player_not_in_area(delta: float):
	is_walking = true
	speed = .03
	progress_ratio += speed * delta
		
	current_move_vector = global_position.normalized() - last_move_vector
	last_move_vector = global_position.normalized()
	
	var angle_of_direction = (rad_to_deg(current_move_vector.angle())) + 90
	
	enemy_animation(angle_of_direction)
	print("direction looking ", direction_looking)

func enemy_animation(facingangle):
	if is_walking:
		animation = "walk_" + facing_direction(facingangle)
		enemy_sprite.play(animation)
	else:
		animation = "idle_" + facing_direction(facingangle)
		print("animation ", animation)
		enemy_sprite.play(animation)

func facing_direction(facingangle):
	
	if facingangle > 135 and facingangle < 225:
		direction_looking = Vector2.DOWN
		return "down"
	elif facingangle >= 45 and facingangle <= 135:
		enemy_sprite.flip_h = false
		enemy_sprite.offset = Vector2(11,0)
		direction_looking = Vector2.RIGHT
		return "side"
	elif facingangle >= 225 and facingangle <= 315:
		enemy_sprite.flip_h = true
		enemy_sprite.offset = Vector2(-10,0)
		direction_looking = Vector2.LEFT
		return "side"
	else:
		direction_looking = Vector2.UP
		return "up"

func _on_notice_area_body_entered(_body):
	player_in_area = true

func _on_notice_area_body_exited(_body):
	player_in_area = false
Mont answered 27/2, 2024 at 19:10 Comment(0)
P
0

Mont Your code could be simplified but the dot product usage is fine.

Piscator answered 27/2, 2024 at 20:12 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.