zoukankan      html  css  js  c++  java
  • [UnityUI]一些有趣的UI样例

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


  • 相关阅读:
    将make的输出重定向到文件
    ubuntu mount u盘以及cp拷贝文件夹
    Emacs Tutorial摘录
    c#实现每隔一段时间执行代码(多线程)
    socket.BeginReceiveFrom异步接收信息时,回调函数无法正常进入
    23个C#实用技巧
    C#中实现Form的透明属性变化即渐隐效果
    C#键位定制:设置一个文本框只能输入数字键
    byte 与 bit 的转换
    C# Socket UDP 案例 2
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/6869506.html
Copyright © 2011-2022 走看看