//tips
//boolの使われ方
boolはtrueまたはfalseを値に持つためifの条件などによく使用される。さらに、boolの切り替えが発生する条件を書くことが多く、初期条件設定、切り替え、boolの条件化など複数のif分岐内で一つのboolを活用することが多い。
例えば、下記のようにMaxMoneyをboolとして宣言し、Moneyの値でboolを切り替え、boolがtrueの場合にのみ発生する条件式を作ることができる。
int Money;
bool MaxMoney;
if(Money <= 1000)
{
bool MaxMoney = true;
}
if(MaxMoney == true)
{
Money = 1000;
}
また、boolをメソッドにしてしまうやり方もあり、bool IsDisplayComplete()でtrue,falseを生成し、それをTextUpdateのifの条件として使用している。
public void TextUpdate(bool _IsPush)
{
if (IsDisplayComplete())
{
//最後の文章ではない & ボタンが押された
if (currentSentenceNum < sentences.Length && _IsPush)
{
SetNextSentence();
}
else if (currentSentenceNum >= sentences.Length)
{
finished = true;
currentSentenceNum = 0;
}
}
else
{
if (_IsPush)
{
timeUntilDisplay = 0;
}
}
}
bool IsDisplayComplete()
{
return Time.time > timeBeganDisplay + timeUntilDisplay;
}
//コルーチンとは
コルーチンとは、実行を停止して Unity へ制御を戻し、その次のフレームで停止したところから続行することができる関数である。
関数は関数内に書かれていることは全て一つのフレーム内で実行されてしまうので、時間経過で値が変化するものは一つの関数内で完結させることはできない。
例えば、オブジェクトの透明度を徐々に減少させる下記のコードを書いても実際には一瞬で透明になってしまう。
void Fade()
{
for (float f = 1f; f >= 0; f -= 0.1f)
{
Color c = renderer.material.color;
c.a = f;
renderer.material.color = c;
}
}
このような状況はUpdate 関数にコードを追加して、フレームごとに処理することも可能だが、このようなタスクはコルーチンを使用するとより楽に処理できる。
IEnumerator Fade()
{
for (float f = 1f; f >= 0; f -= 0.1f)
{
Color c = renderer.material.color;
c.a = f;
renderer.material.color = c;
yield return null;
}
}
IEnumerator が戻り値の型で、yield return の行が実行を停止して次のフレームから実行を継続する位置となる。
止めた後のコルーチンを実行するには StartCoroutine 関数を使用する。
void Update()
{
if (Input.GetKeyDown("f"))
{
StartCoroutine("Fade");
}
}
タスクがそれほど頻繁に繰り返す必要がない場合は、コルーチンに入れることで毎フレーム実行することなく定期的に更新することができるようになる。
停止処理を行うyieldにも様々な種類があり、
・yield return null; 1フレーム処理を中断し、再開
・yield return new WaitForSeconds( num ); num秒間の間処理を中断
・yield break; コルーチンを途中で終了、再開はされない
・yield return new WaitUntil(再開条件); 再開条件に指定した関数がtrueを返すと再開
・yield return new WaitWhile(待機条件); 待機条件にした関数がfalseを返すと再開
などがある。
yield return new WaitUntil(() => Input.GetMouseButtonDown(0)); とすることでクリック待ち処理となるなど少し特殊な要素もある。
Cubeの色を変える下記のコルーチンを実行した。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
void Start()
{
StartCoroutine("ChangeColor");
}
IEnumerator ChangeColor()
{
//赤色にする
gameObject.GetComponent<Renderer>().material.color = Color.red;
//3秒停止
yield return new WaitForSeconds(3);
//青色にする
gameObject.GetComponent<Renderer>().material.color = Color.blue;
}
}
青色に変えないようにするのにyield break;を入れても良い。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
void Start()
{
StartCoroutine("ChangeColor");
}
IEnumerator ChangeColor()
{
//赤色にする
gameObject.GetComponent<Renderer>().material.color = Color.red;
//中断
yield break;
//青色にする
gameObject.GetComponent<Renderer>().material.color = Color.blue;
}
}
コルーチンをつなげて実行することも可能で色を3種類に変化させてみる。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
void Start()
{
StartCoroutine("ChangeColor1");
}
IEnumerator ChangeColor1()
{
//赤色にする
gameObject.GetComponent<Renderer>().material.color = Color.red;
//1秒停止
yield return new WaitForSeconds(1);
//もう一つのコルーチンを実行する
StartCoroutine("ChangeColor2");
}
IEnumerator ChangeColor2()
{
//青色にする
gameObject.GetComponent<Renderer>().material.color = Color.blue;
//1秒停止
yield return new WaitForSeconds(1);
//黄色にする
gameObject.GetComponent<Renderer>().material.color = Color.yellow;
}
}
次にクリック動作でコルーチンを制御する。
using System.Collections;
using UnityEngine;
public class Story1 : MonoBehaviour
{
IEnumerator Start()
{
Debug.Log("ファースト");
yield return new WaitUntil(() => Input.GetMouseButtonDown(0));
yield return null;
Debug.Log("セカンド");
yield return new WaitUntil(() => Input.GetMouseButtonDown(0));
yield return null;
Debug.Log("ラスト");
}
}
コルーチンを利用してUIのテキストを変えてみる。
canvasの下のimageの中にtextを作成し、そこに文言表示を行う。
using System.Collections;
using UnityEngine;
public class Story1 : MonoBehaviour
{
[SerializeField] UnityEngine.UI.Text textbox;
IEnumerator Start()
{
textbox.text = "ファースト";
yield return new WaitUntil(() => Input.GetMouseButtonDown(0));
yield return null;
textbox.text = "セカンド";
yield return new WaitUntil(() => Input.GetMouseButtonDown(0));
yield return null;
textbox.text = "ラスト";
}
}
[SerializeField] UnityEngine.UI.Text textbox;の部分にヒエラルキーからtextオブジェクトをドラッグして実行する。