Unity + NGUI 实现人物头顶UI的信息展示

摘要:
3.在相应目录下创建一个架空UI预设:为了方便测试,一个好的UI预设也放在资源下:需要注意的是,这个预设没有面板,因为希望游戏中显示的所有角色的架空UI信息都可以在同一面板下管理。

1、思路:

  (1)信息数据:需要展示属性信息

  (2)信息的展示:负责显示UI属性信息

  (3)UI的跟随:负责实现UI对人物的跟随

  (4)UI的管理:负责对UI进行创建于回收,游戏中需要用到UI的地方都是与该脚本的交互。

2、将需要用到的UI资源打到一个图集中,以免出现大量人物的时候图集穿插造成不良的影响。

3、创建一个头顶UI预设,当道对应的目录下面:

Unity + NGUI 实现人物头顶UI的信息展示第1张

Unity + NGUI 实现人物头顶UI的信息展示第2张

为了测试的方便,在Resources下面也放一个做好的UI预设:

Unity + NGUI 实现人物头顶UI的信息展示第3张

需要注意的是,做的这个预设是不带Panel的,因为希望可以把游戏展示的所有人物头顶UI信息放到同一个Panel下管理。

4、创建一个Panel,用来管理头顶的UI信息:

Unity + NGUI 实现人物头顶UI的信息展示第4张

5、UI跟随脚本:

using UnityEngine;


/// <summary>
/// 2DUI跟随3D物体
/// </summary>
public class UIFollow3DPosition : MonoBehaviour
{
    public Transform targetTrans;           //2DUI需要跟随的3D目标
    public Camera targetCa;                 //照射的3D目标的摄像机
    public Vector3 offsetPos;               //2DUI需要在3D目标点的基础上做出的偏移量
    public float dis;                       //3D目标点与摄像机之间的距离,为了实现:3D目标点摄像机机发生变化的时候2DUI也跟随发生变化
    public float ratio;                     //2DUI的缩放比例                   

    [HideInInspector]
    public bool isAutoScale = false;        //控制2DUI是否发生缩放

    public const float FarDistance = 40f;   //3D目标点与摄像机的最大距离
    public const float NearDistance = 6.5f; //3D目标点与摄像机的最小距离
    public static Vector3 MaxScale = Vector3.one;
    public static Vector3 MinScale = new Vector3(0.5f, 0.5f, 0.5f);

    private Camera uiCa;                    //NGUI摄像机
    Transform selfTrans;                    //2DUI,因为该脚本是挂在2DUI上的
    GameObject selfObj;                     //2DUI
    Vector3 screenPos;                      //2DUI的屏幕坐标
    Vector3 curPos;                         //2DUI的世界坐标
    Vector3 backPos = new Vector3(3000, 0, 0);

    public Transform cachedTransform
    {
        get
        {
            if (trans == null)
                trans = transform;
            return trans;
        }
    }
    private Transform trans;

    void Awake()
    {
        selfTrans = transform;
        selfObj = gameObject;
        uiCa = UICamera.first.cachedCamera; 
    }
    public void QuickUpdate()
    {
        LateUpdate();
    }
    void LateUpdate()
    {
        if (targetTrans != null && targetCa != null)
        {
            screenPos = targetCa.WorldToScreenPoint(targetTrans.position + offsetPos);
            if(screenPos.z < 0)
            {
                selfTrans.localPosition = backPos;
            }
            else
            {
                curPos = uiCa.ScreenToWorldPoint(screenPos);
                curPos.z = 0;
                selfTrans.position = curPos;
            }
            if(isAutoScale)
            {
                dis = Vector3.Distance(targetTrans.position, targetCa.transform.position);
                ratio = Mathf.Clamp01((dis - NearDistance) / (FarDistance - NearDistance));
                cachedTransform.localScale = Vector3.Lerp(MaxScale, MinScale, ratio);
            }
        }
    }
}

6、数据及展示的实现:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace Module.UI
{
    //头顶显示需要用到的是数据
    public class CharacterTopParam
    {
        public int level;
        public string name;

        public CharacterTopParam(int level, string name)
        {
            this.level = level;
            this.name = name;
        }
    }

    public class UI_Character_TopUI : MonoBehaviour
    {
        [SerializeField]
        UILabel lblInfo;

        GameObject obj = null;
        public GameObject cachedGameObjec
        {
            get
            {
                if (null == obj)
                    obj = gameObject;
                return obj;
            }
        }

        UIFollow3DPosition followPos = null;
        public UIFollow3DPosition FollowPos
        {
            get
            {
                if (null == followPos)
                {
                    followPos = cachedGameObjec.GetComponent<UIFollow3DPosition>();
                    followPos.isAutoScale = true;
                }
                return followPos;
            }
        }

        public void Show(CharacterTopParam param)
        {
            if (null != param)
            {
                lblInfo.text = string.Format("LV.{0} Name.{1}", param.level, param.name);
                cachedGameObjec.SetActive(true);
            }
        }

        public void Hide()
        {
            cachedGameObjec.SetActive(false);
        }

    }
}

7、将以上两个脚本挂载到做好的UI预设上,并进行相应的设置:

Unity + NGUI 实现人物头顶UI的信息展示第5张

8、UI管理脚本的实现:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Module.UI
{
    public class BillboardUIManager
    {
        static BillboardUIManager billboardMgr = null;
        public static BillboardUIManager BillboardMgr
        {
            get
            {
                if (null == billboardMgr)
                    billboardMgr = new BillboardUIManager();
                return billboardMgr;
            }
        }


        Transform childParent;

        public BillboardUIManager()
        {
            GameObject go = GameObject.Find("UI Root/BillboardPanel");
            childParent = NGUITools.AddChild(go).transform;
        }

        public void Destroy()
        {
            GameObject.Destroy(childParent.gameObject);
        }

        public void SetParentRootActive(bool active)
        {
            childParent.gameObject.SetActive(active);
        }

        Queue<UI_Character_TopUI> queueCharacterTopUI = new Queue<UI_Character_TopUI>();
        public UI_Character_TopUI GetCharacterTopUI(Transform target, Camera cam)
        {
            UI_Character_TopUI topUI = null;
            if (queueCharacterTopUI.Count <= 0)
            {
                Object go = Resources.Load("ui_character_top");
                if (go)
                {
                    GameObject prefab = GameObject.Instantiate(go) as GameObject;
                    prefab.transform.parent = childParent;
                    prefab.transform.localPosition = Vector3.zero;
                    prefab.transform.localRotation = Quaternion.identity;
                    prefab.transform.localScale = Vector3.one;
                    NGUITools.SetLayer(prefab, childParent.gameObject.layer);
                    topUI = prefab.GetComponent<UI_Character_TopUI>();
                }
            }
            else
            {
                topUI = queueCharacterTopUI.Dequeue();
            }


            topUI.FollowPos.targetTrans = target;
            topUI.FollowPos.targetCa = cam;
            topUI.FollowPos.offsetPos = new Vector3(0, 1, 0);

            return topUI;
        }

        void RecycleCharacterUI(UI_Character_TopUI topUI)
        {
            if (null != topUI)
            {
                topUI.Hide();
                queueCharacterTopUI.Enqueue(topUI);
            }
        }
    }
}

9,以上就是全部的核心逻辑,下面是调用逻辑:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Module.UI;

public class CubeCtrl : MonoBehaviour
{
    [SerializeField]
    Camera targetCam;

    float speed = 20.0f;

    Transform trans = null;
    public Transform Trans
    {
        get
        {
            if (null == trans)
                trans = transform;
            return trans;
        }
    }
    
    //Show UI Info
    UI_Character_TopUI characterTopUI = null;
    public UI_Character_TopUI CharacterTopUI
    {
        get
        {
            if (null == characterTopUI)
                characterTopUI = BillboardUIManager.BillboardMgr.GetCharacterTopUI(Trans, targetCam);
            return characterTopUI;
        }
    }

    void Start()
    {
        Trans.transform.rotation = Quaternion.identity;
        CharacterTopParam param = new CharacterTopParam(12, "我是方的");
        CharacterTopUI.Show(param);
    }

    void Update()
    {
        if (Input.GetKey(KeyCode.A))
        {
            Trans.Translate(-Time.deltaTime * speed, 0, 0);
        }
        else if (Input.GetKey(KeyCode.D))
        {
            Trans.Translate(Time.deltaTime * speed, 0, 0);
        }
        else if (Input.GetKey(KeyCode.W))
        {
            Trans.Translate(0, 0, Time.deltaTime * speed);
        }
        else if (Input.GetKey(KeyCode.S))
        {
            Trans.Translate(0, 0, -Time.deltaTime * speed);
        }
    }
}

Unity + NGUI 实现人物头顶UI的信息展示第6张

10、项目运行前后的效果对比图:

Unity + NGUI 实现人物头顶UI的信息展示第7张         Unity + NGUI 实现人物头顶UI的信息展示第8张

11、项目运行时候的结构:

Unity + NGUI 实现人物头顶UI的信息展示第9张

免责声明:文章转载自《Unity + NGUI 实现人物头顶UI的信息展示》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇FastJson简单实现@JsonInclude效果,使得非空字段不返回MII、RMII、GMII接口的详细介绍下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Unity消息简易框架 Advanced C# messenger

Unity消息简易框架 Advanced C# messenger Unity C# 消息机制  【转载 雨凇MOMO博客】 https://www.xuanyusong.com/archives/2165 Tips 在寻找Unity下好用的消息事件框架的时候无意中发现该框架,十分简易,但又用起来特别方便。公司VR游戏中试了下,真滴方便。也不造轮...

Unity添加多个可视镜头Preview功能(一)

打算写这样一个工具,可用于影片镜头调节,房产漫游的可视化,建立多个可视镜头,可以动态调整各个镜头的位置和旋转方向,同时,还能在类似于Camera 的Preview这样的小窗口中查看该镜头(在小窗口中点击鼠标左键并拖拽能调节镜头的旋转轴向),示意图如下: 首先,第一步:创建一个脚本,公开两个参数(目前功能还有待丰富,后续更新...) 第二步:创建一个E...

unity3d中dllimport方法的使用,以接入腾讯平台为例!!!

   转载自:http://momowing.diandian.com/post/2012-12-14/40047766982   如果有侵权,请通知我尽快删除! 说到有关dllimport方法可能还有很多人比较陌生,其实我自己也说不太清楚,大概说说什么时候要用它。 事实上功能类似于调用android的第三包,我们想要使用苹果上特定的api或者第三方平台的...

Unity 多屏(分屏)显示,Muti_Display

Unity 多屏(分屏)显示,Muti_Display  最近项目有个需求,主要用于在展厅的展示游戏。 比如,在一个很大的展厅,很大的显示屏挂在墙上,我们不可能通过操作墙上那块显示器上的按钮来控制游戏。这时候有一个小的显示器(比如一个控制器或者一个手机)我们要做的是:挂在墙上的大显示器用来展示3D游戏场景,而所有的UI控制则全部显示在“控制器“上。这在U...

CSS动画总结效果

   CSS3添加了几个动画效果的属性,通过设置这些属性,可以做出一些简单的动画效果而不需要再去借助JavaScript。CSS3动画的属性主要分为三类:transform、transition以及animation。   transform rotate 设置元素顺时针旋转的角度,用法是: transform: rotate(x); 参数x必须是以...

Unity_发布webGL的问题专题笔记

unity发布成webGL会有很多坑,资源加载,命名,浏览器是否支持等问题。希望大家有什么好的解决办法或问题能互相交流。 如何将Unity的WebGl项目打包发布 :https://blog.csdn.net/qq_25542475/article/details/89370682 Unity 基础开发-WebGL发布无法运行问题:https://blo...