FairyGUI 实现3D UI效果

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/wangjiangrong/article/details/96429081

用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;

猜你喜欢

转载自blog.csdn.net/wangjiangrong/article/details/96429081