とりあえず上昇するやつ
UnityのSliderの作り方は、ググレば出てくるので、説明しないよ
using UnityEngine;
using UniRx;
using UnityEngine.UI;
using System;
public class GargeUniRx : MonoBehaviour
{
[SerializeField]
Slider Slider;
// 現在値
[SerializeField]
int StartPoint = 0;
// 追加分
[SerializeField]
int AddPoint = 100;
// MAX値
[SerializeField]
int MaxPoint = 200;
// ゲージの進む速度
[SerializeField]
double MoveTime = 0.2d;
// ゲージの伸び幅
[SerializeField, Range(0.01f, 1f)]
float GargeAddValue = 0.05f;
bool GargeEnd = false;
void Start()
{
float currentValue = (float)StartPoint / MaxPoint;
Slider.value = currentValue;
float endValue = (float) (StartPoint + AddPoint) / MaxPoint;
GargeObservable(MoveTime).Subscribe(_ => {
// 伸びーる
Slider.value += GargeAddValue;
if(Slider.value >= endValue) {
Slider.value = endValue;
GargeEnd = true;
}
});
}
// UnirRxってIntervalしかつかってなくね?
IObservable<long> GargeObservable(double _time)
{
return Observable.Interval(TimeSpan.FromSeconds(_time)).TakeWhile(_ => !GargeEnd);
}
}
StartPoint
AddPoint
MaxPoint
は
inspectorでいじる目的
※リスタート処理作っていないので、確認するのに、いちいちUnity停止 > Unity再生する必要があるけど
ゲージの Start値
が End値
より小さくて、End値
が大きいなら、これだけでいい
ただ、(ゲームとかで)よくあるのが、
ゲージが上がりきって、再度0から残りの分のゲージを上げる(レベルアップして最初からにする)処理について
(StartPoint + AddPoint) / MaxPoint
が 1より大きいのなら、ゲージが1周するわけで
周回(ループ)する回数を算出すればいい
何言ってんだこいつ?
ゲージが伸び切った(SliderのValueが1fに到達した)ら、
SliderのValueを 0f
にする
void Start()
{
float currentValue = (float)StartPoint / MaxPoint;
Slider.value = currentValue;
float endValue = (float) (StartPoint + AddPoint) / MaxPoint;
GargeObservable(MoveTime).Subscribe(_ => {
// 伸びーる
Slider.value += GargeAddValue;
if(Slider.value >= 1f) {
Slider.value = 0f;
endValue -= 1f;
}
if(Slider.value >= endValue) {
Slider.value = endValue;
GargeEnd = true;
}
});
}
ゴリゴリのif文で、美しくないが、
リスタートのときに、一緒に endValue
を -1f
してあげればいい
とりあえず減少するやつ
上昇するときと、やることはたいして変わらない
処理を逆にすればいい
void Start()
{
float currentValue = (float)StartPoint / MaxPoint;
Slider.value = currentValue;
float endValue = (float) (StartPoint + AddPoint) / MaxPoint;
GargeObservable(MoveTime).Subscribe(_ => {
// 縮ーむ
Slider.value -= GargeAddValue;
if(Slider.value <= 0f) {
Slider.value = 1f;
endValue = 1f - (endValue + 1f);
}
if(Slider.value <= endValue) {
Slider.value = endValue;
GargeEnd = true;
}
});
}
上昇の時と違って、
リスタートの時の endValue
は、ゲージMAX(1f)から始まるので、計算がちょっと違う
そんな初歩的なことに、ハマったうんこがここにいるらしい
UniRx全然使っていないし、こんな糞コード晒して恥ずかしくないんですか?
そうだね
じゃあSliderのValueを監視するのをUniRxにしてみようか
// ゲージの値を監視(1fか0fになったら実行される)
IObservable<long> GargePoliceObservable()
{
return Observable.EveryUpdate().Where(_ => {
if(AddPoint > 0)
return Slider.value >= 1f;
else
return Slider.value <= 0f;
}).TakeWhile(_ => !GargeEnd);
}
Start
はこんな感じになる(ゲージ上昇)
void Start()
{
float currentValue = (float)StartPoint / MaxPoint;
Slider.value = currentValue;
float endValue = (float) (StartPoint + AddPoint) / MaxPoint;
GargeObservable(MoveTime).Subscribe(_ => {
// 伸びーる
Slider.value += GargeAddValue;
if(Slider.value >= endValue) {
Slider.value = endValue;
GargeEnd = true;
}
});
GargePoliceObservable().Subscribe(_ => {
Slider.value = AddPoint > 0 ? 0f : 1f;
endValue = AddPoint > 0 ? endValue - 1f : 1f - (endValue + 1f);
});
}
1つの処理に、ガッツリ書くのと大差ない気がする
気分の問題かな?
でもMAX値って変動するよね?
たしかに
RPGとかの経験値テーブルとかは、
- レベル1からレベル2になるのに 200
- レベル2からレベル3になるのに 250
みたいに固定値じゃない
なら頑張って計算してみよう
static readonly Dictionary<int, int> ExpTableList = new Dictionary<int, int>() {
// レベル , 次のレベルに上がるのに必要なポイント
{1, 100 },
{2, 150 },
{3, 200 },
{4, 300 },
{5, 400 },
};
[SerializeField, Range(1, 5)]
int CurrentLevel = 1;
float GetCurrentValue()
{
if(!ExpTableList.ContainsKey(CurrentLevel)) {
return 1f;
}
return (float)StartPoint / ExpTableList[CurrentLevel];
}
float GetEndValue()
{
int count = AddPoint > 0 ? 1 : -1;
int tmpStartPoint = StartPoint;
int tmpAddPoint = AddPoint;
float retval = 0f;
// ゲージ上昇のときだけ
for(int level = CurrentLevel; level < ExpTableList.Count; level += count) {
if(!ExpTableList.ContainsKey(level)) {
break;
}
int maxPoint = ExpTableList[level];
// 必要ポイントより現在値と加算値が大きいなら1fになるね
if(maxPoint <= tmpStartPoint + tmpAddPoint) {
retval += (1f - tmpStartPoint / maxPoint);
} else {
retval += (float)(tmpStartPoint + tmpAddPoint) / maxPoint;
}
tmpAddPoint -= (maxPoint - tmpStartPoint);
if(tmpAddPoint <= 0) {
break;
}
// 1周したのなら、開始値は0にする
tmpStartPoint = 0;
}
return retval;
}
レベル毎に1回ごとに Value値を加算しているだけ
ゲージが上昇する場合なら、+1レベルしていく
ゲージが減少する場合なら、-1レベルしていく
しかしコード汚いなぁ
もっと綺麗に書けないものか