问题是,当我使用 RayCast 激活或停用一个立方体时,其他立方体也会被激活。我将它们放在一个组中,我只希望激活我单击的立方体。
事实是,这对我来说似乎非常复杂,因为这是我第一天使用 Godot,而且我来自 Unity,在那里这很容易做到并且工作正常。
这里有一个视频: https://youtu.be/2k7qQWHNvwA
我尝试仅激活使用 _raycast.get_collider() 单击的立方体,并检查带有对撞机的立方体是否位于特定组中。
目标是,当您左键单击立方体时,它会将其透明度更改为完全可见,并在第 1 层发生碰撞,即与玩家碰撞的地方。
右键单击时,透明度会更改,使其不完全可见,并且碰撞层 1 会停用,以便玩家可以通过它。
所有这些仅适用于您单击的立方体,并且仅当它是红色立方体时。
重要提示:Raycast3D 节点位于播放器内的 Camera 节点内,脚本位于 RayCast3D 中。
这里是脚本:
extends RayCast3D
@export var raycast_path: NodePath
@onready var _raycast = get_node_or_null(raycast_path)
func _ready():
pass
func _input(event):
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT && event.pressed:
_handle_left_click()
elif event.button_index == MOUSE_BUTTON_RIGHT && event.pressed:
_handle_right_click()
func _handle_left_click():
if _raycast.is_colliding():
var collider = _raycast.get_collider().owner
if "CuboRojo" in collider.get_groups():
var cubo_rojo = collider as GeometryInstance3D
var material = cubo_rojo.material_override
material.transparency = 0
cubo_rojo.get_node("StaticBody3D").collision_layer = 1 | 2
func _handle_right_click():
if _raycast.is_colliding():
var collider = _raycast.get_collider().owner
if "CuboRojo" in collider.get_groups():
var cubo_rojo = collider as GeometryInstance3D
var material = cubo_rojo.material_override
material.transparency = 1
cubo_rojo.get_node("StaticBody3D").collision_layer = 2
我尝试了很多方法,但所有对象都同时激活。
问题是他们都共享相同的材料。因此,当您修改材质以添加或删除透明度时,更改会反映在共享相同材质的所有立方体中。
更容易掌握的方法是在修改材料之前复制材料:
cubo_rojo.material_override = cubo_rojo.material_override.duplicate()
但是,当然,这意味着您每次都在创建一个新的物质对象。因此,我建议定义具有透明度的第二种材质(也许在脚本中为其导出一个变量,以便您可以在检查器中设置它),并替换该材质而不是修改它。
或者,您可以存储元数据变量来跟踪您是否已经复制了材料:
if not cubo_rojo.get_meta("material_duplicated", false):
cubo_rojo.material_override = cubo_rojo.material_override.duplicate()
cubo_rojo.set_meta("material_duplicated", true)
这里我们使用
get_meta
从 cubo_rojo
读取名为 "material_duplicated"
的元数据变量,如果元数据变量不存在(这将是起始情况),那么它将返回 false
(我们指定的)。当然,我们使用 set_meta
来写入元数据变量。
我还想指出,使用
collider.is_in_group("CuboRojo")
比 "CuboRojo" in collider.get_groups()
或 collider.get_groups().has("CuboRojo")
更有效。