6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

VRChatでTimelineが使えないからUdonSharpでゴリ押ししてみた

6
Posted at

VRChatでTimelineが使えないからUdonSharpでゴリ押ししてみた

最終的にこんなの作りました

Unity2018からVRChatでTimelineが使えなくなった

Unity2017時代のVRChatではTimelineが使えました。

パーティクルライブのように、音楽に合わせてオブジェクトの表示/非表示を切り替えるようなワールドを作るときに、Timelineは非常に有効です。

ただ、VRChatがUnity2018に移行してから、このTimelineが使えなくなってしまいました。

UdonSharpでゴリ押ししてみることにした

Timelineに相当する処理を自前で実装することにしました。

ちょうどUdonSharp(U#)を勉強中だったので、U#でやってみることにしました。

U#の開発環境構築については、こちらがわかりやすかったです。

U# 入門 ①

Udonで実装してみた

完成したコードがこちらです。

using UdonSharp;
using UnityEngine;
using UnityEngine.UI;
using VRC.SDKBase;
using VRC.Udon;

public class PseudoTimeline : UdonSharpBehaviour
{
    //ボタンラベル
    public Text buttonLabel;

    //制御対象のゲームオブジェクトのリスト
    public GameObject[] cylinder;

    //表示開始時間のリスト
    public float[] startTime;

    //再生時間のリスト
    public float[] duration;

    //経過時間
    [UdonSynced(UdonSyncMode.None)]
    private float currentTime;

    //再生中フラグ
    [UdonSynced(UdonSyncMode.None)]
    private bool isPlaying;

    void Start()
    {
        //停止中にする
        isPlaying = false;
    }

    public override void Interact()
    {
        //ボタンに対するオーナーを変更
        if (!Networking.IsOwner(Networking.LocalPlayer, this.gameObject))
        {
            Networking.SetOwner(Networking.LocalPlayer, this.gameObject);
        }

        //経過時間を初期化
        currentTime = 0.0f;

        //停止中と再生中を反転
        isPlaying = !isPlaying;
    }

    private void Update()
    {
        if (isPlaying)
        {
            //ボタンラベルを切り替え
            buttonLabel.text = "■";

            //経過時間をカウントアップ
            currentTime += Time.deltaTime;

            for (int i = 0; i < cylinder.Length; i++)
            {
                //表示開始
                if (currentTime > startTime[i])
                {
                    cylinder[i].SetActive(true);
                }

                //表示終了
                if (currentTime > startTime[i] + duration[i])
                {
                    cylinder[i].SetActive(false);
                }
            }
        }
        else
        {
            //ボタンラベルを切り替え
            buttonLabel.text = "▶";

            //すべて非表示にする
            for (int i = 0; i < cylinder.Length; i++)
            {
                cylinder[i].SetActive(false);
            }
        }
    }
}

適当なCubeに、 Udon Behaviour をアタッチして、 Source Script に上記のコードを設定してください。

Public Variablesを設定する

以下の図のようにPublic Variablesを設定します。
image.png

Button Label には適当なTextを作成して割り当ててください。再生中なら 、停止中なら になります。

Cylinder には、表示/非表示を切り替えたいGameObject達を設定します。私は円柱のオブジェクトを5つ用意して割り当てました。

Start Time は、各GameObjectの表示開始時間です。 Cylinder と同じ数だけ必要です。

Duration は、各GameObjectの再生時間です。 Cylinder と同じ数だけ必要です。表示終了時間は表示開始時間にこの再生時間を加算した時間になります。

結果

以下のような簡易パーティクルライブが作成できました。

UdonSyncedについて

isPlayingcurrentTime のアトリビュートに [UdonSynced(UdonSyncMode.None)] を付けてます。

これによって、複数のユーザーが同時にパーティクルライブを視聴できるようになります。

さいごに

本記事作成にあたり、以下の記事を参考にしました。ありがとうございました。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?