【ベータ機能】setPostProcessEffectsを使って時間帯によって視界の雰囲気を変えてみよう

本記事はCluster Creator Kitの「ベータ機能」を利用した解説になります。
ベータ機能では正式リリース前の機能を使うことができます。正式リリース前のため、不安定な挙動をしたり将来的に挙動が変わる可能性があります。また、記事公開時点ではベータ機能として紹介していますが、その後正式リリースされている場合もありますので、本記事を参考にする場合はまずスクリプトレファレンスを参照することをおすすめします。

利用にはCluster Creator Kitでベータ機能を設定した状態でアップロードを行う必要があります。ワールドクラフトで利用する場合は、ワールドクラフトのワールドを新規作成する際にベータ機能の設定を行う必要があります。設定方法はこちらをご覧ください。

PlayerHandle.setPostProcessEffectsを使うと、ワールド内にいるプレイヤーに視覚効果(Post Process)を与えることができます。
今回はその作例として、アイテムの周囲にいるプレイヤーに時間帯に応じた効果を設定してみます。

まずは今回使用するスクリプトを紹介します。
ワールド内に作成したGameObjectか、クラフトアイテムとしてアップロードするアイテムに「Scriptable Item」コンポーネントを追加して、以下のスクリプトを設定してください。
作成したワールドやアイテムはベータ機能を有効にしてアップロードする必要があります。

const morningHour = 6;
const dayHour = 11;
const eveningHour = 19;
const nightHour = 22;


const setPostProcessEffectsInterval = 0.1;
const getPlayersNearDistance = 30;


function getMorningEffects() {
    let effects = new PostProcessEffects();
    effects.bloom.active = true;
    effects.bloom.threshold.setValue(0.0);
    effects.bloom.intensity.setValue(1.0);


    return effects;
};


function getDayEffects() {
    return null;
};


function getEveningEffects() {
    let effects = new PostProcessEffects();
    effects.bloom.active = true;
    effects.bloom.threshold.setValue(0.5);
    effects.bloom.intensity.setValue(0.8);
    effects.colorGrading.active = true;
    effects.colorGrading.colorFilter.setValue(1.0, 0.5, 0.3, 1);


    return effects;
};


function getNightEffects() {
    let effects = new PostProcessEffects();
    effects.bloom.active = true;
    effects.bloom.threshold.setValue(1.0);
    effects.bloom.intensity.setValue(2.0);
    effects.colorGrading.active = true;
    effects.colorGrading.colorFilter.setValue(0.3, 0.3, 0.3, 1);


    return effects;
};


function getJSTDate() {
    const date = new Date();
 
    // Etc/GMT-9の時刻へ変換 (時差+9時間)
    date.setTime(date.getTime() + 3600000 * 9);
 
    return {
        timezone: "Etc/GMT-9",
        hours: date.getUTCHours(),
        minutes: date.getUTCMinutes(),
        seconds: date.getUTCSeconds(),
    };
};


$.onStart(() => {
    $.state.queue = [];
    $.state.waitingTime = 0;
});


$.onUpdate((deltaTime) => {
    let waitingTime = $.state.waitingTime - deltaTime;
    if (waitingTime <= 0) {
        let hours = getJSTDate().hours;


        let effects = null;
        if (hours < morningHour) effects = getNightEffects();
        else if (hours < dayHour) effects = getMorningEffects();
        else if (hours < eveningHour) effects = getDayEffects();
        else if (hours < nightHour) effects = getEveningEffects();
        else effects = getNightEffects();


        let queue = $.state.queue;


        if (queue.length === 0) {
            queue = $.getPlayersNear($.getPosition(), getPlayersNearDistance);
        }


        let player = queue.shift();
        if (player) player.setPostProcessEffects(effects);


        $.state.queue = queue;


        waitingTime = setPostProcessEffectsInterval;
    }
    $.state.waitingTime = waitingTime;
});

スクリプトを設定したアイテムをワールドに設置すると、アイテムの周辺にいるプレイヤーに「朝」「昼」「夕方」「夜」の時間帯ごとに異なる視覚効果がかかるようになります。

アイテムから30m以内の範囲にいるプレイヤーにのみ適用されます。

「朝」の効果

function getMorningEffects() {
    let effects = new PostProcessEffects();
    effects.bloom.active = true;
    effects.bloom.threshold.setValue(0.0);
    effects.bloom.intensity.setValue(1.0);


    return effects;
};

「朝」の時間帯に適用する効果のパラメータを設定します。Bloomで朝の明るさを表現しています。
各パラメータの詳細はScript Reference過去の記事を参考にしてください。

「昼」の効果

function getDayEffects() {
    return null;
};

「昼」の時間帯の効果を設定します。昼間は特に効果をかけず標準の見た目にするため、効果のパラメータに「null」を設定して効果をリセットします。

「夕方」の効果

function getEveningEffects() {
    let effects = new PostProcessEffects();
    effects.bloom.active = true;
    effects.bloom.threshold.setValue(0.5);
    effects.bloom.intensity.setValue(0.8);
    effects.colorGrading.active = true;
    effects.colorGrading.colorFilter.setValue(1.0, 0.5, 0.3, 1);


    return effects;
};

「夕方」の時間帯の効果です。Bloomに加え、画面の色味を変えるColorGradingで夕焼けの色を表現しています。

「夜」の効果

function getNightEffects() {
    let effects = new PostProcessEffects();
    effects.bloom.active = true;
    effects.bloom.threshold.setValue(1.0);
    effects.bloom.intensity.setValue(2.0);
    effects.colorGrading.active = true;
    effects.colorGrading.colorFilter.setValue(0.3, 0.3, 0.3, 1);


    return effects;
};

「夜」の時間帯の効果です。BloomにThreshold(しきい値)を設定することで、特に明るく光っている場所だけにBloomが強くかかるようにします。またColorGradingで全体を暗くしています。

現在時刻を取得する

function getJSTDate() {
    const date = new Date();
 
    // Etc/GMT-9の時刻へ変換 (時差+9時間)
    date.setTime(date.getTime() + 3600000 * 9);
 
    return {
        timezone: "Etc/GMT-9",
        hours: date.getUTCHours(),
        minutes: date.getUTCMinutes(),
        seconds: date.getUTCSeconds(),
    };
};

現在時刻を日本時間で取得します。
Dateオブジェクトから直接現在時刻を取得してもいいのですが、プレイヤーのタイムゾーンによって挙動が変わる場合があるため、協定世界時(UTC)からの時差をもとに日本標準時(JST)を計算しています。(参考:時刻の取得とタイムゾーンに関する注意点

$.onUpdate((deltaTime) => {
    let waitingTime = $.state.waitingTime - deltaTime;
    if (waitingTime <= 0) {
        // 略(次で解説)
        waitingTime = setPostProcessEffectsInterval;
    }
    $.state.waitingTime = waitingTime;
});

setPostProcessEffectなどのplayerHandleに対して行う操作には頻度制限があるため、一定周期ごとに実行する仕組みを用意します。

let hours = getJSTDate().hours;


let effects = null;
if (hours < morningHour) effects = getNightEffects();
else if (hours < dayHour) effects = getMorningEffects();
else if (hours < eveningHour) effects = getDayEffects();
else if (hours < nightHour) effects = getEveningEffects();
else effects = getNightEffects();

時間帯に合わせた効果を取得します。
現在時刻の「時」を基準の時刻と比較し

  • 0~5時台は夜
  • 6~10時台は朝
  • 11~18時台は昼
  • 19~21時台は夕方
  • それよりあとは再び夜

として判定します。

基準の時刻はスクリプト冒頭に定数として定義されており、例えば

const morningHour = 6;

const morningHour = 9;

と書き換えれば「朝」の基準が9時に変わり、0~8時台が夜、9~11時台が朝になります。

効果を適用する

let queue = $.state.queue;


if (queue.length === 0) {
    queue = $.getPlayersNear($.getPosition(), getPlayersNearDistance);
}


let player = queue.shift();
if (player) player.setPostProcessEffects(effects);


$.state.queue = queue;

$.stateに保存したプレイヤー一覧を取得し、一覧が空であれば$.getPlayersNear()で周囲のプレイヤーのPlayerHandle一覧を取得します。
shift()で一覧から要素をひとつ取得し、同時にその要素を一覧から削除することができます。ここでは一覧からPlayerHandleをひとつ取り出し、そのプレイヤーにPostProcessを適用しています。
要素を取り出して更新されたプレイヤー一覧は$.stateに保存しておきます。

一覧が空になるたびに周囲のプレイヤー一覧を取得することで、常に周囲のプレイヤーに対して効果の更新を続けます。


setPostProcessEffectを使ってPost Processを変更すると視界全体の雰囲気を変えることができます。今回のように時間帯で変化させたり、例えばゲームの進行や残りHPによって異なる効果がかかるようにしたりといった使い方もできます。
スクリプトを使うと複雑な判定や細かなパラメータ調整などもでき、組み合わせることで表現力を高めることができるので試してみましょう!

記事をシェアしてワールド制作を盛り上げよう!

Cluster Creators Guide|バーチャル空間での創作を学ぶならをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む