我正在尝试将 Unity3D 的 UIToolkit 与 Visual Scripting Graph 结合使用...
通常,我可以查询正确的元素,然后将必要的函数添加到回调中...但是,由于我是可视化脚本的新手,我不确定如何实现这一点。我已经隔离了按钮的“可点击”对象,但我不确定如何在图中分配后续执行。
通常在代码中,我会做类似的事情
clickable.clicked += ExampleFunction();
我在图中弄乱的是如何访问“.clicked”部分。我可以获得正确的按钮元素,并且可以隔离其可点击属性,但我无法弄清楚如何分配某种功能来对单击的按钮做出反应。
我可以使用自定义节点来完成这项工作,但如果可能的话,我正在寻找一种使用内置节点来完成此操作的方法。
好吧...我必须编写一个自定义节点,但我想通了。这是解决方案的图表。
您必须从附加到的任何游戏对象中获取 UIDocument...然后您需要获取根视觉元素,不要克隆或实例化它。然后,您需要使用您在 UI 构建器中指定的名称来查询所需的按钮。如果您使用 U Query Extensions 节点会更容易...之后,我只是制作了一个自定义节点来订阅该功能。我不熟悉执行此操作的任何节点。
这是“订阅开始结果”节点代码:
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;
public class SubscribeStartResult : Unit
{
[DoNotSerialize]
[PortLabelHidden]
public ControlInput inputTrigger;
[DoNotSerialize]
[PortLabelHidden]
public ValueInput element;
protected override void Definition()
{
element = ValueInput<Button>("element");
inputTrigger = ControlInput("inputTrigger", (flow) =>
{
flow.GetValue<Button>(element).clicked += () =>
{
Debug.Log("Button clicked");
};
return null;
});
}
}
通过此设置,在播放模式下单击“开始按钮”将在控制台中记录“单击按钮”。
“返回 null;”线是 lambda 的产物。如果该节点有后续事件,则需要继续控制流...否则,这种节点和代码的组合允许您使用可视化脚本图为 UI Builder 元素分配回调。
这是更新版本。它可以订阅按钮并将其连接到特定游戏对象上的任何自定义事件。更通用。
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;
[UnitTitle("Subscribe UI Button")]
[UnitCategory("Artokarsus")]
public class SubscribeUIButton : Unit
{
[DoNotSerialize]
[PortLabelHidden]
public ControlInput inputTrigger;
[DoNotSerialize]
public ControlOutput outputTrigger;
[DoNotSerialize]
//[PortLabelHidden]
public ValueInput element;
[DoNotSerialize]
public ValueInput gameObject;
[DoNotSerialize]
public ValueInput eventName;
protected override void Definition()
{
inputTrigger = ControlInput("inputTrigger", TriggerUnityEvent);
outputTrigger = ControlOutput("");
element = ValueInput<Button>("Button");
gameObject = ValueInput<GameObject>("target");
eventName = ValueInput<string>("Name", string.Empty);
Requirement(element, inputTrigger);
Requirement(eventName, inputTrigger);
Requirement(gameObject, inputTrigger);
Succession(inputTrigger, outputTrigger);
}
private ControlOutput TriggerUnityEvent(Flow flow)
{
GameObject targetGameObject = flow.GetValue<GameObject>(gameObject);
string name = flow.GetValue<string>(eventName);
flow.GetValue<Button>(element).clicked += () =>
{
CustomEvent.Trigger(targetGameObject, name);
};
return outputTrigger;
}
}