我在 Raycast3D 在 Godot 中选择一个对象时遇到问题

问题描述 投票:0回答:1

问题是,当我使用 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

我尝试了很多方法,但所有对象都同时激活。

raycasting godot4
1个回答
0
投票

问题是他们都共享相同的材料。因此,当您修改材质以添加或删除透明度时,更改会反映在共享相同材质的所有立方体中。

更容易掌握的方法是在修改材料之前复制材料:

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")
更有效。

© www.soinside.com 2019 - 2024. All rights reserved.