Skip to main content

基础组件相关

新建UI对象

通过Hierarchy窗口右键菜单栏/GameObject创建一份新的UI对象:

image.png

选中UI下的复选框,大体分为两块,顶部带有 (VRC) 的四组,均为WorldSDK中VRC官方创建的示例,通过这个创建出来的UI能够直接兼容VRC;其余则是Unity中自带的组件。

如果你需要快速创建一个兼容VRC的UI来测试你的功能,则直接使用带有 (VRC) 的创建示例,否则正常情况下仍建议通过常规顺序来一步步创建你的UI对象,当然,你可以从VRC的创建示例魔改。

如果你在你的场景中首次创建UI对象,那么它不仅会有一个Canvas,还会有一个Event System对象,当然如果只是在vrc,Event System并不重要。

注意事项:

如果你的Scene场景中并没有UI对象,那么你创建的所有UI复选框下的对象,他的层级都是Canvas/xxx  image.png  

如果你的Scene场景中有UI对象,那么你创建的UI复选框下的对象,它会直接在你的UI对象的子层级中的最底层/最下层新建:image.png

一般情况下我们的世界场景中肯定存在多个UI对象,所有我们肯定要避免第二种情况,所以在我们要新建一个UI对象前,请让我们创建一个空对象作为这个新的UI对象的父层级  image.png

Canvas中的组件

Canvas:画布组件,主要用于渲染这个UI
Canvas Scaler:画布分布类自适应组件
RectTransform:UI位置锚点控制相关组件
Graphic Raycaster:射线事件交互组件,(不重要)

EventSystem中的组件(不重要)

玩家输入事件响应系统相关,VRC中会用UI shape脚本代替其作用在ClientSim,所以无需管它。

虽然不重要,只要不管它就行;不要删除!不要删除!不要删除!

SDK相关

VRC UI Shape:可以让玩家可以与UI对象交互的脚本。

此脚本必须添加在Canvas对象(UI对象)中才能起作用;

所有UI对象的Layer必须是非 “UI” 层,不然不起作用;(在UI层除非玩家打开VRChat菜单,否则UI层将阻止玩家交互,除非有特殊需求否则这种效果是不合时宜的:SDK中关于Layer相关使用

Canvas中的RanderMode属性在大多数情况下应该是“World Space” 而并非“Screen Space” ,如果是VR状态下,是不能显示Screen Space下的内容的,如果想实现UI对象一直出现在屏幕中,可以通过GetTrackingData 方法获取本地玩家头部位置与旋转信息实时更新位置,示例代码:

using //

public class TestCanvas : UdonSharpBehaviour
{
    private GameObject currentCanvas;
    [SerializeField] private Vector3 pcOffset = new Vector3(0, 0.1f, 1.5f); // PC玩家的偏移量
    [SerializeField] private Vector3 vrOffset = new Vector3(0, 0.3f, 1.0f); // VR玩家的偏移量

    private void UpdateCanvasPosition() //实时更新函数
  {
    if (currentCanvas != null)
    {
        VRCPlayerApi localPlayer = Networking.LocalPlayer;
        if (localPlayer != null)
        {
            // 获取玩家头部位置和朝向
            Vector3 headPosition = localPlayer.GetTrackingData(VRCPlayerApi.TrackingDataType.Head).position;
            Quaternion headRotation = localPlayer.GetTrackingData(VRCPlayerApi.TrackingDataType.Head).rotation;
            // 偏移量选择
            Vector3 offset = localPlayer.IsUserInVR() ? vrOffset : pcOffset;
            // 计算Canvas的位置和旋转
            Vector3 canvasPosition = headPosition + headRotation * offset;
            // 设置Canvas的位置和旋转
            currentCanvas.transform.position = canvasPosition;
            currentCanvas.transform.rotation = headRotation;
        }
    }
  }

    void Update() //运行
    {
        //逻辑
        UpdateCanvasPosition();
    }
}