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