基础组件相关
新建UI对象
通过Hierarchy窗口右键或菜单栏/GameObject创建一份新的UI对象:
选中UI下的复选框,大体分为两块,顶部带有 (VRC) 的四组,均为WorldSDK中VRC官方创建的示例,通过这个创建出来的UI能够直接兼容VRC;其余则是Unity中自带的组件。
如果你需要快速创建一个兼容VRC的UI来测试你的功能,则直接使用带有 (VRC) 的创建示例,否则正常情况下仍建议通过常规顺序来一步步创建你的UI对象,当然,你可以从VRC的创建示例魔改。
如果你在你的场景中首次创建UI对象,那么它不仅会有一个Canvas,还会有一个Event System对象,当然如果只是在vrc,Event System并不重要。
注意事项:
如果你的Scene场景中并没有UI对象,那么你创建的所有UI复选框下的对象,他的层级都是Canvas/xxx ;
如果你的Scene场景中有UI对象,那么你创建的UI复选框下的对象,它会直接在你的UI对象的子层级中的最底层/最下层新建:
一般情况下我们的世界场景中肯定存在多个UI对象,所有我们肯定要避免第二种情况,所以在我们要新建一个UI对象前,请让我们创建一个空对象作为这个新的UI对象的父层级 。
Unity UI如果是在Hierarchy中同级渲染不同控件,遵循最上的先渲染;
Canvas中的组件
Canvas:画布组件,主要用于渲染这个UI
一个Canvas组件就负责渲染自己的所有UI子对象,如果你的UI对象(控件)的父对象不是一个Canvas,那它大概率是出现问题的;Canvas组件提供几个参数可以调整与修改我们的UI渲染方式:
- RanderMode:控制着这个UI的渲染模式
- Screen Space - Overlay:屏幕空间覆盖,UI始终在前
- Screen Space - Camera:屏幕空间摄像机,场景中的3D物体是可以被渲染在UI前的
- World Space:世界空间,完全遵循3D世界,可以把这个UI看成这个3D世界的一个3D物品(VRC中最常用的渲染模式)
- Pixel Perfect:无锯齿精准渲染(屏幕空间模式下可被启用)
- Sort Order:场景中存在多个Canvas,可以通过此项指定Canvas的排序层,数字越低越先被渲染(屏幕空间覆盖模式下选项)
- Target Display:渲染到目标设备(屏幕空间覆盖模式下选项,不重要)
- Render Camera:指定渲染UI的摄像机(屏幕空间摄像机模式下选项,如果默认不填则效果依旧遵循覆盖模式)
- Plane Distance:UI在摄像机前方的z轴距离(指定摄像机后开启此选项,如果物体在这个数值前,那么就会出现物体渲染在UI前的效果)
- Sorting Layer:排序层,新加的排序层默认都会比Default层高,遵循层级越低越先被渲染,(屏幕空间摄像机与世界空间下选项)
- Order in Layer:如果在同一排序层的渲染排序,数字越低越先被渲染(屏幕空间摄像机与世界空间下选项)
- Event Camera:指定用于处理UI事件的摄像机(世界空间下选项,VRC中可以默认不填并不会影响效果,独立开发如果不填则无法正常注册UI事件)
Canvas Scaler:画布分辨率自适应组件
- Constant Pixel Size:恒定像素大小模式,不论屏幕大小,UI始终保持相同像素大小(UI大小始终是这么大)
- Scale With Screen Size:根据屏幕尺寸缩放模式,随着屏幕尺寸放大缩小
- Constant Physical Size:恒定物理大小模式,不论屏幕大小和分辨率,UI始终保持相同物理大小
World Space下的两个参数作用:
- Dynamic Pixels Per Unit:动态创建的位图单位像素密度(例如Text组件创建的文本,默认为1文字很糊,一般5-10作用为最优;不要过大,如果过大位图会自动变小)
- Reference Pixels Per Unit:每单位的参考像素,默认1个单位对应100像素,除非有特殊需求否则也不用动此参数
此组件就是设定在Screen Space的渲染模式下,通过算法动态调整UI大小来适配不同大小与分辨率的显示器;所以在VRC中并不重要,默认World Space的渲染模式下不会去调整这个,因为分辨率(UI大小)是固定的,我们一般只需要通过调整RectTransform达到效果就行;
RectTransform:UI位置锚点控制相关组件
RectTransform意为矩阵变换,它继承自Transform,在Transform只有位置角度缩放信息的前提下,加入了中心点,锚点,长宽等矩阵相关信息,为了更方便的控制其大小以及分辨率自适应相关。
- Pivot:中心点,取值范围一般为0 - 1,xy都为0.5就是默认这个UI的中心就是中心点
- PosX/Y/Z:中心点位置信息(相对于锚点)
- Width/Height:矩形的宽高信息
- Rotation/Scale:以中心点旋转与缩放信息
- Anchors:锚位置,取值范围一般为0 - 1;一般或默认设置锚都是以点(锚点)的形式存在,当然也可以把它设置成锚范围,这样PosX/Y/Z的位置信息就会变成宽高左边右边与锚范围的宽高左边右边的距离信息。
PosX/Y/Z信息
Blueprint Mode:启用后在进行旋转缩放是只会影响矩形内的内容,而不会影响矩形本身
Raw Edit Mode:启用后改变中心点和锚点都不会改变矩形位置
Graphic Raycaster:射线事件交互组件,(不重要)
通过图像射线检测玩家与UI的交互,在VRC中只要有UI Shape组件存在就有交互,所以这个不重要。
- Ignore Reversed Graphics:是否忽略掉反转图形
- Blocking Objects:射线被阻挡的碰撞器对象(屏幕空间覆盖模式下无效)
- Blocking Mask:射线被阻挡的层(屏幕空间覆盖模式下无效)
EventSystem中的组件(不重要)
玩家输入事件响应系统相关,在组件不存在的情况下只有Canvas中有VRC UI Shape组件,Client Simulator依旧能够响应玩家输入和事件。
虽然不重要,只要不管它就行;不要删除!不要删除!不要删除!
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
方法获取本地玩家头部位置与旋转信息实时更新位置来实时更新Canvas或UI父对象位置,示例代码:
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();
}
}
No Comments