关于Unity中NGUI的3D角色血条的实现
首先要到Unity的Assets Store里面去下载一个扩展的Package叫NGUI HUD Text v1.13(81),注意如果没有安装NGUI就必须先安装NGUI插件,否则会用不了,因为HUD Text是依赖于NGUI插件的,作者是同一个。
3D角色血条实例
1.创建Unity项目工程和文件目录
2.导入模型资源(使用NGUI里面自带的ORC)和NGUI HUD Text v1.13的Package
3.把模型拖进场景中,调整画面,选中Main Camera---->GameObject---->Align With View摄像机对齐选中视图,使得Game视图显现我们想要的画面,如果看不见可能是Camera的Culling Mask没有设置对,要设置成可以看见模型所在的层

4.在ORC模型节点下创建一个Target的子节点当作血量字体的父节点,调整位置到ORC的头顶,血量字体都从这里生成
5.创建一个NGUI的Label然后删除Label,只留下UI Root和摄像机,摄像机的深度值要注意比3D摄像机的深度值大,然后在UI Root节点下再创建一个空节点HUDTextObj
6.添加Assets\HUD Text\Scripts下的HUDText.cs和UIFollowTarget.cs脚本组件到HUDTextObj节点下
7.设置HUDText的Bitmap Font字体属性为Assets\HUD Text\Examples\Atlases下的Arimo20.prefab,如果设置True Type Font为以前的那个msyh,就可以写中文,Font Size字体大小,Effect Color字体特效颜色。
设置UIFollowTarget的target为刚才创建的target,跟随这个节点,Game Camera为3D游戏场景的Camera,UI Camera为UI Root下的Camera,Disable if Invisible如果当前节点不可见就删除,Destroy With Target跟随target节点一起删除

8.写一个脚本test.cs挂载在HUDTextObj节点下控制模型生命值的变化
test.cs
using UnityEngine;
using System.Collections; public class test : MonoBehaviour { public HUDText hudText;
// Use this for initialization
void Start () { } // Update is called once per frame
void Update () {
//hudText.Add(要显示的文字或数字等, 颜色, 停留的时间),实现自动变换的效果
//hudText.Add(Time.deltaTime*10f, Color.yellow, 3f);//在1秒内从1递增到10,停留3秒 if (Input.GetMouseButtonUp())//鼠标左键抬起加血
{
hudText.Add("Add blood +10", Color.green, 0.1f);
} if (Input.GetMouseButtonUp())//鼠标右键抬起扣血
{
hudText.Add("Attacked -20", Color.red, 0.1f);
}
}
}
9.效果

10.添加血条,NGUI---->Open---->Prefab Toolbar,选择一个预制体的进度条拖进场景中,作为UI Root的子节点,设置大小和颜色,位置在模型头顶

11.给test.cs脚本添加关联和控制Slider的语句,可以通过代码控制Slider的Value,从而达到加血扣血会改变血条的值
test.cs
using UnityEngine;
using System.Collections; public class test : MonoBehaviour { public HUDText hudText;
public UISlider slider;
// Use this for initialization
void Start () { } // Update is called once per frame
void Update () {
//hudText.Add(要显示的文字或数字等, 颜色, 停留的时间),实现自动变换的效果
//hudText.Add(Time.deltaTime*10f, Color.yellow, 3f);//在1秒内从1递增到10,停留3秒 if (Input.GetMouseButtonUp())//鼠标左键加血
{
hudText.Add("Add blood +2", Color.green, 0.1f);
slider.value += 0.02f;
} if (Input.GetMouseButtonUp())//鼠标右键扣血
{
hudText.Add("Attacked -2", Color.red, 0.1f);
slider.value -= 0.02f;
}
}
}
12.效果

13.UIFollowTarget.cs部分代码
void Start()
{
if (target)
{
if (gameCamera == null) gameCamera = NGUITools.FindCameraForLayer(target.gameObject.layer);//通过层找到3D摄像机
if (uiCamera == null) uiCamera = NGUITools.FindCameraForLayer(gameObject.layer);//通过层找到UI摄像机
Update();
}
else
{
if (destroyWithTarget) Destroy(gameObject);
else enabled = false;
}
} /// <summary>
/// Update the position of the HUD object every frame such that is position correctly over top of its real world object.
/// </summary> void Update ()
{
if (target && uiCamera != null)
{
//把跟随的节点的坐标转换为gameCamera的视图坐标
Vector3 pos = gameCamera.WorldToViewportPoint(target.position); //判断是否可见,是否在可视区域内
// Determine the visibility and the target alpha
int isVisible = (gameCamera.orthographic || pos.z > 0f) && (pos.x > 0f && pos.x < 1f && pos.y > 0f && pos.y < 1f) ? : ;
bool vis = (isVisible == ); // If visible, update the position
if (vis)
{
pos = uiCamera.ViewportToWorldPoint(pos);
pos = mTrans.parent.InverseTransformPoint(pos);
//pos.x = Mathf.RoundToInt(pos.x);
//pos.y = Mathf.RoundToInt(pos.y);
pos.z = 0f;
mTrans.localPosition = pos;
} // Update the visibility flag
if (mIsVisible != isVisible)
{
mIsVisible = isVisible; if (disableIfInvisible)
{
for (int i = , imax = mTrans.childCount; i < imax; ++i)
NGUITools.SetActive(mTrans.GetChild(i).gameObject, vis);//开始激活
} // Inform the listener
if (onChange != null) onChange(vis);
}
}
else Destroy(gameObject);
}
14. HUDText.cs部分代码
提高游戏性能的编程方法:池,是用List来模拟
循环利用已经创建的gameObject,避免了频繁的初始化gameObject(因为创建,初始化gameObject是需要消耗CPU时间的)
避免了短时间的卡顿现象,比如捕鱼达人,在一两帧内批量创建几百条的鱼可能会出现瞬时间的卡顿,在手机上性能优化比电脑上明显
被激活的gameObject
List<Entry> mList = new List<Entry>();
保存被销毁的文字,但是我们不销毁gameObject,只是隐藏gameObject;然后添加到未使用的List列表中
List<Entry> mUnused = new List<Entry>();
Entry Create ()
{
// See if an unused entry can be reused看是否可以被复用
if (mUnused.Count > )
{
Entry ent = mUnused[mUnused.Count - ];//从未激活的List的最后一个开始取
mUnused.RemoveAt(mUnused.Count - );//取出后再删除未激活的List里面的最后一个
ent.time = Time.realtimeSinceStartup;
ent.label.depth = NGUITools.CalculateNextDepth(gameObject);//改变深度值
NGUITools.SetActive(ent.label.gameObject, true);//激活
ent.offset = 0f;
mList.Add(ent);//添加到已被激活的List里面去
return ent;
} // New entry重新创建
Entry ne = new Entry();
ne.time = Time.realtimeSinceStartup;
ne.label = NGUITools.AddWidget<UILabel>(gameObject);//耗时的
ne.label.name = counter.ToString();
ne.label.ambigiousFont = ambigiousFont;
ne.label.fontSize = fontSize;
ne.label.fontStyle = fontStyle;
ne.label.applyGradient = applyGradient;
ne.label.gradientTop = gradientTop;
ne.label.gradientBottom = gradienBottom;
ne.label.effectStyle = effect;
ne.label.effectColor = effectColor;
ne.label.overflowMethod = UILabel.Overflow.ResizeFreely; // Make it small so that it's invisible to start with
ne.label.cachedTransform.localScale = new Vector3(0.001f, 0.001f, 0.001f);
mList.Add(ne);//添加到已被激活的List里面去
++counter;
return ne;
} /// <summary>
/// Delete the specified entry, adding it to the unused list.
/// </summary> void Delete (Entry ent)
{
mList.Remove(ent);//从已经激活的List里面删除
mUnused.Add(ent);//添加到未激活的等待被复用的List里面
NGUITools.SetActive(ent.label.gameObject, false);//设置为不可见
}
void Update ()
{
#if UNITY_EDITOR
if (!Application.isPlaying) return;
#endif
float time = RealTime.time; if (mOffsets == null)
{
mOffsets = offsetCurve.keys;
mAlphas = alphaCurve.keys;
mScales = scaleCurve.keys;
} float offsetEnd = mOffsets[mOffsets.Length - ].time;
float alphaEnd = mAlphas[mAlphas.Length - ].time;
float scalesEnd = mScales[mScales.Length - ].time;
float totalEnd = Mathf.Max(scalesEnd, Mathf.Max(offsetEnd, alphaEnd)); // Adjust alpha and delete old entries
for (int i = mList.Count; i > ; )
{
Entry ent = mList[--i];
float currentTime = time - ent.movementStart;
ent.offset = offsetCurve.Evaluate(currentTime);
ent.label.alpha = alphaCurve.Evaluate(currentTime); // Make the label scale in
float s = scaleCurve.Evaluate(time - ent.time);
if (s < 0.001f) s = 0.001f;
ent.label.cachedTransform.localScale = new Vector3(s, s, s); // Delete the entry when needed超过一定时间删除
if (currentTime > totalEnd) Delete(ent);
else ent.label.enabled = true;
} float offset = 0f; // Move the entries
for (int i = mList.Count; i > ; )
{
Entry ent = mList[--i];
offset = Mathf.Max(offset, ent.offset);
ent.label.cachedTransform.localPosition = new Vector3(0f, offset, 0f);
offset += Mathf.Round(ent.label.cachedTransform.localScale.y * ent.label.fontSize);
}
}
小技巧
1.升级API,可以在Assets---->Run API Update手动升级

2.当在Scene视图里面调好我们想从Game视图看到的样子后,可以选中Main Camera---->GameObject---->Align With View瞬间把摄像机对齐这个画面,使得Game视图里面就是显现我们要的画面
3.Update()的刷新是按照每帧来显示的,但是Time.deltaTime是按照秒来统计的。当Time.deltaTime*10.0f的时候,这个乘的结果表示是在1秒内从1不断递增到10
4.使用msyh字模就可以写中文
关于Unity中NGUI的3D角色血条的实现的更多相关文章
- 【《Effective C#》提炼总结】提高Unity中C#代码质量的21条准则
作者:Williammao, 腾讯移动客户端开发工程师 商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处. 原文链接:http://wetest.qq.com/lab/view/290.h ...
- 【《Effective C#》提炼总结】提高Unity中C#代码质量的22条准则
引言 原则1尽可能地使用属性而不是可直接访问的数据成员 原则2偏向于使用运行时常量而不是编译时常量 原则3 推荐使用is 或as操作符而不是强制类型转换 原则4 推荐使用条件属性而不是if条件编译 原 ...
- 【转】Effective C#观后感之提高Unity中C#代码质量的21条准则
转自:http://blog.csdn.net/swj524152416/article/details/75418162 我们知道,在C++领域,作为进阶阅读材料,必看的书是<Effectiv ...
- 关于Unity中NGUI的Checkbox复选框、Slider滑动条和Button的6种触发回调事件的方式
Checkbox复选框 1.创建一个NGUI背景Sprite1节点 2.打开NGUI---->Open---->Prefab Toolbar---->选择一个复选框节点,拖拽到背景节 ...
- Shader实例:NGUI制作网格样式血条
效果: 思路: 1.算出正确的uv去采样过滤图,上一篇文章说的很明白了.Shader实例:NGUI图集中的UISprite正确使用Shader的方法 2.用当前血量占总血量的百分比来设置shader中 ...
- 关于Unity中NGUI图片精灵响应鼠标的方法
我在Unity里做NGUI的时候发现一个问题. 在Unity2D场景当中,一个精灵图片只要加上了Box Collider或者Box Collider2D,就可以相应OnMouseEnter和OnMou ...
- 关于Unity中NGUI的Tab商城、Scrollview和打字机效果的实现
Tab商城实例 UIToggle 和 UIToggledObjects+ Box Collider(实现商城功能必备) 1.创建两个个UI Sprite,Sprite1和Sprite2 2.给Spri ...
- 关于Unity中NGUI的背包实现之Scrollview(基于Camera)
基于UIPanel的scrollview实现方式在移动设备上的性能不如基于camera的方式.因为UIPanel的scrollview实现方式要渲染很多的道具图,性能自然就降低了.如果是用第二个摄像机 ...
- 关于Unity中NGUI的Pivot和锚点
Pivot 1.创建一个Sprite类型的Sprite1节点,关联一个图集和一张贴图,用图中的六个按钮调整这个贴图的Pivot点,一共有八个点可以选择 2.再创建一个Sprite类型的Sprite2节 ...
随机推荐
- 汇合confluence
Confluence是一个专业的企业知识管理与协同软件,也可以用于构建企业wiki.使用简单,但它强大的编辑和站点管理特征能够帮助团队成员之间共享信息.文档协作.集体讨论,信息推送. 空间 空间是页面 ...
- POJ.2065.SETI(高斯消元 模线性方程组)
题目链接 \(Description\) 求\(A_0,A_1,A_2,\cdots,A_{n-1}\),满足 \[A_0*1^0+A_1*1^1+\ldots+A_{n-1}*1^{n-1}\equ ...
- web前端不可错过的开发工具–Adobe Brackets
Adobe Brackets是一个开源的基于HTML/CSS/JavaScript开发,运行在native shell上的集成开发环境.该项目由Adobe创建和维护,根据MIT许可证发布.提供Wind ...
- python 字符串的一些方法
总结:# split 分割 ********# strip 脱 默认脱头尾的空格 ********# replace 替换 ********# join 插入 拼接 ********# format ...
- 继承之final关键字的使用
final关键字 使用final关键字坐标识具有"最终的"含义, final可以修饰类.方法.属性.和变量. final修饰类表示该类不能被继承 final修饰方法,则表示该方法不 ...
- 探讨后端选型中不同语言及对应的Web框架
在进行后端选型的时候,实际上我们要选择的是一个框架.后端领域所使用的技术和框架已经趋于稳定,我们只需要按我们的需要选择所需要的框架.当存在多个框架适合时,我们再选择适合的语言.不得不指出的是,当我们喜 ...
- golang语言并发与并行——goroutine和channel的详细理解
如果不是我对真正并行的线程的追求,就不会认识到Go有多么的迷人. Go语言从语言层面上就支持了并发,这与其他语言大不一样,不像以前我们要用Thread库 来新建线程,还要用线程安全的队列库来共享数据. ...
- 哪个中年IT男不是一边面对危机,一边咬牙硬抗【转】
来自: 懂懂笔记 对于 2017 年年末那则令人哀伤的消息,相信很多同龄人都会触目伤怀.面对公司的强制性劝退,深圳中兴网信科技有限公司某研发组主管从办公楼上一跃而下,用最决绝的方式结束了宝贵的生命. ...
- zeromq学习笔记1——centos下安装 zeromq-4.1.2
1.前言 MQ(message queue)是消息队列的简称,可在多个线程.内核和主机盒之间弹性伸缩.ZMQ的明确目标是“成为标准网络协议栈的一部分,之后进入Linux内核”.现在还未看到它们的成功. ...
- Cancel-Based Recovery
http://www.toadworld.com/platforms/oracle/w/wiki/1010.cancel-based-recovery.aspx Cancel-Based recove ...