最新文章
Cocos2d-x游戏开发实例详解7:对象释放时机
03-25 13:59
Cocos2d-x游戏开发实例详解6:自动释放池
03-25 13:55
Cocos2d-x游戏开发实例详解5:神奇的自动释放
03-25 13:49
Cocos2d-x游戏开发实例详解4:游戏主循环
03-25 13:44
Cocos2d-x游戏开发实例详解3:无限滚动地图
03-25 13:37
Cocos2d-x游戏开发实例详解2:开始菜单续
03-25 13:32
unity 伤害值
本次主要为大家讲解Unity中伤害值显示的问题。由于我在项目里做过相关内容,所以今天拿出来和大家分享,仅供学习参考。
一、伤害数值显示在游戏中的重要性
在Unity3D游戏开发里,伤害数值显示是一个关键的功能。以游戏《血雨前传:蜃楼》为例,它虽脱离了前两部作品的回合制模式,采用爽快的ACT横版过关模式,但本质上是一款地道的RPG游戏。其诡异、独特的画面风格以及古龙式武侠叙事风格,为该作品赋予了无限生命力。《雨血》系列更是近年来少有的走出国门、享誉国外的游戏。这款游戏的招式华丽,打击感十足。而在战斗中,敌我双方生命值的对比至关重要,因此实时显示玩家对敌人造成的伤害值能让玩家更好地把握战斗局势。像《仙剑奇侠传五前传》就在战斗中加入了伤害统计,方便玩家掌控战场。
接下来,我们将通过Unity3D中的OnGUI()方法来实现伤害数值的显示。
二、基于OnGUI()方法实现伤害数值显示的代码及解析
代码实现
using UnityEngine;
using System.Collections;
public class DamagePopup : MonoBehaviour {
// 目标位置
private Vector3 mTarget;
// 屏幕坐标
private Vector3 mScreen;
// 伤害数值
public int Value;
// 文本宽度
public float ContentWidth = 100;
// 文本高度
public float ContentHeight = 50;
// GUI坐标
private Vector2 mPoint;
// 销毁时间
public float FreeTime = 1.5F;
void Start () {
// 获取目标位置
mTarget = transform.position;
// 获取屏幕坐标
mScreen = Camera.main.WorldToScreenPoint(mTarget);
// 将屏幕坐标转化为GUI坐标
mPoint = new Vector2(mScreen.x, Screen.height - mScreen.y);
// 开启自动销毁线程
StartCoroutine("Free");
}
void Update() {
// 使文本在垂直方向产生一个偏移
transform.Translate(Vector3.up * 0.5F * Time.deltaTime);
// 重新计算坐标
mTarget = transform.position;
// 获取屏幕坐标
mScreen = Camera.main.WorldToScreenPoint(mTarget);
// 将屏幕坐标转化为GUI坐标
mPoint = new Vector2(mScreen.x, Screen.height - mScreen.y);
}
void OnGUI() {
// 保证目标在摄像机前方
if (mScreen.z > 0) {
// 内部使用GUI坐标进行绘制
GUI.Label(new Rect(mPoint.x, mPoint.y, ContentWidth, ContentHeight), Value.ToString());
}
}
IEnumerator Free() {
yield return new WaitForSeconds(FreeTime);
Destroy(this.gameObject);
}
}
代码要点解析
- 坐标转换:根据Transform组件获取位置坐标,然后将此坐标转化为屏幕坐标及GUI坐标。
- Unity3D中常见的四种坐标系:
- 世界坐标:场景中物体的坐标,可使用
transform.position获得。 - 屏幕坐标:以像素来定义,屏幕的左下角为(0,0)点,右上角为(
Screen.width,Screen.height),Z的位置是以相机的世界单位来衡量的,如Input.mousePosition即为屏幕坐标。 - 视口坐标:视口坐标是标准的和相对于相机的,相机的左下角为(0,0)点,右上角为(1,1)点,Z的位置同样以相机的世界单位来衡量。
- GUI坐标:该坐标系以屏幕的左上角为(0,0)点,右下角为(
Screen.width,Screen.height)。
- 世界坐标:场景中物体的坐标,可使用
- 坐标转换流程:在代码中,我们先将世界坐标转化为屏幕坐标,再转化为GUI坐标。
代码使用步骤
将上述脚本绑定在一个空的游戏体上,并制作成预设,后续示例会使用这个预设。
三、实现角色攻击显示伤害值的具体步骤
场景需求
我们希望实现当角色攻击红色的胶囊体时,在游戏场景中显示玩家对胶囊体造成的伤害值。
实现步骤
- 给模型和胶囊体加上碰撞器,并勾选
IsTrigger使其成为一个触发器。分别将它们的tag设为Player和Enemy。 - 为
Enemy编写一个脚本:using UnityEngine; using System.Collections;
public class Enemy : MonoBehaviour { public GameObject PopupDamage;
void OnTriggerEnter(Collider mCollider) {
if (mCollider.gameObject.tag == "Player") {
// 克隆伤害弹出组件
GameObject mObject = (GameObject)Instantiate(PopupDamage, transform.position, Quaternion.identity);
mObject.GetComponent
<a id="heading-8-运行结果及问题说明"></a>
### 运行结果及问题说明
这里设定玩家对敌人造成的伤害值为20到40,运行程序后,由于使用的是非精确碰撞,导致程序一开始角色就和胶囊体发生了碰撞,而`OnTrigger()`方法只能在碰撞开始的时候捕捉碰撞,所以只显示了一次伤害值。不过我们关注的是伤害数值的显示,这个问题可暂时不追究。
<a id="heading-9-四-自定义伤害显示效果的思路"></a>
## 四、自定义伤害显示效果的思路
有朋友可能会问,为什么其他游戏里显示的伤害效果看起来那么眩目,而这个程序却只能显示普普通通的文字呢?这里给出两种思路供大家探究。
1. **使用GUISkin**:在项目中创建一个`GUISkin`,然后在`DamagePopup`脚本中添加一个`GUIStyle`类型的成员变量`mStyle`,通过该变量引用项目中创建的`GUISkin`,从而定义整体的GUI样式。将`OnGUI`中的方法修改为:
GUI.Label(new Rect(mPoint.x, mPoint.y, ContentWidth, ContentHeight), Value.ToString(), mStyle);
这样就能实现自定义的文字效果。
2. **使用贴图**:首先准备0 - 9的数字图片,然后将`Value`各个数位上的数字分别截取出来,根据截取的结果来绘制贴图,同样可以实现自定义的效果。
<a id="heading-10-五-总结"></a>
## 五、总结
今天的内容主要围绕Unity中伤害值显示的问题展开,从原理到代码实现,再到自定义效果的思路都进行了详细介绍。感谢大家关注我的博客,希望大家喜欢今天的内容。
<a id="heading-11-每日箴言"></a>
## 每日箴言
活得优雅些,别人压不垮你,内心的强大才是真正的强大。