[Unity] デューティ比を指定したオブジェクトの点滅

Posted on September 05, 2021  -  1 min read

ON/OFFの比率(デューティ比)を任意に指定してオブジェクトを点滅させたい場合、Mathf.Repeat()メソッドを使えば1行で実装できる。

var isShown = Mathf.Repeat(t, interval) > interval * (1 - dutyRatio);

Mathf.Repeat()は、指定された周期で繰り返す値を取得する周期関数のメソッドである。

public static float Repeat(float t, float length);

第1引数tに時刻、第2引数lengthに繰り返す周期を指定する。 戻り値には、0からlengthの間を繰り返した値が返される。

参考:Mathf-Repeat - Unity スクリプトリファレンス

返される値は0からlengthの範囲となるため、デューティ比による閾値にはlengthを掛ける必要がある。 また、デューティ比が0から1に大きくなるにつれて、ON時間が長くなる。

したがって、閾値は次の計算式となる。

interval * (1 - dutyRatio)

指定したオブジェクトを点滅させるスクリプト

以上を踏まえ、オブジェクトを指定したデューティ比で点滅させるスクリプトは次のようになる。

using UnityEngine;

internal class BlinkWithDutyRatio : MonoBehaviour
{
    [SerializeField] private GameObject _target;
    
    [SerializeField] private float _interval = 1;
    [SerializeField, Range(0, 1)] private float _dutyRatio;

    private float _startTime;

    private void Start()
    {
        _startTime = Time.time;
    }

    private void Update()
    {
        var t = Time.time - _startTime;
        var isShown = Mathf.Repeat(t, _interval) > _interval * (1 - _dutyRatio);

        _target.SetActive(isShown);
    }
}

点滅のさせ方は色々あるが、今回はゲームオブジェクト自体をSetActiveでアクティブ/非アクティブ切り替えられるようにした。

オブジェクトの配置

次の画像のように、子オブジェクトを点滅させるようにする。

ヒエラルキの構成例
ヒエラルキの構成例

画像のBlinkingObjectに上記スクリプトをアタッチし、Cubeを点滅させるようにする。

パラメータの設定

親(例ではBlinkingObject)にスクリプトをアタッチし、各種パラメータを設定する。

パラメータ設定
パラメータ設定

Targetに点滅対象のゲームオブジェクトを設定する。この時、自身のゲームオブジェクトを設定すると、一度非アクティブになってからスクリプトが走らずに消えたままになってしまうので注意すること。 Intervalに点滅間隔、Duty Ratioに0から1の範囲でデューティ比を指定して完了。

ここまでの手順を正しく行った状態で実行すると、狙ったデューティ比でオブジェクトが点滅するのを確認できる。

結論

オブジェクトを点滅させる処理は、if文のような条件分岐処理を書かないといけないと思われるが、 Mathf.Repeat()メソッドを使えば比較演算子だけで点滅処理が実現できる。

さらに、デューティ比を任意に変えながら点滅させるという自由まで手に入れられる。

かなり汎用的に使える手法で、様々な場面で活躍できるだろう。