Unity 战斗系统中角色UI血条设计

ops/2024/12/28 0:30:36/

1:如何选取技术方案

Unity战斗系统中,每个角色经常会有血条与昵称。如何架构设计才高效,我们列举一些常用的做法:

  1. onGUI来做昵称与血条;
  2. 3D世界中创建一个3D物体来做血条与昵称,然后让血条与昵称对着摄像机;
  3. 基于UGUI/NGUI单独做血条与昵称的UI节点,然后把UI节点位置与角色同步;
  4. 其它可能的做法;

方案(1)中onGUI的性能是很差的, 一般只用于显示一些调试相关的信息,不适合用来做正式的游戏物体。方案(2)中创建3D物体,然后对着摄像机,能实现功能,可能的问题就是血条昵称这样的物体,可能会打乱物体的合批,使得drawcall比较高, 昵称与血条的Shader也可能与角色的不一样,会有不断切换Shader, set bass call爆增的风险。所以在正式的项目里面会使用方案(3)的UGUI/NGUI来单独创建血条与昵称的UI节点,然后角色移动同时更新同步UI节点的位置。

这样角色到哪里血条与昵称就跟到哪里。所有的血条与昵称都在UGUI的一个节点下,大量角色战斗的时候这些血条与昵称可以合批一起绘制,尽量降低Drawcall。方案定下来后,就基于这个思路来实现,需要解决角色与血条如何管理,角色与血条位置如何同步2大问题。

2: 如何排布角色节点与UI血条

  3D角色美术建模完成以后,程序把它导入项目中,还要做一件很重要的事情,就是给这个角色加一个3D的节点mountPoint,这个节点在屏幕中的位置就是UI血条在屏幕中的位置,这个很关键。很多同学就会疑惑了,只要角色位置+一个固定的偏移就可以了,为什么要这个点呢?因为3D游戏与2D游戏不一样,3D游戏物体在屏幕中的位置除了和自己本身有关系外还和摄像机的角度有关系,所以不能直接是位置加一个偏移,而是在3D角色上加一个合适的3D的点,这个点在屏幕上的位置就是UI血条与昵称所在的位置,如图:

mountPoint的坐标转到屏幕坐标后,就是UI血条与昵称所在的屏幕位置。接下来看下UI节点。战斗场景中都会有一个操作UI,所有的UI都要盖在角色的血条与昵称上,所以当我们做战斗场景的主UI的时候,专门做一个UIBloodRoot节点,用来挂游戏中所有的血条与昵称对象,如图:

最后再做一个昵称+血条的UI对象,等角色创建的时候,再把这个对象创建出来,如图:

3 战斗系统中3D角色的UI代码设计

首先每个战斗单元,我们都会设计一个管理类提供策略,比如玩家对象,很多游戏会设计一个Player类来控制玩家, Boss怪会设计一个BossEnemy的类来控制Boss,而Player, Boss需要的很多策略,有些是共用的,血条就是其中之一,所以一般Player与Boss都会继承自一个策略基类FightCharactor,我们就可以把战斗掉血,吃道具加血以及UI血条的机制策略设计到FightCharactor里。

class FightCharactor extends Monobehaviour {

// 实现掉血,加血,血条的机制;

private float hp; // 战斗单元的血量

private UICharactor uiCharactor; // 控制ui血条显示,角色昵称显示的组件实例;

// end

public void Init() {} //

}

Class Player extends FightCharactor {

// 实现玩家特有的策略

// end

}

Class BossEnemy extends FightCharactor {

// 实现Boss特有的策略

// end

}

接下来设计一个UICharactor组件类,new 一个组件类的实例添加到血条与昵称的ui对象上,来提供显示血条进度,与显示角色昵称的功能。

Class UICharactor extends MonoBehaviour {

public void SetBloodPer(float per) {…}

public void SetUnick(string unick) {…}

}

在主战斗UI界面控制代码处提供一个接口UICharactor CreateUICharactor(),返回UIChractor对象实例。伪代码如下:

UICharactor CreateUICharactor() {

    GameObject uiObject = GameObject. Instantiate(UI血条+昵称的预制体);

// 将血条对象放到UIBloodRoot节点下;

uiObject.transform.SetParent(this.UIBloodRoot, false);

UICharactor ctrl = uiObject.AddComponent<UICharactor>(); //添加组件实例到UI节点

return ctrl;

}

在战斗角色FightCharactor类中的初始化方法Init中,调用UI控制代码的CreateUICharactor接口,获得UICharactor的组件实例,这样就可以在战斗掉血中,调用UICharactor的接口来显示血量与昵称了。

public void Init() {

this.uiCharactor = 游戏UI界面控制对象实例. CreateUICharactor();

}

在代码中this.uiCharactor. SetBloodPer接口可以显示角色的血量,this.uiCharactor.SetUnick接口可以显示玩家的昵称等。

最后一件事情,就是角色到哪里,UI血条昵称对象的位置就更新到哪里,这个如何设计呢?可以在FightCharactor类里面写一个LateUpdate方法, 获取战斗单元中的mountPoint挂载点的位置, 然后将这个位置,结合游戏摄像机转换为屏幕坐标, 然后在UICharactor代码里编写一个函数ShowAt(Vector3 screenPos);在UGUI里面把屏幕坐标转成ui节点的世界坐标,这样UI血条昵称节点位置就放到mountPoint对应的屏幕点上了,玩家看起来就同步了。

class FightCharactor {

// …

void LateUpdate() {

Vector3 worldPos = this.mountPoint.transform.position;

Vector3 sceenPos = this.gameCamera.WorldToSceen(worldPos);

this.uiCharactor.ShowAt(sceenPos);

}

// …

}

class UICharactor {

// …

public void ShowAt(Vector3 sceenPos) {

Vector3 wordPos = ui模式下屏幕坐标转世界坐标;

this.transform.position = worldPos;

}

// …

}

本期的战斗系统的UI血条昵称的架构与设计就分析到这里,我录制了了一个视频课件,完整的讲解与实现了刚才的架构与设计


http://www.ppmy.cn/ops/145518.html

相关文章

Chromium GN 目标指南 - view_example 表单示例 (八)

1. 引言 在前面的文章中&#xff0c;我们学习了如何创建计数器示例&#xff0c;了解了如何使用 Label 和 Button 控件进行交互以及更新 UI 状态。在本篇文章中&#xff0c;我们将创建一个更复杂的示例 —— 表单&#xff0c;以学习如何使用 Textfield、Combobox 和 Checkbox 等…

DocFlow票据AI自动化处理工具,提升企业票据数字化管理效能

随着全球化与信息化进程&#xff0c;企业的文件、信息、数据吞吐量不断增长&#xff0c;2020年以来&#xff0c;业务形势的变革再次加速了企业对先进的文档数字化管理解决方案需求。其中&#xff0c;票据处理始终面临着文件量大耗时、单据高度多样化、“淡旺季”周期波动性强、…

极狐GitLab 17.7正式发布,可从 GitLab 丝滑迁移至极狐GitLab【一】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料&#xff1a; 极狐GitLab 官网极狐…

面试场景题系列:分布式系统中的唯一ID生成器

1.场景需求需求界定 •ID必须是唯一的。 •ID只包含数字。 •ID长为64位。 •ID按日期排序。 •可以每秒生成超过10&#xff0c;000个唯一ID。 2.高层级的设计 在分布式系统中&#xff0c;有多个方法可以用来生成唯一ID。我们考虑的方法有&#xff1a; •多主复制(Multi…

最新的强大的文生视频模型Pyramid Flow 论文阅读及复现

《PYRAMIDAL FLOW MATCHING FOR EFFICIENT VIDEO GENERATIVE MODELING》 论文地址&#xff1a;2410.05954https://arxiv.org/pdf/2410.05954 项目地址&#xff1a; jy0205/Pyramid-Flow&#xff1a; 用于高效视频生成建模的金字塔流匹配代码https://github.com/jy0205/Pyram…

linux服务器上CentOS的yum和Ubuntu包管理工具apt区别与使用实战

在 CentOS 7 上&#xff0c;系统默认使用 yum 作为包管理工具&#xff0c;而不是 apt。apt 是为 Debian 和 Ubuntu 系统设计的&#xff0c;不能在 CentOS 或其他基于 RHEL 的发行版上直接使用。 如果你希望继续使用 CentOS 7&#xff0c;并管理软件包&#xff0c;你应该使用 y…

Zookeeper 底层原理解析

一、引言 在分布式系统的浩瀚星空中&#xff0c;Zookeeper 宛如一颗最为闪耀的导航星&#xff0c;为众多分布式应用指引方向、保驾护航。无论是大名鼎鼎的 Hadoop、HBase&#xff0c;还是其他各类复杂的分布式架构&#xff0c;Zookeeper 都扮演着不可或缺的关键角色。它如同一…

JavaScript文件端点提取与安全分析:两种高效实用的方法

提取JS文件中的所有端点(Endpoints) JavaScript文件中包含了大量的信息,对于安全研究人员来说,提取这些文件中的API端点是发现潜在漏洞的重要环节之一。在本篇文章中,我们将介绍两种高效提取JavaScript文件端点的方法。以下方法主要应用于渗透测试场景,尤其是针对目标域…