Godot Version
Godot 4.6
Question
I’m trying to make a lock on feature for my game project however it won’t lock on even though I followed the tutorial step by step
The tutorial I used was https://www.youtube.com/watch?v=pq3q3EZZ-PU By DevDrache
#For the Player
extends CharacterBody3D
@export var enemy_select_range := 100.0
@onready var ksd_rotat: Node3D = $KSD_rotation
@onready var ksd_skele: Skeleton3D = $"KSD_rotation/KSD Skeleton"
@onready var ksd_model: Node3D = $"KSD_rotation/KSD Skeleton/KSD Mesh"
@onready var Overall: CollisionShape3D = $Overall
@onready var camera_pivot: Node3D = $"Camera Pivot"
@onready var camera_controller: SpringArm3D = $"Camera Pivot/Camera Controller"
@onready var camera : Camera3D = $"Camera Pivot/Camera Controller/Camera"
@onready var enemy_ray_cast: RayCast3D = $RayCast3D
@onready var health = $HUD/Health
@onready var psi = $HUD/Psi
@onready var stamina = $HUD/Stamina
@onready var gauge_image: TextureRect = $"HUD/HUD control/Gauge Image"
@onready var gauge_timer: Timer = $"Gauge Timer"
#Stats and Moveset
const HEALTH = 1000.0
const ATTACK = 145.0
const DEFENSE = 80.0
const WALK_SPEED = 10.0
const AGILE_SPEED = 30.0
const FIGHT_SPEED = 80.0
const MACH_SPEED = 150.0
const ACCEL = 40.0
const TURN_SPEED = 12.0
const LOOK_SPEED = 8.0
const SHORT_JUMP = 30.0
const HIGH_JUMP = 80.0
const GRAVITY = 10.0
const GAUGE = 1000.0
const STAMINA = 1000.0
const WEAKNESS = ["Curse", "PSI"]
const RESISTANCE = ["Slash", "Fire", "Electric", "Bless"]
const NEW_MOVESET = ["Blast Reign", "Flame Core", "Furalumin", "Armour Burst"]
const ADV_MOVESET = ["God Swipe", "Altar Flare", "Mega E-Go", "Palladia", "Magnus Burst", "Aymrian"]
const PRO_MOVESET = ["Dragon Reign", "Light Monarch", "Platinum Flare", "Virtuous E-Go"]
var camera_input_dir := Vector2.ZERO
var last_dir = Vector3.BACK
var double_jump = false
var gauge = 1
var gauge_ready = true
var gauge_lock = false
var input_buffer_list = []
var selected_enemy: Node3D
var locked_on_enemy: Node3D
func _ready() -> void:
health.init_health(HEALTH)
psi.init_health(GAUGE)
stamina.init_health(STAMINA)
_set_ray_cast_selection()
func _set_ray_cast_selection():
enemy_ray_cast.add_exception(self)
enemy_ray_cast.target_position = Vector3(0, 0, enemy_select_range)
func _input(_event: InputEvent) -> void:
enemy_ray_cast.rotation.x = camera_pivot.rotation.x
enemy_ray_cast.rotation.y = camera_pivot.rotation.y
_check_current_enemy()
if Input.is_action_just_pressed("Lock On Enemy") and not locked_on_enemy and selected_enemy:
locked_on_enemy = selected_enemy
locked_on_enemy.locked_on(true)
elif Input.is_action_just_pressed("Lock On Enemy") and locked_on_enemy:
locked_on_enemy.locked_on(false)
locked_on_enemy = null
func _physics_process(delta: float) -> void:
#Lock on enemy
if locked_on_enemy: _set_lock_on_camera()
else: _camera_control()
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta * GRAVITY
if is_on_floor():
double_jump = false
# Handle jump.
if Input.is_action_just_pressed("Jump-Accept") and is_on_floor():
if gauge == 1:
velocity.y = SHORT_JUMP
else:
velocity.y = HIGH_JUMP
if Input.is_action_just_pressed("Jump-Accept") and not is_on_floor() and double_jump == false:
if gauge == 1:
velocity.y = SHORT_JUMP
else:
velocity.y = HIGH_JUMP
double_jump = true
#Movement including Gauge controller and Camera controller
#Movement inputs
var input_dir := Input.get_vector("Move Left", "Move Right", "Move Forward", "Move Back")
var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
var forward := camera.global_basis.z
var right := camera.global_basis.x
var move_dir := forward * input_dir.y + right * input_dir.x
move_dir.y = 0.0
move_dir = move_dir.normalized()
direction = direction.rotated(Vector3.UP, camera.global_rotation.y).normalized()
#Gauge Controller
if Input.is_action_just_pressed("Change Gear") and gauge < 4 and gauge_ready == true and gauge_lock == false:
gauge_ready = false
gauge_timer.start()
gauge += 1
gauge_image.rotation_degrees -= 90
elif Input.is_action_just_pressed("Change Gear") and gauge == 4 and gauge_ready == true and gauge_lock == false:
gauge_ready = false
gauge_timer.start()
gauge = 1
gauge_image.rotation_degrees -= 90
elif Input.is_action_just_pressed("Change Gear") and gauge == 1 and gauge_ready == true and gauge_lock == true:
gauge_ready = false
gauge_timer.start()
gauge += 1
gauge_image.rotation_degrees -= 90
elif Input.is_action_just_pressed("Change Gear") and gauge <= 2 and gauge_ready == true and gauge_lock == true:
gauge_ready = false
gauge_timer.start()
gauge = 1
gauge_image.rotation_degrees = 0
if Input.is_action_just_pressed("Change Gear") and gauge < 4 and gauge_ready == true and gauge_lock == false:
gauge_ready = false
gauge_timer.start()
gauge += 1
gauge_image.rotation_degrees -= 90
if gauge == 1:
#Neutral Gear
camera_controller.position.y = lerp(camera_controller.position.y, 1.5, delta)
camera_controller.position.z = lerp(camera_controller.position.z, 0.0, delta)
velocity = velocity.move_toward(move_dir * WALK_SPEED, ACCEL * delta)
elif gauge == 2:
#Agile Gear
velocity = velocity.move_toward(move_dir * AGILE_SPEED, ACCEL * delta)
elif gauge == 3:
#Fight Gear
camera_controller.position.x = lerp(camera_controller.position.x, 0.5, delta * 2)
camera_controller.position.y = lerp(camera_controller.position.y, 1.5, delta)
velocity = velocity.move_toward(move_dir * FIGHT_SPEED, ACCEL * delta)
elif gauge == 4:
#Speed Gear
camera_controller.position.x = lerp(camera_controller.position.x, 0.0, delta)
camera_controller.position.y = lerp(camera_controller.position.y, 3.0, delta * 2)
camera_controller.position.z = lerp(camera_controller.position.z, 5.0, delta)
velocity = velocity.move_toward(move_dir * MACH_SPEED, ACCEL * delta)
move_and_slide()
if move_dir.length() > 0.2:
last_dir = move_dir
var target_dir = Vector3.BACK.signed_angle_to(last_dir, Vector3.UP)
ksd_rotat.rotation.y = lerp_angle(ksd_rotat.rotation.y, target_dir, TURN_SPEED * delta)
func _camera_control():
#Camera Rotation for controller Inputs
var axis_dir := Input.get_vector("Look Left", "Look Right", "Look Up", "Look Down")
if axis_dir.length() >= 0.2:
camera_pivot.rotate_y(deg_to_rad(-axis_dir.x * LOOK_SPEED))
camera_controller.rotate_x(deg_to_rad(-axis_dir.y * LOOK_SPEED))
camera_controller.rotation.x = clamp(camera_controller.rotation.x, deg_to_rad(-80.0), deg_to_rad(30.0))
#Stop Z rotation of camera
camera.rotation.z = clamp(camera.rotation.z, 0.0, 0.0)
camera_input_dir = Vector2.ZERO
func _check_current_enemy():
if locked_on_enemy: return
if enemy_ray_cast.is_colliding() and "Enemy" in enemy_ray_cast.get_collider().name:
selected_enemy = enemy_ray_cast.get_collider()
selected_enemy.selected(true)
else:
if selected_enemy:
selected_enemy.selected(false)
selected_enemy = null
func _set_lock_on_camera():
camera_pivot.look_at(locked_on_enemy.global_position)
func _on_gauge_timer_timeout() -> void:
gauge_ready = true
#For the Enemy
extends CharacterBody3D
@onready var label_3d: Label3D = $Label3D
const SPEED = 5.0
const JUMP_VELOCITY = 4.5
func _init() -> void:
add_to_group("enemy")
func _ready() -> void:
selected(false)
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity += get_gravity() * delta
move_and_slide()
func selected(boolean):
label_3d.modulate = Color.WHITE
label_3d.visible = boolean
func lock_on(boolean):
label_3d.modulate = Color.RED
label_3d.visible = boolean