[UnityUI]一些有趣的UI例子

1.环形进度条


[UnityUI]一些有趣的UI例子_第1张图片


2.图形匹配

[UnityUI]一些有趣的UI例子_第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.过渡血条,一般为深红色


[UnityUI]一些有趣的UI例子_第3张图片

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];
        }
    }  

}


你可能感兴趣的:(UGUI)