DaveTheCoder
Thanks for replying. As can be seen in the Scene Tree, the Tongue has a Collision Shape (a small dot in the middle of the Tongue...). When a collision is detected, a signal is sent to the Script. If the collision is with a Hole (an equally small dot in its centre...), The piece can be fixed in position (Connect flag is true...) so can no longer be Dragged, and will turn Red. This is where the angle of the other piece needs detecting, so that the Connecting piece can align itself. The angle difference can be any of the eight 45° angles that the pieces can adopt. Here's all the code...
extends Node3D
const RAY_LENGTH := 1000
var lv_dragging : bool = false
var lv_conn_flag : bool = false
var lv_lock : bool = false
var lv_mous_posi : Vector3 = Vector3.ZERO
var lv_offset : Vector3 = Vector3.ZERO
var lv_connect : Vector3 = Vector3.ZERO
var lv_mesh_node: MeshInstance3D
var lv_chil_labe: Label3D
var lv_tong
@onready var lv_labe = ""
@onready var lv_came_uppe_l = $"../Scene_Stuff/Came_Uppe_L"
@onready var lv_came_uppe_r = $"../Scene_Stuff/Came_Uppe_R"
@onready var lv_came_lowe_l = $"../Scene_Stuff/Came_Lowe_L"
@onready var lv_came_lowe_r = $"../Scene_Stuff/Came_Lowe_R"
@onready var lv_came_over_head = $"../Scene_Stuff/Came_Over_Head"
@onready var lv_came_3d = $"../Scene_Stuff/Came_3D"
# Called when the node enters the scene tree for the first time.
func _ready():
for lv_child in self.get_children():
if lv_child is MeshInstance3D:
lv_mesh_node = lv_child
for lv_child_2 in lv_mesh_node.get_children():
if lv_child_2 is Label3D:
lv_chil_labe = lv_child_2
lv_came_lowe_l.current = true
func _process(_delta):
if Input.is_action_just_released("Came_Uppe_L") :
lv_came_uppe_l.current = true
if Input.is_action_just_released("Came_Uppe_R") :
lv_came_uppe_r.current = true
if Input.is_action_just_released("Came_Lowe_L") :
lv_came_lowe_l.current = true
if Input.is_action_just_released("Came_Lowe_R") :
lv_came_lowe_r.current = true
if Input.is_action_just_released("Came_Over_Head") :
lv_came_over_head.current = true
if Input.is_action_just_released("Came_3D") :
lv_came_3d.current = true
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(_delta):
if lv_dragging == true:
if get_mouse_world_position() != null:
lv_offset = get_mouse_world_position()
var lv_x = lv_offset.x
var lv_z = lv_offset.z
lv_mesh_node.global_position = Vector3(lv_x,0.0,lv_z)
func _on_static_body_3d_input_event(_camera, event, _event_position, _normal, _shape_idx):
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed():
print("Dragging")
if lv_dragging == false:
if lv_lock == false:
lv_dragging = true
lv_conn_flag = false
else:
print("Over")
lv_dragging = false
if lv_conn_flag == true:
lv_lock = true
print("Locked")
lv_chil_labe.modulate = Color(1.0,0.0,0.0,1)
if event.button_index == MOUSE_BUTTON_RIGHT and event.is_pressed():
if lv_lock == true:
lv_lock = false
lv_conn_flag = false
print("Unlocked")
lv_chil_labe.modulate = Color(0.0,1.0,0.0,1)
else:
print("Rotate")
lv_dragging = false
if lv_conn_flag == true:
lv_lock = true
lv_mesh_node.rotate_y(deg_to_rad(int(45)))
func get_mouse_world_position(collision_mask: int = 0b00000000_00000000_00000000_00000001):
var raycast_result = _do_raycast_on_mouse_position(collision_mask)
if raycast_result:
return raycast_result.position
# Returns raycast result after it hits an object in the world.
# @return Dictionary or null
func _do_raycast_on_mouse_position(collision_mask: int = 0b00000000_00000000_00000000_00000001):
# Raycast related code
var space_state = get_world_3d().direct_space_state
var cam = get_viewport().get_camera_3d()
var mousepos = get_viewport().get_mouse_position()
var origin = cam.project_ray_origin(mousepos)
var end = origin + cam.project_ray_normal(mousepos) * RAY_LENGTH
var query = PhysicsRayQueryParameters3D.create(origin, end)
query.collide_with_areas = true
query.collision_mask = collision_mask
var result = space_state.intersect_ray(query) # raycast result
return result
func _on_tongue_area_shape_entered(_area_rid, area, _area_shape_index, _local_shape_index):
if str(area.name)[0] == "H":
lv_conn_flag = true
func _on_tongue_area_shape_exited(_area_rid, _area, _area_shape_index, _local_shape_index):
lv_conn_flag = false
lv_lock = false
func _on_area_3d_area_shape_entered(_area_rid, _area, _area_shape_index, _local_shape_index):
print("Touched")
print("Degrees : ",self.global_transform.basis.y)
Is any more information needed..?