最新文章
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
ngui技能控制
由于本人之前比较喜欢玩LOL,所以想实现一个关于LOL技能释放的简单功能,包括按Q、W、E、R释放技能以及冷却时间倒计时等基础功能。接下来,我们先看看效果。
这里展示了德玛的技能效果。不过需要说明的是,第二张图可能有些不符常规,在原本的游戏中,4个技能通常是不能同时释放的。放这张图只是为了让大家更清晰地看到遮罩倒计时效果,大家可以忽略这一细节。下面,我们开始详细介绍实现过程。
1. 准备素材
需要准备4个技能图标和一张mask图(这张图可以在PS中制作,仅为一张纯色图)。
2. 通过NGUI制作技能控制UI
将准备好的5张图片选中,打包成Atlas。接着,制作一个Sprite用于放置技能图标,在这个Sprite下方再放置一个Sprite(使用mask图),并设置该mask的Sprite的透明度,以便能够看到下面的技能UI。同时,添加一个label用于显示倒计时。将这三个元素重叠在一起。关于具体的制作方法,大家可以参考siki老师的教程。
3. 设置maskSprite的Type类型
设置maskSprite的Type类型(具体设置如图所示),并设置fill dir。大家可以尝试改变amout的值,就能看到按比例旋转的效果(这里不太清楚该如何准确描述这种旋转,若有了解的朋友,欢迎告知)。
4. 完成技能UI复制
label的设置相对简单,这里就不多做介绍了。完成上述设置后,复制这组UI元素,即可得到4个技能UI。
5. 编写脚本部分
功能设计
本功能的设计目标是,根据LOL的按键规则,按下Q、W、E、R释放相应的技能。当某一技能释放后,其他技能通常不能触发,但存在例外情况,例如某些增加防御的技能可以与其他技能同时释放。具体来说,按下W键技能之后,还可以触发其他三个技能之一;而按下Q、E、R时,它们之间不能同时存在。
脚本优化思路
最初的脚本方案是为每个技能挂载一个脚本,获取mask的Sprite Script和Label的Script,当按下按键时调用相应技能的脚本。但这种方式存在问题,因为这4个技能的脚本基本相同,相当于编写了4个重复的类。为了优化这种情况,我们可以使用一个类,让每个技能都调用这个脚本。以下是优化后的脚本:
using UnityEngine;
using System.Collections;
public class SKillUIManager : MonoBehaviour
{
// 4个技能的类型
public enum SkillType
{
BigMask,
Defend,
SweepAttack,
KoAtttack
}
public PlayerSkillHandler skillHandlerScript; // 这个脚本控制着技能的释放
public SkillType skillType; // 技能的类型
public UISprite maskSpriteScript; // 遮罩的sprite script
public UILabel label; // 显示冷却的时间倒计时
private bool _isCooling = false; // 是否冷却
private bool _isSkill = false; // 是否释放技能
private float coolingTime; // 冷却时间
private float coolingTemp; // 这个也是冷却时间,不过是临时的,变化的,用来设计倒计时
public bool isSkill
{
set { _isSkill = value; }
get { return _isSkill; }
}
public bool isCooling
{
set { _isCooling = value; }
get { return _isCooling; }
}
void Start()
{
// 这里判断你的技能类型
maskSpriteScript.fillAmount = 0;
switch (skillType)
{
case SkillType.BigMask:
coolingTime = 10;
coolingTemp = 10;
break;
case SkillType.Defend:
coolingTime = coolingTemp = 15;
break;
case SkillType.SweepAttack:
coolingTime = coolingTemp = 20;
break;
case SkillType.KoAtttack:
coolingTime = coolingTemp = 200;
break;
}
label.gameObject.SetActive(false);
}
void Update()
{
if (isSkill)
{
// 释放了技能,技能进入冷却状态,判断是否冷却了,没有就设true
if (!_isCooling)
{
// 设置遮罩为1
maskSpriteScript.fillAmount = 1.0f;
_isCooling = true;
label.gameObject.SetActive(true);
}
if (_isCooling)
{
// 遮罩旋转效果
maskSpriteScript.fillAmount -= (1.0f / coolingTime) * Time.deltaTime;
// 倒计时
coolingTemp -= Time.deltaTime;
label.text = "" + (int)coolingTemp;
// 到达接近0时,把一些变量设为初始值
if (maskSpriteScript.fillAmount <= 0.01f)
{
_isCooling = false;
isSkill = false;
coolingTemp = coolingTime;
label.gameObject.SetActive(false);
maskSpriteScript.fillAmount = 0;
skillHandlerScript.isAttack = true;
}
}
}
}
}
这个脚本与之前的脚本相比,增加了一个枚举类型。在Start方法中,首先判断技能的类型,按下键盘后会触发相应的技能,并且在键盘控制类中只需要调用一个脚本的方法就可以实现4个技能的释放。下面是技能键盘控制类的脚本:
using UnityEngine;
using System.Collections;
public class PlayerSkillHandler : MonoBehaviour
{
public enum KeyCodes // 键盘值码
{
KEY_Q,
KEY_W,
KEY_E,
KEY_R,
KEY_F,
KEY_D,
KEY_B,
NULL
}
public KeyCodes currentKeyCode = KeyCodes.NULL;
public GameObject bigAttack;
public GameObject sweepAttack;
public GameObject koAttack;
public GameObject defend;
private bool _isAttack = true;
public bool isAttack
{
set { _isAttack = value; }
get { return _isAttack; }
}
void Start()
{
// 可根据需求添加初始化代码
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Q))
{
UsedTheSkill(PlayerSkillHandler.KeyCodes.KEY_Q);
}
if (Input.GetKeyDown(KeyCode.W))
{
UsedTheSkill(PlayerSkillHandler.KeyCodes.KEY_W);
}
if (Input.GetKeyDown(KeyCode.E))
{
UsedTheSkill(PlayerSkillHandler.KeyCodes.KEY_E);
}
if (Input.GetKeyDown(KeyCode.R))
{
UsedTheSkill(PlayerSkillHandler.KeyCodes.KEY_R);
}
}
/// <summary>
/// 使用技能
/// </summary>
public void UsedTheSkill(KeyCodes currentKey)
{
currentKeyCode = currentKey;
switch (currentKeyCode)
{
case KeyCodes.KEY_Q:
// 这里我们判断是否是冷却状态了,如果是就不能再触发
if (bigAttack.GetComponent<SKillUIManager>().isCooling)
return;
// 释放技能
bigAttack.GetComponent<SKillUIManager>().isSkill = true;
currentKeyCode = KeyCodes.NULL;
print("释放Skill...Q");
break;
case KeyCodes.KEY_W:
if (defend.GetComponent<SKillUIManager>().isCooling)
return;
currentKeyCode = KeyCodes.NULL;
defend.GetComponent<SKillUIManager>().isSkill = true;
print("释放Skill...W");
break;
case KeyCodes.KEY_E:
if (sweepAttack.GetComponent<SKillUIManager>().isCooling)
return;
sweepAttack.GetComponent<SKillUIManager>().isSkill = true;
currentKeyCode = KeyCodes.NULL;
print("释放Skill...E");
break;
case KeyCodes.KEY_R:
if (koAttack.GetComponent<SKillUIManager>().isCooling)
return;
koAttack.GetComponent<SKillUIManager>().isSkill = true;
currentKeyCode = KeyCodes.NULL;
print("释放Skill...R");
break;
default:
break;
}
}
}
脚本挂载与参数设置
将PlayerSkillHandler脚本挂载到panel下,并赋予相应的参数。同时,为每个技能挂载SKillUIManager脚本。
运行测试
完成上述步骤后,运行程序,按下QWER键,即可看到最开始展示的技能释放效果。如果大家想实现当一个技能进入冷却状态时,某些技能不能同时触发的功能,只需将键盘控制类脚本中的注释删除即可。
至此,这个模仿LOL技能释放效果的功能就完成了。如果大家在实现过程中发现任何问题,欢迎随时提出。