马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?注册帐号
x
现在的UI选型,虽然UGUI明显是优于NGUI的,但万一遇到了和未开源的C++部分相关的问题,就只能等待官方解决,开发者自己则毫无办法。
不过考虑到这种BUG无非和Unity引擎的BUG一样,因为自己改不了就不用,那那干脆就别用Unity了??悸堑経GUI带来的好处这种程度的限制是无所谓的,又不是不给解决。 不过像那些与其说是BUG,不如说是设计缺陷的地方就不好办了。目前发现的只有一处: 当组件Z轴不为0,旋转角不为90的整数倍的时候,组件的分批Bounds检测会失效。 (并不是不分批,而是分批时相当于所有组件都重叠在一起,会严格按照Hierarchy顺序渲染,这样会产生大量额外DrawCall) 组件被中间的Text分隔开了 将Text和Image分隔开后就能正确合批。 但这样父子级关系被基本废掉了,处理Cell尤其不便。简单界面尚可,复杂界面则是灾难——至少是不如NGUI的depth机制的。 这不仅仅会影响3D界面,还会影响到界面动画里的旋转效果。
因为其他地方都不能改,看上去也只能在材质上做文章了。
Shader部分简单增加一个属性,并且和vertex mul就好了。 其实除了加uniform属性外,还有个办法是将变换矩阵存入顶点数据内,但这样做会增加合批时的负担??悸堑叫话愣际切鼋缑?,直接改材质会更好一点。 但因为UI的所有材质都是共享的,而不同的3D界面旋转方向不同,必须让不同界面使用不同的材质副本,所以必须在运行期间批量设置组件的material属性。 除了默认材质外,还可能有自定义材质。而自定义材质即使加上了“_TransformModifier”参数,复制也依然必须进行,这是为了避免影响到其他共享材质的组件?;剐枰米值淅幢苊庵馗锤粗撇闹?。 [AppleScript] 纯文本查看 复制代码 foreach (Graphic g in graphics)
{
Material curMat = g.material;
if (curMat == g.defaultMaterial)
{
g.material = modifierMat;
}
else
{
Material m;
customMatDict.TryGetValue(curMat, out m);
if (m == null)
{
m = GameObject.Instantiate(curMat);
customMatDict.Add(curMat, m);
}
g.material = m;
}
}
处理材质只需要在开始的时候做一次,而后面可能对变换矩阵做多次修改。所以需要拆分到两个函数。 [AppleScript] 纯文本查看 复制代码 static readonly int propertyNameHash = Shader.PropertyToID("_TransformModifier");
public void Refresh()
{
Matrix4x4 matrix = Matrix4x4.TRS(position, Quaternion.Euler(rotation), Vector3.one);
if (modifierMat != null)
{
modifierMat .SetMatrix(propertyNameHash, matrix);
}
foreach (var m in customMatDict)
{
if (m.Value != null)
m.Value.SetMatrix(propertyNameHash, matrix);
}
}
修改material属性虽然比较安全,但是如果你使用了Mask这类自身也需要复制材质的功能,实际显示用的材质会和material属性的材质不一样,这样在之后修改材质的变换矩阵就没用了。 要解决这个问题,就需要直接修改materialForRendering属性而非material。但materialForRendering获取时成本较高,一刀切并不合适,所以加了一个参数来控制。 (此外,RectMask2D由于不会复制材质,并没有上述问题。所以用RectMask2D来代替Mask是更好的办法) 然而这东西最后还有一个问题没解决:点击区域。 因为只是看上去旋转了,实际上Transform都还是原样,点击区域自然也没变。本来是想通过修改GraphicRaycaster解决的,看了看有点麻烦就先算了。 ——本来我关心的也只是界面的3D动画。
创建一个只负责检测点击的空界面,然后直接3D旋转到同样角度倒也是可以凑合实现的。
知乎@flashyiyi
|