提问人:TheZombrex 提问时间:9/18/2023 最后编辑:TheZombrex 更新时间:9/30/2023 访问量:148
我在 Raycast3D 中选择一个对象时遇到问题
Im having problems with Raycast3D selecting one object in Godot
问:
问题是,当我使用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)
这里我们用来读取一个元数据变量 called ,如果元数据变量不存在(这将是起始情况),那么它将返回(我们指定)。当然,我们用来编写元数据变量。get_meta
cubo_rojo
"material_duplicated"
false
set_meta
我还想指出,使用将比 或 更有效。collider.is_in_group("CuboRojo")
"CuboRojo" in collider.get_groups()
collider.get_groups().has("CuboRojo")
补遗
当我写下答案时,这逃脱了我的脑海。
您可以将 s(例如材质)标记为与场景的每个实例重复,而不是重复使用。为此,请将 的属性设置为 。Resource
resource_local_to_scene
Resource
true
评论