Godot Version
Godot 4.6 Stable
Question
I'm working on a survival horror game, right now mostly doing the movement system for the playable character.
I have the basic stuff already in a state machine, iddle, walk, aim, and basic interactions.
What I have right now with the interaction system is a set of Area3D nodes with a collision area that triggers the player ability to interact with an object, this is so you get the classic thing of inspecting the world (Think SH3 It’s Bread meme I guess).
It’s in this way, a generic Interactable Area3D node that is instanced into a 3D object and has a collision Shape, with this code:
extends Area3D
@export var interact_name: String = “”
@export var is_interactable: bool = true
var interact: Callable = func():
pass
The interact_name being what I write the text in.
That Area3D is then instanced into an object in the world with this code:
extends CSGBox3D
@onready var interactable: Area3D = $Interactable
func _ready() → void:
interactable.interact = _on_interact
func _on_interact():
print("this is a box")
All of it then works within a code inside a node in the player controller, said controller formatted this way:
CharacterBody3D -Lilith Player Controller
-CollisionShape3D
-MeshRoot (Just the model and animation tree)
-Camera (Camera System and Code)
-StateMachine (A normal node with the state machine script with a bunch of nodes with script for each movement state like fall, idle, walk, run, etc).
-Interaction Component (It has an Area3D for the interaction range and the script to trigger it and label node to work the inspecting action).
The Interaction component script for inspecting things is:
extends Node3D
@onready var interact_label: Label = $“Interact Label”
var current_interactions :=
var can_interact := true
func _input(event: InputEvent) → void:
if event.is_action_pressed(“interact”) and can_interact:
if current_interactions:
can_interact = false
Interact_label_pause()
can_interact = true
else:
interact_label.hide()
else:
pass
func Interact_label_pause():
if not interact_label.visible:
interact_label.text = current_interactions[0].interact_name
interact_label.show()
await current_interactions[0].interact.call()
get_tree().paused = true
else:
interact_label.hide()
get_tree().paused = false
func _sort_by_nearest(area1, area2):
var area1_dist = global_position.distance_to(area1.global_position)
var area2_dist = global_position.distance_to(area2.global_position)
return area1_dist < area2_dist
func _on_interaction_range_area_entered(area: Area3D) → void:
current_interactions.push_back(area)
func _on_interaction_range_area_exited(area: Area3D) → void:
current_interactions.erase(area)
What I want to do is now add to that Interaction Component so that there are other types of interactions, in this case, the character being able to jump down platforms or climp up.
I tried to recreate the inspection system by creating a new instance called Movement Interaction with this code:
extends Area3D
@export var power_vector : Vector3
@export var is_interactable: bool = true
var interact_movement: Callable = func():
pass
And I have this invisible wall with a trigger similar to the 3D objects you inspect:
extends StaticBody3D
@onready var interactable: Area3D =$“Movement Interaction”
func _ready() → void:
interactable.interact_movement = _on_interact
func _on_interact():
print("You will jump down")
The print is mostly to know that the script is actually triggering.
Now I’ve changed the main Interaction compenent script to work with everything… but I have no clue what to do now, I don’t know what I should make the function be so that it calls the movement interaction.
extends Node3D
@onready var interact_label: Label = $“Interact Label”
var current_interactions :=
var can_interact := true
var can_move := true
func _input(event: InputEvent) → void:
if event.is_action_pressed(“interact”) and can_interact:
if current_interactions:
can_interact = false
can_move = false
Interact_label_pause()
can_interact = true
can_move = true
else:
interact_label.hide()
if event.is_action_pressed("interact") and can_move:
if current_interactions:
can_move = false
can_interact = false
Interact_Movement()
can_interact = true
can_move = true
else:
pass
func Interact_Movement():
if
pass
func Interact_label_pause():
if not interact_label.visible:
interact_label.text = current_interactions[0].interact_name
interact_label.show()
await current_interactions[0].interact.call()
get_tree().paused = true
else:
interact_label.hide()
get_tree().paused = false
func _sort_by_nearest(area1, area2):
var area1_dist = global_position.distance_to(area1.global_position)
var area2_dist = global_position.distance_to(area2.global_position)
return area1_dist < area2_dist
func _on_interaction_range_area_entered(area: Area3D) → void:
current_interactions.push_back(area)
func _on_interaction_range_area_exited(area: Area3D) → void:
current_interactions.erase(area)
I have no clue what to do with the interact movement function and how to call it to call the vector movement of the Movement Interaction node, so that you move in the vector3 that is cuztomized for each type of movement.
The idea is that eventually I will also attach the animation depending on what type of movement it is and I made the Vector3 a export var so that I can make the movement change depending on what is required. Just so I don’t have to create too many scripts.