VRChat Creators Roadmap (March 2026)

Welcome to 2026! We’re excited to give you an update on new and upcoming features for VRChat world and avatar creators.

Please remember that it’s not a complete list - it doesn’t include every change, our plans might change, and new features might make it in before they’re announced here.

Completed Roadmap Items

We improved VRChat’s audio system with Steam Audio, replacing ONSP. Your worlds and avatars might sound slightly different now - please check last December’s Developer Update for more details.

Status Name
Complete Replace ONSP with Steam Audio[1]

We also implemented a few minor features that weren’t mentioned on our previous roadmap:

Status Name Description
Complete[1:1] Add “Unique Random” playback order to the Animator Play Audio state behaviour Play random sounds without repeating the same random sound twice in a row.
Complete[1:2] Add/Expose EventTiming.PostLateUpdate, EventTiming.FixedUpdate, and Behaviour.isActiveAndEnabled to Udon These changes make your Udon scripts more versatile and powerful.
Complete[1:3] Improve VRCPlayerAPI.GetPlayers Get a list of players without needing to provide an array as a parameter.

Read our SDK release notes for more details.

New Roadmap

The new roadmap includes the following features:

:red_exclamation_mark:This roadmap was created in March 2026. All items are subject to change!

Status Name
In progress[2] Add a ‘Box’ ShapeType (New!)
In progress[2:1] Add raycast component to avatars SDK (New!)
In progress[2:2] Implement custom “global” physbone colliders (New!)
In progress[2:3] VRCTween (New!)
In progress[2:4] Expose VRC+ status to Udon (New!)
In progress[2:5] Soba
In progress[2:6] Avatar optimizer
Planned [3] World analytics (New!)

Click on the blue URLs above to see more information in the associated feedback posts.

Let’s go into a bit more detail about some of the roadmap items:

Soba

We’re still working on Soba! We’re currently hard at work getting it ready for closed beta testing, so we don’t have a detailed preview to share with you this time.

However, we thought you might enjoy seeing some of our work-in-progress technical documentation! Here’s a table showing which C# language features Soba and UdonSharp currently support:

Soba - C# Language Features (Click to expand)

The following chart lists features of C# 9.0, along with their support in both UdonSharp and Soba:

CategoryFeatureUdonSharpSoba
Classesdefining behaviors
defining behaviors
defining non-behavior classes
defining abstract classes
defining sealed classes
defining partial classes
defining nested types
defining outside a file with the same name
Structuresdefining
Interfacesdefining
implementing
Type systempolymorphism
value types & reference types
nullable types
Genericscalling generic methods
using generic types
defining generic types
Methodsdefining instance methods
recursionPartial
defining static methods
defining constructors
defining static constructors
defining destructors
defining properties
defining indexers
`event` (not Unity/VRChat events)
delegates
lambdas
nested functions
extension methods
operator overloading
named parameters
optional parameters
`ref` & `out` parameters
Iteratorsdefining
`yield`
Control flow`if`/`else`
`switch` statements
`switch` expressions
pattern matching
`for`, `while`, `do`...`while`
`foreach`
`break`, `continue`, `return`
`goto`
Operatorsarithmetic (unary `+`/`-`, `*`, `/`, `%`, `+`, `-`)
logical (`&&`, `\|\|`)
bitwise (unary `~`, `&`, `\|`, `^`, `<>`)
logical shift right (`>>>`)
relational (`==`, `!=`, `<`, `>`, `<=`, `>=`)
ternary (`cond ? ifTrue : ifFalse`)
type-testing (`is`)
casts (C-style)
casts (`as`)
null-coalescing (`??`)
null-coalescing assignment (`??=`)
range (`x..y`)
increment (`++x`, `x++`, `--x`, `x--`)
assignment (`=`, `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `\|=`, `^=`, `<>=`, `>>>=`)
logical shift right and assign (`>>>=`)
Exception handling`try`/`catch`/`finally`
`using` & `IDisposable`
Data typesinteger types (`byte`, `sbyte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`)
floating-point types (`float`, `double`)
arrays
non-generic collections
generic collections
LINQ
Tuples
anonymous types
dynamic types
Reflectiondefining attributes
`System.Reflection` library
`GetType()` method
expression trees
Preprocessorpreprocessor directives
defining symbols
conditional compilation
nullable contexts
Name resolutiondefining namespaces
`using` directives
Native codeunsafe code
P/Invoke
COM interop
`stackalloc`

Please keep in mind that this list might change before (or after) Soba releases! Once it’s out, you’ll find an up-to-date list in our documentation.

New avatars features

We’re implementing a few small avatar feature requests:

  • Currently, contacts can only be sphere-shaped or capsule-shaped. This isn’t ideal for all types of interactions - for example, if a world or an avatar has square buttons that players can press with their fingers. Box-shaped contacts should be a neat addition that makes contacts more versatile and useful.
  • Raycasts allow avatars to - for example - point at something with their hand, and make something appear at that location. FinalIK can already do this - but it’s a paid asset, and not optimized for non-PC avatars. We’re making raycasts an official feature of our avatars SDK, and they’re available on Android & iOS, too!
  • We’re also working on global avatar colliders. Currently, only your avatar’s built-in hand and finger colliders are “global”, allowing you to interact with PhysBones that aren’t on your avatar. We’re working on the ability to add more global colliders and choose whether these colliders can interact with other avatars, worlds, and/or items. So many options!

You’ll gain access to box-shaped contacts and global avatar colliders very soon! We’re preparing to release them with our upcoming SDK.

VRCTween

Tweening is a term from animation, short for ‘in-betweening’. In a classic animation studio, a lead animator would draw the ‘key frames’ of an animation like the walk cycle above, and junior animators would draw all the frames in-between these key frames to create a fluid animation without tying up the lead with this work.

VRChat worlds have to solve similar problems all the time - you may want to move an object smoothly, enlarge a text element, or make a button flash red. You can already use Unity animations or Udon for tweening, but it’s usually slow and requires a lot of manual work.

The new VRCTween class provides new nodes and events that make tweening much more convenient.

For example, here’s an Udon graph script that uses TweenPosition to smoothly move a GameObject to another position, and triggers a custom event once it’s done. (Without any update loops or Unity animations!)

Here’s the same example in UdonSharp:

Click to expand
using UdonSharp;
using UnityEngine;
using VRC.SDK3.Components;
using VRC.Udon.Common.Interfaces;

public class TweenCompareTest : UdonSharpBehaviour
{
    public GameObject cube;

    void Start()
    {
        // Calculate position
        Vector3 targetPosition = cube.transform.position + new Vector3(0, 1, 0);
        
        // Start Tween
        int tweenId = VRCTween.TweenPosition(cube, targetPosition, 3f, VRCTween.Ease.IN_OUT_SINE);

        // Track completion
        VRCTween.OnComplete(tweenId, (IUdonEventReceiver)this, "OnAnimationComplete");
    }

    public void OnAnimationComplete()
    {
        Debug.Log("Animation complete!");
    }
}

And that’s not all - you can also tween floats, vectors, quaternions, and more. VRCTween is based on DOTween and brings much of the same functionality. We hope you’ll enjoy using it!

World analytics

This feature was requested almost eight years ago - and by none other than the founder of VRChat. (Check out the original feature request on our Canny feedback board.)

Currently, world creators only have access to their world’s current visitors and total number of visits/favorites. That’s… not much. And it may leave you with many questions, such as:

  • Are visits increasing over time? Are users coming back?
  • How long do users usually stay? Is your world engaging?
  • How large are instances usually? Does your world need to fit more users?
  • How many of your users don’t speak English? Should you translate your world?
  • Does your world have performance issues? If yes, on what platform?

We want to give world creators access to analytics to help them find the answers. This makes it easier to improve your world, and to measure those improvements.

Don’t get too excited yet, because there are several important caveats:

  • We want to start simple. Don’t expect a fully-fledged analytics suite.
  • We have to test this feature with a small group of creators first, for various reasons. It may take a while before we can give most world creators access to world analytics.
  • World analytics will be somewhat limited for privacy reasons. It won’t include advanced features or custom events.
  • We’re still in the planning stages for world analytics. Our plans may change!

That said, we know you’re probably excited about world analytics, and we hope you enjoy hearing that we’ll be working on it. We’ll share more information about it in the future.

Other features

This is not a complete list! It doesn’t include:

Got questions?

  • Visit feedback.vrchat.com to be notified about status changes for any feature you upvoted or commented on.
  • Our bi-weekly dev updates are where we usually go in-depth about how these features work.
  • And, of course, once a feature is released, read the SDK release notes and documentation to learn more.

  1. “Complete” means that this feature is done and released to everyone on the main version of VRChat. ↩︎ ↩︎ ↩︎ ↩︎

  2. “In Progress” means that the feature is getting active development work! We are building the feature and performing internal testing and feedback cycles. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  3. “Planned” means that we haven’t started major development on the feature, but we plan on working on it. The feature may require some design and scoping work. ↩︎

10 Likes

Will VRCTween have the possibility to tween using animation curves?
If not I would love if we could! That allows for a lot of customisation when tweening, especially when used to in combination with LerpUnclamped you can currently do some nice over bounce stuff.

This is something I’m currently doing for my UI System:
https://fixupx.com/DrBlackRat/status/1960443806462984363/video/1

4 Likes

The initial release does not support arbitrary animation curves, but supports all the Ease types that DOTween provides:

  • Linear
  • Sine
  • Quad
  • Cubic
  • Quart
  • Quint
  • Expo
  • Circ
  • Elastic
  • Back
  • Bounce

For all the types besides linear, you can use the In, Out, or In/Out version. In the demo video you shared, the movement looks similar to an In/Out tween like Cubic or Quad.

1 Like

I didn’t see it explicitly mentioned under the preprocessor directives section. Is Soba going to support proper asmdef version defines inside soba scripts?

It’s been something udon has sorely been lacking and is an absolute necessity (IMO) for community package maintainers.

6 Likes

OOOoo! Proper global colliders. Will be happy to see the hacky workarounds deprecated. Right now the global colliders are achieved through moving the existing hand and finger colliders around ~ mega cursed: Global Collider | Modular Avatar

3 Likes

Are these also being added to world Physbones, been holding out hope for the ability for things like floors and walls to natively act as colliders for physbones.

1 Like

I think worlds can already have “global” PhysBones - it’s one of the reasons we considered adding it to avatars, too.

Though that’s probably not what you’re looking for - or I misunderstood how the system works! Turning walls and floors into colliders/PhysBones is an interesting idea.

U# Supports abstract classes.

3 Likes

Fixed! Thanks for pointing that out.

Once the Soba documentation is released, you’ll be able to suggest changes directly via our GitHub repository: GitHub - vrchat-community/creator-docs · GitHub

1 Like

Non-behavior classes too and a bunch more if you use the beta U# version on Github, it’s a lot nicer to use :blush:

But great to see some Soba news, hopefully won’t be tooo long before we can finally get our hands on it :partying_face:

1 Like

I honestly hope that Soba could be one day implemented in the Avatars SDK as a means to replace animators in some instances, though the catch would be that it’d have to be it’d be it’s own library and should utilize the parameters list if you wanna have it sync to remote users.

I’m glad to see the randomize function of the play audio behavior be expanded on. Has VRC ever considered adding a synced function to it? So that results of the randomizer are constant across local and global users?

Sad to see the new character controller get pushed to the backburner! I was really hoping to see something about it since its a highly requested feature! Maybe having a “CharacterController” Station type could be made so Soba or U# can make their own character controllers for worlds.

3 Likes

This should already be possible by either using multiple animation states or using an Avatar Parameter Driver set to sync its parameter and using that parameter as the input for which audio clip to play. There’s a note about this in the docs here, in bold: State Behaviors | VRChat Creation

no generics? seriously?
guess i’ll be staying with u# 1.2-beta1 for as long as possible then :slight_smile:

(thank you merlin)

3 Likes

I’m so sad… It would save the day so many times, and I wouldn’t have to write boilerplate code. optimization would be better too, and why can’t I use the try-catch method? That’s a very basic thing, too. But what bothers me the most are generic types and Linq. WE NEED THE GENERIC TYPES and Linq.

Some features that I would love to see added to Soba would be:

  • Generics
  • Delegates / Events
  • Try/catch/finally
  • Linq

I believe that Events, delegates & Generics are still being worked on and might become available once the ‘official’ list is revealed when soba releases. It would be incredibly neglectful to not include these features. Generics especially prevent thousands of lines of boilerplate code that becomes a total nightmare to maintain realistically.

Try Catch Finally irks me a tiny bit due to the fact that making your own exceptions can be beneficial to debugging in my eyes. Catching a specific exception thrown in your own logic flow is a lot better than having to use 101 Utility functions and a boolean sprayed with a bit of luck you didn’t miss a NullReference somewhere.

Linq not being a thing perplexes me out of all things C#. As a game design student I can confirm all C# classes I’ve ever taken emphasize the use of Linq up and into the Exam. it makes no sense this feature goes unsupported. I want to believe this is still being worked on of course, as a lot of these additions listed are no-brainers for people who have already used C# and know how to use the language effectively.

Besides that I’m happy to see a lot of the U# beta features coming to the main SDK. I do hope we can get to use Newtonsoft for JSON instead of the what I consider ‘bandaid solution’ DataLists and DataDictionaries are.

My final question would just be if Items will support Soba too, there are talks of scriptable items and while Items being locked to Udon would be better than nothing, it’s a good thing to know.

LINQ is generally not an ideal thing to be using in very high-performance paths, which is the situation in most game development cases, for general apps there are a lot more opportunities for its use as you tend to have a lot more functionality that isn’t running in a hot path. For a simple indie game that’s only going to be released on PC, it’s often fine and may speed up your development a bit, but in general it tends to lead to bad practices for making optimal code, an inflated stack and can create more garbage collector load.

LINQ can be written in more performant ways if utilizing modern .NET 9 features like Spans, and has better compiler optimizations when those features are available, but the user often has to intentionally know the more optimal way to use it, and it’s still not ideal for games even then, so I don’t think we should encourage worse approaches by supporting it, especially in a game context that already has significant processing overhead, especially on standalone headsets.

And modern IDE auto-complete makes typing a lot of boilerplate stuff that LINQ saves you from a lot quicker these days anyways.

Personally I’d rather see Unity’s NativeArray based APIs exposed, primarily things like Load/GetRawTextureData() and the Advanced Mesh API, to allow for very high performance direct reading/writing to texture/mesh data and reducing unnecessary large memory allocations from the old ways of touching this data. (But being able to use the allocators and Job system yourself as well would be great too.). This would open up even more potential for world creativity.

Hopefully Generic classes make it in though, but I can at least live without it since they’re supporting Interfaces and Abstracts and you can constrain a generic method to an interface to get your generic calls on unrelated types, in a still high-performance and box-free way.
Not saying it makes up for all the benefits of having Generic classes of course, definitely would still be nice.

Getting Throw and Try-Catch-Finally would definetly be a Game-Changer for error-handling code. My use-case right now would be for getting rid of tons of spaghetti-error-handling-code. (I use an out var called “valid” to emulate throw & try/catch, which leads to hundreds if not thousands of additional lines of code, when adapting existing codebases into U#)

Generics would also certainly be nice, so that we can finally use stuff like List and create custom classes, which have a type-generic with an interface lower-bound to use interfaces to their fullest. Honestly I couldn’t say if Generics or Throw & Try-Catch-Finally are more important to me.

Delegates are in my opinion sort of least nessesary (and I’m also least familiar with them) out of all of those.
Maybe delegates are useful in some sort of higher-order-function stuff, but when you have interfaces and custom types one can probably already do 90% of the things that Delegates allow (just with interfaces and a little more code)

Outside of Throw, Try-Catch-Finally and Generics I’m already happy with that list.
The Ultimate experience with Soba would be for c# code, which doesn’t use forbidden features, to work the same in Unity Editor, Unity Editor Play-Mode and in VRChat

Delegates, which I presume also means Action/Func, can make for a lot simpler code that more easily follows SOLID principles, more specifically decoupling.
You don’t need to worry about managing/defining interfaces everywhere to create types for passing objects into other objects so they can call methods or set properties on them, nor trying to cast generics into specific types (which has overhead).
Instead you can just pass the actual methods/events to target objects that you want them to eventually call when appropriate, sending information/triggers back to the source object, and letting that source object be the one to decide how that information/event should be used in the moment, as it’s behavior was defined in the source, not the target.
These methods/delegates can also be constructed during runtime with varying behavior/values, allowing you to dynamically inject unique behavior to be triggered by things without that thing needing to know anything about the source, allowing more decoupling with minimal code.

A custom defined Delegate type is especially useful for creating events, as you can let objects add their methods to it and when you Invoke that delegate, all those methods get called, which is commonly used to broadcast that something happened back to the objects that assigned their methods to it, often providing some information with it, instead of having them all constantly watching for some state change in an update loop, wasting cycles.
(of course you could do this in a messier way by managing a collection of specific type instances and looping through them to call methods when an event happens, but a delegate lets you do that without needing a specific type/interface, just a specific method signature)

It’s actually really fun and useful to use once you get used to the different way of setting up behavior and comes in handy quite frequently. It shouldn’t be used for every situation of course, all these different features have their more ideal use scenarios. But Delegates are a very powerful feature to have, especially in cases of events or a managing type that wants managed instances to be able to do callbacks without having to know anything about specific types, the dependency relationship kept one-way simply. And those instances can further pass it down a chain if needed, all without types coming into play, just method signature.
And even injecting unique per-instance behavior, as you can have the manager construct an Action/Func that references the target itself, allowing it to be a new local behavior for that instance. There’s a vast world of possibilities with delegates, somewhat similar to how working with pointers can be so much more powerful (but better debugging/safety with delegates haha)

1 Like