Unity不均匀进度条

       在游戏中进度条的使用非常的多,经验条,任务进度,奖励进度等等。当数值达到很大的时候,经验条增长的速度可能会很慢,这对玩家的兴趣有消极作用。所有有时候会使用非线性增长的方式来处理,就是进度条的前一部分会增长的比较快,但是那只是表象,真正占比反而很少。如图,1000经验占了进度条比例的0.3

                                

        以下是代码,BarDefine绑定在进度条上。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

/**
* 控制进度条分段进度
*/

public class BarDefine : MonoBehaviour {

    [Header("调整控制进度条的分段")]
    public int m_sections;
    public float[] splits;
    public float[] values;
    public float num;

    private float realBarValue;  //真实的进度条的值//
    private List<float> realValues;  //存储分段后的各个部分的分阶值//

    private void Start() {
        Initializer(10000);
        Refresh(9999);
    }

    public void Initializer(int _maxValue) {
        realValues = new List<float>();
        for(int i = 0; i < m_sections; i++) {
            realValues.Add(_maxValue * values[i]);
        }
    }

    public float Refresh(int _currValue) {
        float tempValue = _currValue;
        int jieji = 0;
        float totalValue = 0;
        for(int i = 0; i < realValues.Count; i++) {
            totalValue += realValues[i];
            if(tempValue < totalValue) {
                jieji = i;
                break;
            }
        }
        realBarValue = 0;
        if(jieji > 0) {
            for(int i = 0; i < jieji; i++) {
                realBarValue += splits[i];
                tempValue -= realValues[i];
            }
        }
        if(tempValue > 0) {
            float leftvalue = 0;
            leftvalue = (tempValue / realValues[jieji]) * splits[jieji];
            realBarValue += leftvalue;
        }
        Debug.Log("realBarValue = " + realBarValue);
        if(realBarValue < 0)
            realBarValue = 0;
        if(realBarValue > 1)
            realBarValue = 1;
        return realBarValue;
    }






#if UNITY_EDITOR
    [CustomEditor(typeof(BarDefine),true)]
    public class BarDefineEditor : Editor {

        public override void OnInspectorGUI() {
            Color bgcolor = GUI.backgroundColor;
            //获取脚本对象
            BarDefine script = target as BarDefine;
            //script.m_sections = EditorGUILayout.TextField("text", script.m_sections);
            EditorGUILayout.LabelField("分成的份数", GUILayout.MaxWidth(150));
            GUILayout.BeginHorizontal();

            script.m_sections = EditorGUILayout.IntField("sections", script.m_sections);
            GUILayout.EndHorizontal();
            /*GUI.backgroundColor = Color.green;
            if(GUILayout.Button("Split", EditorStyles.miniButton, GUILayout.MaxWidth(50))) {
                GUILayout.BeginVertical();
                GUI.backgroundColor = bgcolor;
                script.splits = new float[script.m_sections];
                script.values = new float[script.m_sections];
                for(int i = 0; i < script.m_sections; i++) {
                    GUILayout.BeginHorizontal();
                    script.splits[i] = EditorGUILayout.FloatField("split_"+i, script.splits[i]);
                    script.values[i] = EditorGUILayout.FloatField("value_"+i, script.values[i]);
                    GUILayout.EndHorizontal();
                }
                GUILayout.EndVertical();
            }*/
            GUILayout.BeginVertical();
            float value0 = 0;
            float value1 = 0;
            for(int i = 0; i < script.m_sections; i++) {
                value0 += script.splits[i];
                value1 += script.values[i];
            }
            if(value0 == 1.0f && value1 == 1.0f) {
                GUI.backgroundColor = Color.green;
            } else {
                GUI.backgroundColor = Color.red;
            }
            if(script.splits.Length == 0) {
                script.splits = new float[script.m_sections];
                script.values = new float[script.m_sections];
            }
            EditorGUILayout.LabelField("请确保splits和values的分量加起来是 1.0f,且都不能为 0,后果自负");
            for(int i = 0; i < script.m_sections; i++) {
                GUILayout.BeginHorizontal();
                script.splits[i] = EditorGUILayout.FloatField("split_" + i, script.splits[i]);
                script.values[i] = EditorGUILayout.FloatField("value_" + i, script.values[i]);
                GUILayout.EndHorizontal();
            }
            GUILayout.EndVertical();
        }


    }
#endif
}

然后调用的代码如下.

public Slider slider;
public long currExp;
public long maxExp; 

    
void Start(){
    barDefine = gameObject.getComponent<BarDefine>();
}
   
private void FillBar(){
    if (barDefine != null) {
       barDefine.Initializer(maxExp);
       float value = barDefine.Refresh(currExp);
       slider.value = value;
   }
}

     

 使用Editor是为了方便更改设置,如图(需要确保进度条的值和比例加起来都是1),split为将进度条分成几段,values是每段所占总值的比例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值