FairyGUI 实现3D UI效果

it2022-05-05  160

用FairyGUI的时候,美术想做一些3D效果的UI,但是在编辑器上不支持,需要我们Unity这边帮助实现,当时的大体思路和之前做投影效果类似,通过自定义数据这块在Unity这对GObject进行修改。https://blog.csdn.net/wangjiangrong/article/details/95341797

但是FairyGUI的默认摄像机Stage Camera是正交摄像机,实现了GObject的旋转之后并没有3D的效果,需要使用摄像机的透视模式来处理。关于如何保证UI正好完整显示在屏幕上,在上一篇关于摄像机Size的问题上也进行了分析https://blog.csdn.net/wangjiangrong/article/details/96338240

所以,我们需要做的就是,首先修改好Stage Camera,然后美术在Unity通过旋转2DUI达到其预期要的3D效果后,纪录其旋转值,通过FairyGUI那给需要3D效果的UI,在自定义属性处添加旋转值,最后我们在解析的时候对配置了旋转值的物体进行旋转即可。

效果如下:

FairGUI,给左边的按钮配置了UIRotation:0,-30,0|PositionZ:-50(旋转角度以及Z轴),右边的按钮配置了UIRotation:0,30,0

Unity解析后显示如下

可以看见有了3D的效果,虽然丑了点=。=

下面进行设置以及代码的修改:

首先将Stage Camera的Projection改为Perspective,Field of View设置为90。同时对StageCamera.cs脚本进行修改,我们将摄像机的Z轴设置为-cachedCamera.orthographicSize,HitTestContext.cachedMainCamera设置为自己(不做这步操作会导致UI触电出问题,无法点击),生成Stage Camera的时候修改对应配置。

using UnityEngine; namespace FairyGUI { /// <summary> /// Stage Camera is an orthographic camera for UI rendering. /// </summary> [ExecuteInEditMode] [AddComponentMenu("FairyGUI/UI Camera")] public class StageCamera : MonoBehaviour { ...... void OnScreenSizeChanged(int newWidth, int newHeight) { ...... if (constantSize) { cachedCamera.orthographicSize = DefaultCameraSize; upp = cachedCamera.orthographicSize * 2 / screenHeight; } else { upp = 0.02f; cachedCamera.orthographicSize = screenHeight / 2 * UnitsPerPixel; } cachedTransform.localPosition = new Vector3(cachedCamera.orthographicSize * screenWidth / screenHeight, -cachedCamera.orthographicSize, -cachedCamera.orthographicSize); ...... } /// <summary> /// Check if there is a stage camera in the scene. If none, create one. /// </summary> public static void CheckMainCamera() { ...... //HitTestContext.cachedMainCamera = Camera.main; HitTestContext.cachedMainCamera = main; } /// <param name="name"></param> /// <param name="cullingMask"></param> /// <returns></returns> public static Camera CreateCamera(string name, int cullingMask) { ...... //camera.orthographic = true; camera.orthographic = false; camera.orthographicSize = DefaultCameraSize; //camera.nearClipPlane = -30; //camera.farClipPlane = 30; camera.farClipPlane = DefaultCameraSize + 1; ...... } } }

然后在之前我们解析投影新增的GObject.cs上添加解析自定义旋转(UIRotation)与Z轴(PositionZ)的代码,如下

using UnityEngine; using System; namespace FairyGUI { public partial class GObject : EventDispatcher { ...... bool mIs3DUI = false; Vector3 mUIRotation = Vector3.zero; float mPositionZ = 0; public bool Is3DUI { get { return mIs3DUI; } } public Vector3 UIRotation { get { return mUIRotation; } } public float PositionZ { get { return mPositionZ; } } //call in AnalyUserDefineData public virtual void CustomAction() { if (data != null && mIs3DUI && displayObject != null) { displayObject.cachedTransform.localEulerAngles = mUIRotation; _z = mPositionZ; } } //call in Setup_AfterAdd public void AnalyUserDefineData(object data) { if (data != null && !"".Equals(data.ToString())) { string[] args = data.ToString().Split('|'); foreach(string arg in args) { string[] keyvalue = arg.Split(':'); if (keyvalue.Length != 2) { continue; } ...... if (keyvalue[0].Equals("UIRotation")) { mIs3DUI = true; string[] array = keyvalue[1].Split(','); mUIRotation = new Vector3(float.Parse(array[0]), float.Parse(array[1]), float.Parse(array[2])); } if (keyvalue[0].Equals("PositionZ")) { mPositionZ = float.Parse(keyvalue[1]); } } CustomAction(); } } } }

最后还需要注意的是,需要设置RenderMode为WorldSpace,否则一样会影响UI的触电导致无法点击。

果然用的UIPanel则直接在UIPanel上设置,用GRoot的话初始化的时候设置

GRoot.inst.container.renderMode = RenderMode.WorldSpace;

 


最新回复(0)