Pesquisar este blog

PLAYER COM RAYCAST - CAMERA

 extends CharacterBody3D


var pegou = 0 

const SPEED = 5.0

const JUMP_VELOCITY = 4.5

const MOUSE_SENSITIVITY = 0.003


@onready var camera_3d: Camera3D = $Camera3D

@onready var ray_cast_3d: RayCast3D = $Camera3D/RayCast3D

@onready var hold_position: Marker3D = $Camera3D/HoldPosition

@onready var label: Label = $Label


const MIN_PITCH = deg_to_rad(-80.0)

const MAX_PITCH = deg_to_rad(80.0)


var camera_pitch: float = 0.0

var last_detected_object: Object = null


# Lista de objetos que você pode SEGURAR (ficam na mão)

var objetos_para_segurar: Array[String] = [

"caixa",

"caixa2",

"Cadeira",

"Livro"

]


# Lista de objetos que SUMEM ao pegar (Coletáveis)

var objetos_para_coletar: Array[String] = [

"cesta",

"chave",

"lanterna"

]


# Variável para armazenar o objeto que está segurando

var held_object: RigidBody3D = null

const HOLD_STRENGTH: float = 20.0 # Força de atração do objeto para a mão


func _ready() -> void:

Input.mouse_mode = Input.MOUSE_MODE_CAPTURED

# AJUSTES PARA SUBIR RAMPAS / DIAGONAIS COM FLUIDEZ

floor_stop_on_slope = true

floor_max_angle = deg_to_rad(90.0) # Ângulo máximo da rampa/diagonal (45 graus)

floor_snap_length = 0.2 # Mantém o jogador "grudado" ao subir/descer


func _unhandled_input(event: InputEvent) -> void:

if event is InputEventMouseMotion:

rotate_y(-event.relative.x * MOUSE_SENSITIVITY)

camera_pitch -= event.relative.y * MOUSE_SENSITIVITY

camera_pitch = clamp(camera_pitch, MIN_PITCH, MAX_PITCH)

camera_3d.rotation.x = camera_pitch

if event.is_action_pressed("ui_cancel"):

Input.mouse_mode = Input.MOUSE_MODE_VISIBLE


func _physics_process(delta: float) -> void:

if not is_on_floor():

velocity += get_gravity() * delta


if Input.is_action_just_pressed("ui_accept") and is_on_floor():

velocity.y = JUMP_VELOCITY


var input_dir := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")

# Direção calculada considerando a rotação da câmera (permite andar/subir em diagonais)

var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()

if direction:

velocity.x = direction.x * SPEED

velocity.z = direction.z * SPEED

else:

velocity.x = move_toward(velocity.x, 0, SPEED * delta * 10.0)

velocity.z = move_toward(velocity.z, 0, SPEED * delta * 10.0)


move_and_slide()

# Checa a colisão para atualizar o Label

_check_raycast_collision()

# Ação de Interagir (Pressionar a tecla E)

if Input.is_action_just_pressed("interact"):

if held_object == null:

_interact_with_object()

else:

_drop_object()

# Atualiza a posição do objeto segurado com física

_move_held_object(delta)


func _check_raycast_collision() -> void:

if held_object != null:

return


if ray_cast_3d.is_colliding():

var collider = ray_cast_3d.get_collider()

if is_instance_valid(collider):

if collider.name in objetos_para_segurar or collider.name in objetos_para_coletar:

if collider != last_detected_object:

last_detected_object = collider

print("Olhando para: ", collider.name)

label.text = collider.name

else:

last_detected_object = null

label.text = ""

else:

last_detected_object = null

label.text = ""

else:

last_detected_object = null

label.text = ""


func _interact_with_object() -> void:

if ray_cast_3d.is_colliding():

var collider = ray_cast_3d.get_collider()

if not is_instance_valid(collider):

return

if collider.name in objetos_para_coletar:

var nome_do_item = collider.name

Global.adicionar_item(nome_do_item)

label.text = ""

last_detected_object = null

collider.queue_free()

return


if collider is RigidBody3D and collider.name in objetos_para_segurar:

held_object = collider

held_object.linear_velocity = Vector3.ZERO

print("Pegou o objeto: ", held_object.name)

label.text = "Pressione E para soltar " + held_object.name


func _drop_object() -> void:

if is_instance_valid(held_object):

print("Soltou o objeto: ", held_object.name)

held_object = null

label.text = ""


func _move_held_object(_delta: float) -> void:

if held_object != null:

if not is_instance_valid(held_object):

held_object = null

label.text = ""

return


var target_pos = hold_position.global_position

var current_pos = held_object.global_position

var diff = target_pos - current_pos

held_object.linear_velocity = diff * HOLD_STRENGTH