VTS-Sharp
2.4.1
dotnet add package VTS-Sharp --version 2.4.1
NuGet\Install-Package VTS-Sharp -Version 2.4.1
<PackageReference Include="VTS-Sharp" Version="2.4.1" />
<PackageVersion Include="VTS-Sharp" Version="2.4.1" />
<PackageReference Include="VTS-Sharp" />
paket add VTS-Sharp --version 2.4.1
#r "nuget: VTS-Sharp, 2.4.1"
#:package VTS-Sharp@2.4.1
#addin nuget:?package=VTS-Sharp&version=2.4.1
#tool nuget:?package=VTS-Sharp&version=2.4.1
VTS-Sharp v2.4.1
A C# client interface for creating VTube Studio Plugins with the official VTube Studio API, for use in Unity, Godot, and other C# development environments!
IMPORTANT!
If you are updating your project from using a 1.x.x version of the library to using a 2.x.x version of the library, please read the migration guide, as the project was restructured in version 2.0.0 to decouple it from the Unity Engine, allowing it to be more easily used in other C# environments!
About
This library is maintained by Tom "Skeletom" Farro. You can contact him via email at tom@skeletom.net or by leaving an issue ticket on this repo.
Usage
In order to start making a plugin, follow these simple steps:
Check to see which packages from this library you need for your project based on your C# environment.
- If you are using Unity or Godot and want your plugin to be a MonoBehaviour or Node, make a class which extends
VTS.Unity.UnityVTSPluginorVTS.Godot.GodotVTSPlugin. - If you are using any other C# environment, make a class which extends
VTS.Core.CoreVTSPlugin, or which has one as a member variable.
- If you are using Unity or Godot and want your plugin to be a MonoBehaviour or Node, make a class which extends
In your class, call the
Initializemethod on the plugin, which will attempt to connect to VTube Studio and authenticate the plugin.It also has you specify what happens when:
- The plugin connects to VTube Studio successfully.
- The plugin disconnects from VTube Studio.
- The plugin encounters an error while attempting to connect to VTube Studio.
Once your plugin is authenticated, you can call any method found in the official VTube Studio API, which are built-in as appropriately named methods on the
VTSPluginclass!
And that's it! In fact these steps are all done for you already, out of the box, in the various examples found in the aptly-named Examples folder! Check out the ones suited for your environment of choice.
You can find a video tutorial that demonstrates how to get started in under 90 seconds here.
Design Patterns and Considerations
Swappable Components
In order to afford the most flexibility (and to be as decoupled from Unity as possible), the underlying components of the VTSPlugin are all defined as interfaces. This allows you to swap out the built-in implementations with custom ones to suit your specific constraints. For example, maybe you need your auth token to save to a database instead of a local file, or need your logs to output to Godot's logging utility instead of the default C# console. These components are provided to the constructor of the VTS.Core.CoreVTSPlugin.
Because Unity MonoBehaviors are not created with constructors, the VTS.Unity.UnityVTSPlugin class provides an accessor called DependencyImplementations which returns a struct containing references to implementations for all underlying components. The VTS.Unity.UnityVTSPlugin class defines this accessor with working implementations by default, but if you want to use something different, you can override the accessor in your extended class. The VTS.Godot.GodotVTSPlugin class follows this pattern as well.
These components include:
IWebSocket, the WebSocket transport layer.ITokenStorage, the mechanism for saving the VTube Studio authentication token.IJsonUtility, the mechanism for serializing and deserializing JSON messages over the socket.IVTSLogger, the logger for printing debug and error messages.
Asynchronous Code
Because the VTube Studio API is websocket-based, all calls to it are inherently asynchronous. As of version 2.1.0, there are now two design patterns for handling asychnonous calls included in this library. You can use the one that suits your perferences and needs the best!
This library also supports the VTube Studio Event Subscription API. With this feature, you can subscribe to various events to make sure your plugin gets a message when something happens in VTube Studio. Event Subscription follows a similar asynchronous design pattern.
Callback-based Design Pattern
The initial implementation of this library revolves around callbacks to achieve asynchronous results. This is similar to the resolve and reject functions of a JavaScript Promise.
API Calls
Take, for example, the following method signature, found in the VTSPlugin class:
void GetAPIState(Action<VTSStateData> onSuccess, Action<VTSErrorData> onError)
The method accepts two callbacks, onSuccess and onError, but does not return a value.
Upon the request being processed by VTube Studio, one of these two callbacks will be invoked, depending on if the request was successful or not. The callback accepts in a single, strongly-typed argument reflecting the response payload. You can find what to expect in each payload class in the official VTube Studio API.
Event Subscription
Take, for example, the following method signature, found in the VTSPlugin class:
void SubscribeToTestEvent(VTSTestEventConfigOptions config, Action<VTSTestEventData> onEvent, Action<VTSEventSubscriptionResponseData> onSubscribe, Action<VTSErrorData> onError)
The method accepts an optional configuration class, and three callbacks, onEvent, onSubscribe and onError, but does not return a value.
Upon successfully subscribing to the event in VTube Studio, the onSubscribe callback will be invoked, and then onEvent will be invoked any time VTube Studio publishes an event of that type. If the subscription fails for any reason, onError will be invoked.
Async/Await-based Design Pattern
As of version 2.1.0, the library now supports the async and await pattern for asynchronous code.
API Calls
Take, for example, the following method signature, found in the VTSPlugin class:
async Task<VTSStateData> GetAPIState()
This method will can be called like so:
var stateData = await plugin.GetApiState();
Upon the request being processed by VTube Studio, the method will resolve into a payload of VTSStateData if the request was successful, or it will throw a VTSException if the request failed for any reason.
Event Subscription
Take, for example, the following method signature, found in the VTSPlugin class:
async Task<VTSEventSubscriptionResponseData> SubscribeToTestEvent(VTSTestEventConfigOptions config, Action<VTSTestEventData> onEvent)
The method accepts an optional configuration class, and one callback, onEvent.
Upon successfully subscribing to the event in VTube Studio, the method will resolve into a payload of VTSEventSubscriptionResponseData and then onEvent will be invoked any time VTube Studio publishes an event of that type. If the subscription fails for any reason, a VTSException will be thrown.
Packages
As of version 2.0.0, the library has been reorganized into various packages, making it easier to extend in to new environments. If you are updating your project from using a 1.x.x version of the library to using a 2.x.x version of the library, please completely remove the library from your project, and re-import it, as files have been moved and will not simply overwrite in-place.
The current packages are as follows:
VTS.Core: contains the core of the library, and is required in all C# environments. Other environment-specific pakages build on top of this.VTS.Unity: contains Unity-specific examples, as well as implementations of some plugin components and a wrapper for building a plugin as a MonoBehavior on a GameObject. However, this package is not required for working in a Unity environment, and is simply there for convenience.VTS.Godot: contains Godot-specific examples, as well as implementations of some plugin components and a wrapper for building a plugin as a Node. However, this package is not required for working in a Godot environment, and is simply there for convenience.
Breaking Changes
In Version 2.4.1
- The
Initializemethod is no longer repsonsible for dependency injection of plugin components, as this is now also accomplished by the constructor of theVTS.Core.VTSPluginclass and is thus redundant.- For
VTSPluginimplementations that do not leverage constructors, such asVTS.Unity.UnityVTSPluginandVTS.Godot.GodotVTSPlugin, an accessor calledDependencyImplementationsexists and can be overridden to specify components for just-in-time injection.
- For
In Version 2.0.0
- Namespaces have been totally reorganized. The two resulting namespaces in this version are
VTS.CoreandVTS.Unity. These correspond to the aformentioned packages. - The
VTSPluginMonoBehaviour class has been renamed toUnityVTSPlugin, and moved into theVTS.Unitynamespace. As such, please update your plugin classes to extendVTS.Unity.UnityVTSPlugin. - The
VTSWebSocketMonoBehaviour class has been totally removed. You may safely remove it from any game objects. This class now exists as a pure C# equivalent.
API
interface IVTSPlugin
Provided Implementations
VTS.Core.CoreVTSPluginVTS.Unity.UnityVTSPluginVTS.Godot.GodotVTSPlugin
Properties
string PluginName
The name of this plugin. Required for authorization purposes.
string PluginAuthor
The name of this plugin's author. Required for authorization purposes.
string PluginIcon
The icon of this for this plugin, as a base64 string. Optional, must be exactly 128*128 pixels in size.
IWebSocket Socket
The underlying WebSocket implementation.
ITokenStorage TokenStorage
The underlying Token Storage mechanism for connecting to VTS.
IJsonUtility JsonUtility
The underlying JSON serializer/deserializer implementation.
IVTSLogger Logger
The underlying Logger implementation.
bool IsAuthenticated
Is the plugin currently authenticated?
Methods
void Initialize
Connects to VTube Studio, ans authenticates the plugin. Takes the following args:
Action onConnect: Callback executed upon successful initialization.Action onDisconnect: Callback executed upon disconnecting from VTS (accidental or otherwise).Action<VTSErrorData> onError: Callback executed upon failed initialization.
The plugin will attempt to intelligently choose a port to connect to, using the following criteria:
- It will first attempt to connect to the designated port (
8001by default, can be manually set with SetPort). - If that fails, it will attempt to connect to the first port discovered by UDP.
- If that takes too long and times out, it will attempt to connect to the default port (
8001).
Task InitializeAsync
Connects to VTube Studio, and authenticates the plugin. Takes the following args:
Action onDisconnect: Callback executed upon disconnecting from VTS (accidental or otherwise).
If this method fails to execute, it will throw a VTSException.
void Disconnect
Disconnects from VTube Studio. Will fire the onDisconnect callback set via the Initialize method.
Dictionary<int, VTSStateBroadcastData> GetPorts
Generates a dictionary indexed by port number containing information about all available VTube Studio ports.
For more info, see API Server Discovery (UDP) on the official VTube Studio API.
bool SetPort
Sets the connection port to the given number. Returns true if the number is a valid VTube Studio port, returns false otherwise.
If the port number is changed while an active connection exists, you will need to reconnect. Takes the following args:
int portThe port number to set.
bool SetIPAddress
Sets the connection IP address to the given string. Returns true if the string is a valid IP Address format, returns false otherwise.
If the IP Address is changed while an active connection exists, you will need to reconnect. Takes the following args:
string ipStringThe string form of the IP address, in dotted-quad notation for IPv4.
VTube Studio API Requests
Request methods can be inferred from the official VTube Studio API.
VTube Studio API Events
Event subscription methods can be inferred from the official VTube Studio Event Subscription API.
interface IWebSocket
Provided Implementations
VTS.Core.WebSocketImpl
Methods
string GetNextResponse
Fetches the next response to process.
void Start
Connects to the given URL and executes the relevant callback on completion. Takes the following args:
string URL: URL to connect to.Action onConnect: Callback executed upon connecting to the URL.Action onDisconnect: Callback executed upon disconnecting from the URL (accidental or otherwise).Action<Exception> onError: Callback executed upon receiving an error.
void Stop
Closes the websocket. Executes the onDisconnect callback as specified in the Start method call.
bool IsConnecting
Is the socket in the process of connecting?
bool IsConnectionOpen
Has the socket successfully connected?
void Send
Send a payload to the websocket server. Takes the following args:
string message: The payload to send.
interface IJsonUtility
Provided Implementations
VTS.Core.NewtonsoftJsonUtilityImplReadMe
Methods
T FromJson<T>
Deserializes a JSON string into an object of the specified type. Takes the following args:
T: The type to deserialize into.string json: The JSON string.
string ToJson
Converts an object into a JSON string. Takes the following args:
object obj: The object to serialize.
interface ITokenStorage
Provided Implementations
VTS.Core.TokenStorageImpl
Methods
string LoadToken
Loads the auth token.
void SaveToken
Saves an auth token. Takes the following args:
string token: The token to save.
void DeleteToken
Deletes the auth token.
interface IVTSLogger
Provided Implementations
VTS.Core.ConsoleVTSLoggerImplVTS.Unity.UnityVTSLoggerImplVTS.Godot.GodotVTSLoggerImpl
Methods
void Log
Logs a message. Takes the following args:
string message: The message to log.
void LogWarning
Logs a warning. Takes the following args:
string warning: The warning to log.
void LogError
Logs an error. Takes the following args:
string error: The error to log.
void LogError
Logs an error. Takes the following args:
Exception error: The exception to log.
Acknowledgements
DenchiSoft
None of this would be possible without Denchi's tireless work on VTube Studio itself.
Newtonsoft JSON.NET
An implementation of IJsonUtility using Newtonsoft's JSON.NET has been included for use, adhering to the library's MIT license.
Made With VTS-Sharp
Below is a list of some plugins which were made using this library! If you have made something you would like included on this list, please send Tom a message.
| Plugin | Developer | Explanation |
|---|---|---|
| VConnect (Video) | Remasuri3 | An app with a streaming overlay and automation studio where you connect any live event to any on-screen reaction using a visual node editor. No coding knowledge necessary. Just drag, connect, and sit back to watch as your stream reacts. |
| VBridger (Video) | PiPuProductions | An app designed for VTube Studio and Live2D, which allows the user to make better use of iPhoneX ARKit tracking on their Live2D model. |
| VInput (Video) | xiaoye1997 | An app for sending data to VTubeStudio, such as game controller inputs, racing steering wheel data, time data, hardware monitoring data and data derived from custom LUA scripting. |
| Twitch Integrated Throwing System (T.I.T.S) (Video) | Remasuri3 | An app which allows your chat to bully you as much as possible >:D It can be used with or without VTube Studio to let people throw items at your face! |
| VTS-Heartrate (Video) | Skeletom | An app which allows users to connect their heartrate data to VTube Studio, to cause their model to become flushed under stress and breathe more heavily, among other things. |
| PentabInfoPickerForVTS (Video) | Ganeesya | An app which allows users to control their model with a tablet and pen. |
| Camera Optical Flow Tracking Into VTube Studio | PengCho | An app for real-time vlogging with just a single, forward-facing camera. It automatically points your model's gaze towards the direction that the video feed is moving using Optical Flow techniques! No tracking camera needed. |
| VTS-ChangeEyeColor (Github) | TaniNatsumi | An app which allows users to change the eye colors of their model. Can change each eye color individually (heterochromia). |
| VTSLive | fastest_yukkuri | An app which allows VTube Studio to reflect the movement of analog and digital clocks, the movement of the sun and moon, and weather information from around the world. |
| VTS-Mod | MechaWolfVtuberShin | An app which allows users to change the surface color of the model including RGB. It can also change the rotation of the model. |
| ViewLink | Kawa Entertainment | An app for translating 3D VR movement into Live2D motion tracking, allowing you to stream VR games with your Live2D model. |
| Audiomimi (Video) | Artemiz | An app that allows you to use SFX based on VTS parameter movement. |
| VTS Desktop Audio (Video) | Lua V. Lucky | An app that allows you to control your model with your desktop audio! Converts various parts of the audio spectrum to custom tracking parameters. |
| Twitch High Intensity Color Changer (T.H.I.C.C) | Remasuri3 | An app which allows your chat to change colors on your model via point redeems and other events! |
| Winter Wonderland Twitch Overlay (Video) | Lua V. Lucky | An app which provides numerous festive elements for any stream. Decorate a Christmas tree, pelt the streamer with snowballs, and more! |
| VtubeStudioSimpleSETool (Video) | Mononobe Monoko | An app for playing Sound Effects (SE) and displaying particle effects based on your movement. |
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- Newtonsoft.Json (>= 13.0.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.