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

8 篇文章 0 订阅

名字牌包括2D,3D名字牌两种,区别在于2D是基于屏幕坐标的名字牌,将名字牌的gameobject结点挂在UI相机下,不会受3D场景中物件的影响,3D名字牌可以视为游戏场景内的一部分物件,名字牌跟随角色移动同时也会被3D场景中其他物件遮挡,这里仅讨论2D名字牌

关于ngui实现名字牌的方式,很多博客都写到过,本人在这里针对RPG游戏中的实现方式进行一下个人总结

先归纳一下这类需求:

名字牌:玩家血条、个人昵称,帮派名称、称号 及其他XX等顶在角色头顶的,延伸需求涉及名字牌屏蔽功能,只显示一定范围的玩家名字牌,其他屏蔽,当角色跑到身后时进行视野裁剪,同时场景内角色管理时,从性能角度需要考虑仅显示一定数量上限的角色包括显示优先级,比如NPC和普通玩家、好友、家族成员,帮派成员,敌国玩家,这些角色达到一定数量时是否创建还是仅创建名字牌

伤害tips: 普通攻击,暴击、吸血等 ,涉及美术字,tips动画

掉落物品tips:击杀怪物或者打碎箱子爆出的场景内道具上加道具tips提示


相关功能点:

1,3d场景中角色位置是不断变化的,2D的名字牌需要将位置时时和3D中的坐标对应,角色向右移动,屏幕上的名字牌也要跟随移动,即3D坐标空间和2D空间通过屏幕位置进行转换,

3DCamera.WorldToScreenPoint
<pre name="code" class="csharp" style="font-family: Arial, Helvetica, sans-serif; padding: 5px; border: 1px dotted rgb(170, 170, 170); color: rgb(63, 63, 63); font-size: 14px; line-height: 30px; orphans: 2; widows: 2; background-color: rgb(246, 246, 246);">2DCamera.ScreenToWorldPoint
具体实现代码:
<pre name="code" class="csharp" style="font-family: Arial, Helvetica, sans-serif; padding: 5px; border: 1px dotted rgb(170, 170, 170); color: rgb(63, 63, 63); font-size: 14px; line-height: 30px; orphans: 2; widows: 2; background-color: rgb(246, 246, 246);">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()
    {
<span style="white-space:pre">	</span>//取得3D场景摄像机和UI相机
        m_go3DCamera = GameObject.FindWithTag("MainCamera").GetComponent<Camera>();
        m_go2DCamera = GameObject.Find("UI Root").transform.FindChild("Camera").GetComponent<Camera>();
    }
void Update () {
//每帧UPDATE时,计算3D场景中角色位置变化,通过计算得到2D空间中的坐标位置,重新设置此物件在屏幕坐标的位置
        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;
    }
}

 2:,视野裁剪: 
 
<span style="white-space:pre">	</span>当其他玩家或者怪物,NPC离开主角摄像机范围时,需要隐藏对应的名字牌
方法:1,通过摄像机的<span style="color: rgb(51, 51, 51); font-size: 16px; line-height: 28px; white-space: pre-wrap; background-color: rgb(255, 255, 255);">ViewportToWorldPoint 计算物体是否在屏幕坐标内</span>
<span style="color: rgb(51, 51, 51); font-size: 16px; line-height: 28px; white-space: pre-wrap; background-color: rgb(255, 255, 255);">方法:2,</span>
<span style="color: rgb(51, 51, 51); font-size: 16px; line-height: 28px; white-space: pre-wrap; background-color: rgb(255, 255, 255);">3,由于是用NGUI实现的,因此,将创建的名字牌,血条等放到UIRoot下,利于减少drawcall</span>
<span style="color: rgb(51, 51, 51); font-size: 16px; line-height: 28px; white-space: pre-wrap; background-color: rgb(255, 255, 255);">创建一个panel,将名字牌、血条、伤害tips 的prefab不添加panel,同时将同一类的uilabel uisprite深度尽量接近,利用unity 的自动合并材质的功能</span>
<span style="color: rgb(51, 51, 51); font-size: 16px; line-height: 28px; white-space: pre-wrap; background-color: rgb(255, 255, 255);">4,由于游戏中需要大量创建tips 名字牌、血条,频繁的创建和销毁gameobject会带来性能的损失,因此需要引入池技术,每种类型 血条 ,名字牌,普通攻击tips 美术字的暴击tips 等每种创建时从池中取得,销毁时由池负责,池并不是真正销毁,有可能是setvisible,有可能是localscale  为0 </span>
<span style="color: rgb(51, 51, 51); font-size: 16px; line-height: 28px; white-space: pre-wrap; background-color: rgb(255, 255, 255);">5,美术字暴击tips 美术为了追求效果,一些暴击、吸血等tips需要用美术字,使用uifont将美术字制作成字库,通过key-value取得对应的美术字效果,如果单个引用美术字会引起drawcall的增加,</span>
<span style="color: rgb(51, 51, 51); font-size: 16px; line-height: 28px; white-space: pre-wrap; background-color: rgb(255, 255, 255);"></span><div style="font-family: Tahoma; padding: 0px; font-size: 14px; color: rgb(63, 63, 63); line-height: 30px; orphans: 2; widows: 2;">减少DrawCall:</div><div style="font-family: Tahoma; padding: 0px; font-size: 14px; color: rgb(63, 63, 63); line-height: 30px; orphans: 2; widows: 2;">NGUI内置合并DrawCall机制,同一个Panel下,不被打断的depth区间段,使用同样的Material,这些Widget可以被合并为一个DrawCall</div>



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值