Godot Version
4.4.1 stable
Question
I’m trying to use StateCharts as a way to create two different states in an object I want the player to interact with. I have the states working fine but I need to be able to tell what my raycast is looking at. And then be able to press an interact button to then have the object do something. Hard to explain but I will try to show examples below.
This is my objects scene tree.
I have an interaction component that shows UI when put on any object in Godot.
class_name InteractionComponent extends Node
@export var mesh : MeshInstance3D
@export var context : String
@export var override_icon : bool
@export var new_icon : Texture2D
var parent
var highlight_material = preload("res://materials/interactable_highlight.tres")
func _ready() -> void:
parent = get_parent()
connect_parent()
set_default_mesh()
func _process(delta: float) -> void:
pass
func in_range() -> void:
mesh.material_overlay = highlight_material
MessageBus.interaction_focused.emit(context, new_icon, override_icon)
func not_in_range() -> void:
mesh.material_overlay = null
MessageBus.interaction_unfocused.emit()
func on_interact() -> void:
print(parent.name)
func connect_parent() -> void:
parent.add_user_signal("focused")
parent.add_user_signal("unfocused")
parent.add_user_signal("interacted")
parent.connect("focused", Callable(self, "in_range"))
parent.connect("unfocused", Callable(self, "not_in_range"))
parent.connect("interacted", Callable(self, "on_interact"))
func set_default_mesh() -> void:
if mesh:
pass
else:
for i in parent.get_children():
if i is MeshInstance3D:
mesh = i
Code for the InteractionComponent.
This is my raycast code.
func interact_cast() -> void:
var camera = Global.player.CAMERA_CONTROLLER
var space_state = camera.get_world_3d().direct_space_state
var screen_center = get_viewport().size / 2
var origin = camera.project_ray_origin(screen_center)
var end = origin + camera.project_ray_normal(screen_center) * interact_distance
var query = PhysicsRayQueryParameters3D.create(origin, end)
query.collide_with_bodies = true
var result = space_state.intersect_ray(query)
var current_cast_result = result.get("collider")
if current_cast_result != interact_cast_result:
if interact_cast_result and interact_cast_result.has_user_signal("unfocused"):
interact_cast_result.emit_signal("unfocused")
interact_cast_result = current_cast_result
if interact_cast_result and interact_cast_result.has_user_signal("focused"):
interact_cast_result.emit_signal("focused")
func interact() -> void:
if interact_cast_result and interact_cast_result.has_user_signal("interacted"):
interact_cast_result.emit_signal("interacted")
Basically is there a way for me to put what my raycast is looking at in a variable, then using an if statement, have that variable equal the object I want it to (in this case the “generator”), and also have the interact button pressed. This would change the state from “Broken” to “Fixed” but only when I am looking at the generator. Not when I’m looking at something else. Sorry for the bad explaination but all help is greatly appreciated!