1.环形进度条
2.图形匹配
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.UI;
/// <summary>
/// 被拖拽的大方块
/// </summary>
public class DragBrick : MonoBehaviour {
private List<Transform> childrenTra = new List<Transform>();//大方块下的小方块
private List<GameObject> targetGo = new List<GameObject>();//小方块匹配的空方块
private GameObject[] tempGo;
private Vector3 posOffset;
void Start()
{
Transform[] tra = transform.GetComponentsInChildren<Transform>();
for (int i = 1; i < tra.Length; i++)//tra[0]是自身,故不算上
childrenTra.Add(tra[i]);
}
public void DragStart()
{
posOffset = transform.position - Input.mousePosition;
transform.SetAsLastSibling();
}
public void DragUpdate()
{
transform.position = Input.mousePosition + posOffset;
}
/// <summary>
/// 注意点:
/// 1.被射线检测的物体要带有Collider
/// 2.被射线检测的物体的z轴 > 发出射线检测的物体的z轴
/// 3.当没有给Raycast函数传layerMask参数时,仅仅只忽略使用IgnoreRaycast层的碰撞器。
/// </summary>
public void DragEnd()
{
tempGo = new GameObject[childrenTra.Count];
int suitableBrickAmount = 0;//能正确匹配的砖块数目
for (int i = 0; i < childrenTra.Count; i++)
{
RaycastHit hit;
if (Physics.Raycast(childrenTra[i].position, Vector3.forward, out hit))
{
tempGo[i] = hit.transform.gameObject;
suitableBrickAmount++;
}
else break;
}
if (suitableBrickAmount == childrenTra.Count)//完全匹配
{
if (targetGo.Count == 0)//初次完全匹配
{
Match();
}
else//已经完全匹配,再次完全匹配
{
Clear();
Match();
}
}
else//不能完全匹配
{
Clear();
}
}
void Match()
{
for (int i = 0; i < tempGo.Length; i++)
{
targetGo.Add(tempGo[i]);
targetGo[i].layer = 2;//忽略射线碰撞
Vector3 pos = targetGo[i].transform.position;
pos.z--;
childrenTra[i].position = pos;
childrenTra[i].GetComponent<Outline>().enabled = true;
}
}
void Clear()
{
for (int i = 0; i < targetGo.Count; i++)
targetGo[i].layer = 0;
targetGo.Clear();
for(int i = 0;i < childrenTra.Count;i++)
childrenTra[i].GetComponent<Outline>().enabled = false;
}
}
3.多重血条
描述:
1.当受到伤害较小时,出现“残血”效果
2.当受到伤害较大时,出现“流水”效果
3.多重血条主要由四种血条组成:
a.最底层血条
b.当前血条与下一血条,就像下图中的紫色和红色
c.过渡血条,一般为深红色
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
//如果只有一条血,那么一条血就是所有的血量
//如果有多条血,那么一条血就设定为一个固定值
public class MultiplyBloodBar : MonoBehaviour {
public Image nowBar;//当前血条
public Image middleBar;//过渡血条
public Image nextBar;//下一血条
public Text countText;//剩下的血条数text
private int count;//剩下的血条数(不包括当前血量)
private float nowBlood;//在一条血中的当前血量,如:100/1000则为100
private float oneBarBlood = 10000f;//一条血的容量,如:100/1000则为1000
private int colorIndex = 0;
public Color[] colors;//血条的颜色,注意Alpha值,默认为0
private float slowSpeed = 0.1f;//受到重伤时( >oneBarBlood)或者处于加血状态,当前血条的流动速度
private float quickSpeed = 1f;//受到轻伤时( <oneBarBlood),当前血条的流动速度
private float speed;//当前血条采用的速度
private float middleBarSpeed = 0.1f;//过渡血条的流动速度
private float nowTargetValue;//当前血条移动的目标点
private float middleTargetValue;//过渡血条移动的目标点
private bool isBloodMove = false;//控制血条的移动
void Update()
{
MoveNowBar();//当前血条的流动
MoveMiddleBar();//过渡血条的流动
}
/// <summary>
/// 传入总血量,初始化血条
/// </summary>
/// <param name="number"></param>
public void InitBlood(float number)
{
count = (int)(number / oneBarBlood);
nowBlood = number % oneBarBlood;
if (nowBlood == 0)
{
nowBlood = oneBarBlood;
count--;
}
colorIndex = count % colors.Length;
nowBar.color = colors[colorIndex];
nowBar.fillAmount = nowBlood / oneBarBlood;
if (count != 0)
{
int nextColorIndex = (colorIndex - 1 + colors.Length) % colors.Length;
nextBar.color = colors[nextColorIndex];
nextBar.gameObject.SetActive(true);
}
else
{
nextBar.gameObject.SetActive(false);
}
middleBar.gameObject.SetActive(false);
countText.text = count + "";
}
/// <summary>
/// 血量变化,并根据伤害判断是否使用过渡血条
/// </summary>
/// <param name="number"></param>
public void ChangeBlood(float number)
{
nowBlood += number;
nowTargetValue = nowBlood / oneBarBlood;
isBloodMove = true;
if ((number < 0) && (Mathf.Abs(number) <= oneBarBlood))//处于受伤状态并且伤害量较低时
{
speed = quickSpeed;
middleBar.gameObject.SetActive(true);
middleBar.transform.SetSiblingIndex(nextBar.transform.GetSiblingIndex() + 1);
middleBar.fillAmount = nowBar.fillAmount;
middleTargetValue = nowTargetValue;
}
else//处于受伤状态并且伤害量较大时,或者处于加血状态
{
speed = slowSpeed;
middleBar.gameObject.SetActive(false);
}
}
/// <summary>
/// 普通血条的流动
/// </summary>
void MoveNowBar()
{
if (!isBloodMove) return;
nowBar.fillAmount = Mathf.Lerp(nowBar.fillAmount, nowTargetValue, speed);
if (Mathf.Abs(nowBar.fillAmount - nowTargetValue) < 0.01f)//到达目标点
isBloodMove = false;
if (count == 0)
nextBar.gameObject.SetActive(false);
else
nextBar.gameObject.SetActive(true);
if (nowBar.fillAmount >= nowTargetValue)
SubBlood();
else
AddBlood();
}
/// <summary>
/// 过渡血条的流动
/// </summary>
void MoveMiddleBar()
{
//受到轻伤时( <oneBarBlood),才会出现过渡血条
if (speed == quickSpeed)
{
middleBar.fillAmount = Mathf.Lerp(middleBar.fillAmount, middleTargetValue, middleBarSpeed);
if (Mathf.Abs(middleBar.fillAmount - 0) < 0.01f)
{
middleBar.transform.SetSiblingIndex(nextBar.transform.GetSiblingIndex() + 1);
middleBar.fillAmount = 1;
middleTargetValue++;
}
}
}
void AddBlood()
{
float subValue = Mathf.Abs(nowBar.fillAmount - 1);
if (subValue < 0.01f)//到达1
{
count++;
countText.text = count.ToString();
nowBar.fillAmount = 0;
nowTargetValue -= 1;
nowBlood -= oneBarBlood;
nextBar.color = colors[colorIndex];
colorIndex++;
colorIndex %= colors.Length;
nowBar.color = colors[colorIndex];
}
}
void SubBlood()
{
float subValue = Mathf.Abs(nowBar.fillAmount - 0);
if (subValue < 0.01f)//到达0
{
//当前血条已经流动完,将过渡血条放置最前
middleBar.transform.SetSiblingIndex(nextBar.transform.GetSiblingIndex() + 2);
if (count <= 0)
{
middleBar.gameObject.SetActive(false);
Destroy(this);
return;
};
count--;
countText.text = count.ToString();
nowBar.fillAmount = 1;
nowTargetValue += 1;
nowBlood += oneBarBlood;
colorIndex--;
colorIndex += colors.Length;
colorIndex %= colors.Length;
nowBar.color = colors[colorIndex];
int nextColorIndex = colorIndex - 1 + colors.Length;
nextColorIndex %= colors.Length;
nextBar.color = colors[nextColorIndex];
}
}
}