标签:

Unity里实现人物头顶的名字牌、血条的实现,网上很多博客有提到过。这里结合自己在项目中的开发,简单总结几点。

宣雨松的热门博客里有提到过直接利用Unity自身的OnGUI()实现人物血条:http://www.xuanyusong.com/archives/1032 。

撇开血条进度条的更新,重点关注头顶物件位置的更新。简化之,实现人物头顶的名字牌的。

核心代码如下:

using UnityEngine;

using System.Collections;

public class Following : MonoBehaviour {

public Camera m_Camera = null;

public GameObject m_goFollowing = null;

public Vector3 m_vOffset;

void OnGUI()

{

Vector3 vPosScreen = m_Camera.WorldToScreenPoint(m_goFollowing.transform.position + m_vOffset);

GUI.Label(new Rect(vPosScreen.x, Screen.height - vPosScreen.y, 200, 80), "牧羊少年奇幻之旅");

}

不过,实际项目中暂时不会用Unity的原生UI,目前的项目多用的是Unity4.x版本,原生UI太难用,多用NGUI等插件。下面主要介绍Unity中借助NGUI实现人物的头顶挂件。

头顶物件用NGUI实现可以根据渲染相机来分为两种方式:

(1)采用渲染场景的MainCamera来渲染头顶物件,这样的头顶物件可以看做普通的3D物体,是可以被场景中3D物体遮挡的。

(2)专门用UI相机渲染,头顶物件作为UI,不会被场景中3D物体遮挡。

一般我们会采用方式2,UI尽量不要用主相机渲染,用专门的UI相机渲染。

不过,还是顺带提一下采用方式(1)处理UI的核心代码:

public class Following : MonoBehaviour {

public GameObject m_goFollowing = null;

public float m_fOffset = 0;

void Update()

{

gameObject.transform.position = m_goFollowing.transform.position + new Vector3(0, m_fOffset, 0);

gameObject.transform.rotation = Camera.main.transform.rotation;

}

}

如果您在实践中发现UILabel不可见,请注意:

(1)UILabel UISprite不能单独用,一定要附带一个Panel,作为Panel的子节点或者NGUIPanel和UILabel UISprite挂在同一个GameObject下。

(2)同时UILabel的Layer必须和所附带的NGUIPanel保持一致。请保证你的相机没有屏蔽UILabel所在的Layer。

(3)UILabel UISprite无论是在哪个Panel下,尽量放在UIRoot下吧。若有些物体看不见,调整下Scale。

我们一般采用方式2,UI用专门的UI相机渲染,核心是将主相机下的Transform映射到UI相机下的Transform。

using UnityEngine;

using System.Collections;

public class Following : MonoBehaviour {

public GameObject m_goFollowing = null;

public float m_fOffset = 0;

private Camera m_go3DCamera = null;

private Camera m_go2DCamera = null;

void Start()

{

m_go3DCamera = GameObject.FindWithTag("MainCamera").GetComponent();

m_go2DCamera = GameObject.Find("UI Root").transform.FindChild("Camera").GetComponent();

}

void Update () {

Vector3 vPos = TransPos(m_goFollowing.transform.position + new Vector3(0, m_fOffset, 0));

gameObject.transform.position = new Vector3(vPos.x, vPos.y, 0); //get proper z, z = 0.0f simply

gameObject.transform.rotation = m_go2DCamera.transform.rotation; //keep the same rotation with camera, so Parallel with camera

}

//Transform WorldPos in 3DCamera to new WorldPos in 2DCamera. They share the same ScreenPos

Vector3 TransPos(Vector3 worldpos)

{

if (m_go3DCamera == null || m_go2DCamera == null)

{

return Vector3.zero;

}

Vector3 screenPos = m_go3DCamera.WorldToScreenPoint(worldpos);

Vector3 newWorldPos = m_go2DCamera.ScreenToWorldPoint(screenPos);

return newWorldPos;

}

}

这其中的要点都写在注释里了。

游戏场景一般用3DCamera渲染,名字牌血条等属于UI,应该被UI相机渲染。头顶的名字牌血条要跟随着3D场景里的物体,关键是如何将3D相机空间里的位置映射到UI相机相机空间。中间的桥梁是屏幕位置,两个相机看到的头顶物件应该映射到同一个屏幕坐标。

同时,两个细节需要注意:

1. 为保证UI可见,通过UI相机变换得到的坐标深度要设置为合适的值,太远或太近会出视野范围。可以简单地设置为0。

2. 头顶物件要注意和UI相机保持平行,即头顶物件的rotation设置为UI相机的rotation。

实际应用中,还有一些性能问题需要注意。

(1)减少DrawCall:

NGUI内置合并DrawCall机制,同一个Panel下,不被打断的depth区间段,使用同样的Material,这些Widget可以被合并为一个DrawCall。

具体而言,使用同样的Atlas的UISprite,挂在同一个UIPanel下的depth区间,此depth区间在此UIPanel下不被其他的Atlas使用。UILabel也针对每种字体分配一个Depth区间。 当然,前提是不影响功能需求。

以头顶的名字条NameBar、血条HPBar为例,NameBar.prefab, HPBar.prefab本身不要带有UIPanel,我们为头戴物件在NGUI-UIRoot下创建一个共同的UIPanel--HeadWearingPanel,所有实例化的NameBar、HPBar都挂在HeadWearingPanel下。

另外,NGUI3.8.0之前的版本,显示/隐藏UIWdget会导致所有UIDrawCall的销毁重建,对CPU负荷较大。如果用NGUI3.8.0之前的版本,建议不要直接用gameObejct.SetActive(false)来实现UI控件的隐藏,可以令transform.scale = Vector3.zero, 或者将欲隐藏的UI移到视野外。NGUI3.8.0的版本没有这个问题了。

(2)减少GC

对于要频繁创建销毁的UI,做一个资源池。避免频繁创建销毁对象带来的大量gc。

针对每种类型的Prefab创建一个Pool.删除NameBar、HPBar时,并不真正Destroy,将之隐藏即可。常见NameBar、HPBar时,先从Pool里查找是否有可用的NameBar、HPBar,若没有找到才真正实例化创建新对象。

标签:

unity头顶状态制作_Unity里名字牌、血条等头顶挂件的实现相关推荐

  1. unity头顶状态制作_Unity中结合IK实现Lookat

    前言 之前只是花个周末复读了一篇育碧的演讲,讲到一些周边系统,程序化镜头,口型匹配,角色补光,景深,Lookat,我都玩过一点,很多在2U引擎里都算是标配;本以为投靠Unreal可以缓解大部分周边系统 ...

  2. unity头顶状态制作_unity实现头顶血条

    本文来自网易云社区 作者:汪毅军 在游戏中,头顶血条的是一个非常常见的功能,其中血条可分为2D血条和3D血条.2D血条不会随着模型远近而变化,始终保持着相同的大小:但3D血条会随着模型远近移动而产生透 ...

  3. RPG 游戏 unity ngui 实现2D名字牌血条等功能

    名字牌包括2D,3D名字牌两种,区别在于2D是基于屏幕坐标的名字牌,将名字牌的gameobject结点挂在UI相机下,不会受3D场景中物件的影响,3D名字牌可以视为游戏场景内的一部分物件,名字牌跟随角 ...

  4. 【Unity3D——UIFixedObj】用于跟随物体显示UI标签(如角色名、血条等)

    该脚本用于跟随物体显示UI标签(如角色名.血条等). 跟随角色,显示角色名或者血条/蓝条等,且不受摄像机距离远近影响. 可扩展:使该UI未处于视野范围内时隐藏,处于视野范围内时显示. 效果图如下所示: ...

  5. slider unity 头顶血条_Unity开发者教程:人物血条跟随的功能开发(一)

    相信各位菜鸟用UGUI做人物血条跟随时都会遇到大坑,今天就来说说如何用UGUI来做人物血条跟随. 第一种: 把Canvas画布作为Player的子物体. 首先:布置一下场景,简单的地面和一个胶囊人物. ...

  6. Unity 回合制战斗系统(中级篇)-血条和伤害数值

    项目文件找出来了,老版本的脚本有报错,我在新版2019.4.21f1c1下解决了报错,战斗场景可以正常跑的. 需要的同学点下面地址下载(关注就行啦不用积分),祝大家都早日学成 项目包下载 ------ ...

  7. 【游戏开发】unity教程8 用IMGUI和UGUI实现血条

    github传送门:https://github.com/dongzizhu/unity3DLearning/tree/master/hw8/enhancedDisk 视频传送门:https://sp ...

  8. Unity UGUI实现王者荣耀版多格血条

    上篇讲述了Boss多层血条的实现方法,这篇就主要讲述一下类似于王者荣耀,LoL的分段式血条, 这样的血条在游戏的视觉层会带给玩家非常好的体验.就好比玩家买了一个狂徒铠甲.如过你用 的是分段血条的话,就 ...

  9. Unity的NGUI插件的HUD Text插件血条数值的显示

    原文取自:qq_32009641的博客 以前没接触这个插件时,做的小demo中实现怪物血条使用GUI绘制的 (就是雨松大大的方法,很经典 在这里先谢过大大) 用这个插件实现怪物血条只需简单的几部 方法 ...

最新文章

  1. 发那科机器人示教器电缆线_云和发那科机器人维修
  2. MySql批量插入时,如何不插入重复的数据
  3. html 资源缓存,解决index.html缓存问题
  4. c语言顺序查找算法,c语言实现排序和查找所有算法
  5. Selenium 中文API
  6. 实现jdbc连接mysql_Java JDBC连接MYSQL数据库教程(实现)
  7. C#中public函数的用法_python中的lambda函数用法
  8. JAVA总结实录01 : 异常处理 try-catch-finally
  9. 也来对比一下segmentfault、开源中国、简书
  10. python初级工程师面试题_Python工程师面试题
  11. Python爬虫开源项目代码分享,100个
  12. mysql置疑原因_数据库置疑的处理办法
  13. html5霓虹效果代码,HTML5 canvas蜂巢式彩色霓虹背景效果
  14. Unity导入Mixamo动画,合并Mixamo动作
  15. 城乡规划编制单位资质乙级都要走什么流程
  16. c语言boll函数,布林线学习(二) 布林线的公式为:BOLL:MA(CLOSE,M); UB:BOLL+2*STD(CLOSE,M); LB:BOLL-2*... - 雪球...
  17. 2016年8月6日 星期六 --出埃及记 Exodus 16:6
  18. S32G-VNP-RDB2开发环境搭建
  19. 上下料机械手控制系统硬件性能及运动轨迹说明
  20. 代码的同源性检测:基于c语言实现的对代码的同源性检测 详细教程

热门文章

  1. java简单通讯录代码_java使用线性表写一个简单的通讯录系统
  2. [转][读书笔记2]软件开发与如何开发软件的若干感想
  3. 浏览器原理 12 # 垃圾回收:垃圾数据是如何自动回收的?
  4. IPHONE小说软件测试,如何进行 iPhone 客户端的软件测试
  5. 【C++项目实战】 门诊预约管理系统(底层UI封装)
  6. shell脚本之购物车清单脚本
  7. 修改苹果手机定位服务器地址,GPSCheat插件可以轻松自定义/更改手机GPS位置
  8. 连接的外部图形设备可能无法与计算机工作,连接外围设备,可以为计算机提供额外功能,Win10如何使用和管理...
  9. 【BIM入门实战】Revit 2018幕墙的绘制与注意事项
  10. 0x0FDFE224 (ucrtbased.dll)处(位于.exe 中)引发的异常: 0xC0000005: 写入位置 0x01100000 时发生访问冲突。 如有适用于此异常的处