DEV Community

Cover image for VRChatでTimelineが使えないからUdonSharpでゴリ押ししてみた
Shoichi Okaniwa
Shoichi Okaniwa

Posted on • Originally published at qiita.com

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

Introduction

I created a workaround for the absence of Timeline in VRChat by using UdonSharp to manually control when objects appear and disappear based on time.

Here's what I ended up creating:

Unity2018 and the Loss of Timeline in VRChat

In the VRChat days of Unity2017, you could use Timeline effectively for creating worlds where object visibility aligned with music, like a particle live show. However, Timeline became unavailable in VRChat after the transition to Unity2018.

Attempting with UdonSharp

I decided to create my own implementation of Timeline functionality. While learning UdonSharp (U#), I attempted this using U#.

A handy guide for setting up the UdonSharp development environment was U# Intro ①.

Implementing with Udon

Here is the completed code:

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

public class PseudoTimeline : UdonSharpBehaviour
{
    // Button label
    public Text buttonLabel;

    // List of game objects to control
    public GameObject[] cylinder;

    // List of start times
    public float[] startTime;

    // List of durations
    public float[] duration;

    // Elapsed time
    [UdonSynced(UdonSyncMode.None)]
    private float currentTime;

    // Playing flag
    [UdonSynced(UdonSyncMode.None)]
    private bool isPlaying;

    void Start()
    {
        // Start as stopped
        isPlaying = false;
    }

    public override void Interact()
    {
        // Change owner for the button
        if (!Networking.IsOwner(Networking.LocalPlayer, this.gameObject))
        {
            Networking.SetOwner(Networking.LocalPlayer, this.gameObject);
        }

        // Initialize elapsed time
        currentTime = 0.0f;

        // Toggle between play and stop
        isPlaying = !isPlaying;
    }

    private void Update()
    {
        if (isPlaying)
        {
            // Change button label
            buttonLabel.text = "■";

            // Count up elapsed time
            currentTime += Time.deltaTime;

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

                // Stop showing
                if (currentTime > startTime[i] + duration[i])
                {
                    cylinder[i].SetActive(false);
                }
            }
        }
        else
        {
            // Change button label
            buttonLabel.text = "▶";

            // Hide everything
            for (int i = 0; i < cylinder.Length; i++)
            {
                cylinder[i].SetActive(false);
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Attach Udon Behaviour to a suitable Cube and set the Source Script to the above code.

Setting Public Variables

Set the Public Variables as shown below:

image.png

Create and assign an appropriate Text to Button Label. It changes to when playing and when stopped.

For Cylinder, set the GameObjects you wish to toggle visibility for. I prepared five cylinder objects.

Start Time specifies the show start time for each GameObject. You need the same amount as Cylinder.

Duration is the play time for each GameObject. You need the same number as Cylinder. The hide end time is the start time plus this duration.

Results

A simple particle live presentation can be created as shown below:

About UdonSynced

The attributes [UdonSynced(UdonSyncMode.None)] are attached to isPlaying and currentTime. This allows multiple users to view the particle live simultaneously.

Conclusion

In writing this article, I referred to the following articles. Thank you.

Top comments (0)