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

server/2024/12/28 2:46:57/

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/server/153787.html

相关文章

使用 Python 操作 Excel 表格

在Python中操作Excel表格&#xff0c;你可以使用几个流行的库&#xff0c;比如openpyxl、pandas和xlrd/xlwt。下面我会分别介绍这些库的基本用法。 1. 使用 openpyxl openpyxl 是一个用来读写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库。 安装&#xff1a; pip install ope…

芯片Tapeout power signoff 之IR Drop Redhawk Ploc文件格式及其意义

数字IC后端工程师在芯片流程最后阶段都会使用redhawk或voltus进行设计的IR Drop功耗signoff分析。必须确保静态&#xff0c;动态ir drop都符合signoff标准。 在做redhawk ir drop分析前&#xff0c;我们需要提供一个redhawk ploc供电点坐标。 数字IC设计后端实现前期预防IR D…

重温设计模式--10、单例模式

文章目录 单例模式&#xff08;Singleton Pattern&#xff09;概述单例模式的实现方式及代码示例1. 饿汉式单例&#xff08;在程序启动时就创建实例&#xff09;2. 懒汉式单例&#xff08;在第一次使用时才创建实例&#xff09; 单例模式的注意事项应用场景 C代码懒汉模式-经典…

聊聊volatile的实现原理?

在 Java 并发编程中&#xff0c;有 3 个最常用的关键字&#xff1a;synchronized、ReentrantLock 和 volatile。 虽然 volatile 并不像其他两个关键字一样&#xff0c;能保证线程安全&#xff0c;但 volatile 也是并发编程中最常见的关键字之一。例如&#xff0c;单例模式、Co…

RAGFlow 基于深度文档理解构建的开源 RAG引擎 - 使用Ollama添加大模型

RAGFlow 基于深度文档理解构建的开源 RAG引擎 - 使用Ollama添加大模型 flyfish 当安装完ragflow之后&#xff0c;开始添加大模型 $ git clone https://github.com/infiniflow/ragflow.git $ cd ragflow $ docker compose -f docker/docker-compose.yml up -d浏览器打开http:…

【OCR】数据集合集!

本文将为您介绍经典、热门的数据集&#xff0c;希望对您在选择适合的数据集时有所帮助。 1 RapidOCR 更新时间&#xff1a;2024-12-24 访问地址: GitHub 描述&#xff1a; 基于 ONNXRuntime、OpenVINO 和 PaddlePaddle 的超棒 OCR 多编程语言工具包。多平台、多语言 OCR 工具…

泰山派GPIO子系统驱动---亮灯

本人linux驱动小白&#xff0c;文章基于B站up主 李Sir______ 视频内容记录&#xff0c;做笔记用。如有错误欢迎指正。本文将以开发板第40引脚GPIO3_B4作为LED灯珠的控制引脚&#xff0c;高电平灯亮&#xff0c;低电平灯灭。 杂话 在linux内核中&#xff0c;芯片厂商已经把所有…

WebSocket | 背景 概念 原理 使用 优缺点及适用场景

1 背景 在 WebSocket 出现之前&#xff0c;为了实现推送技术&#xff0c;所用的技术都是轮询&#xff0c;轮询是指浏览器每隔一段时间向服务器发出 HTTP 请求&#xff0c;服务器再返回最新的数据给客户端 常见的轮询方式分为轮询与长轮询&#xff0c;它们的区别如下图所示&…