UdonChat port
TL;DR: UdonChat’s core mechanic — read an InputField, broadcast a chat message, render into a log — translates directly. The package’s UdonStringEvent bus (EventReceiver.SendEvent(name, payload)) goes away: WASM lets scripts call each other’s methods directly, so we replace the bus with a reference + method call. The in-world keyboard subsystem is not ported — CVR has native text input and porting 13 key-tracking scripts adds no value.
What ports and what doesn’t
Section titled “What ports and what doesn’t”| Script from UdonChat | Port status |
|---|---|
ChatController | Ported (ChatController.cs) |
ChatEventHandler | Ported (ChatEventHandler.cs) — directly called, no event bus |
UdonLogger + LoggerButtons | Ported as UdonChatLog.cs — simpler rotating buffer |
EventEmitter / EventReceiver (UdonStringEvent) | Removed — direct calls replace the bus |
InWorldKeyboardManager + 12 keyboard scripts | Not ported — use the native keyboard |
PlayerTracker, GenericButton*, KeyEventListener | Not ported — UI plumbing specific to the keyboard |
Port strategy
Section titled “Port strategy”From EventReceiver string-dispatch to direct calls
Section titled “From EventReceiver string-dispatch to direct calls”UdonSharp has no generic function-pointer / delegate surface for cross-behaviour calls, so UdonChat dispatches on string names:
// Udon original — broadcastreceiver.SendEvent("ChatMessage", message.Replace(",", "|"));
// Udon original — handlerswitch (e[0]){ case "ChatMessage": logger.Notice(characterName + ": " + e[1]); break;}In WASM you just hold a reference and call the method:
// WASM port — broadcast over the network + deliver to the local handlerNetworking.SendMessage(writer.Buffer.Slice(0, writer.Length), null, SendType.Reliable, loopback: true);// handler invoked on receivereceiver.Handle(author, text);Networking
Section titled “Networking”Broadcast is an explicit Networking.SendMessage with loopback: true so the sender also receives its own message and renders it in the log. The message carries [byte tag, string author, string text]; BufferReaderWriter handles string length prefixing.
Bad-word filter
Section titled “Bad-word filter”Kept. Normalizes common leet substitutions (1→i, 3→e, etc.), lowercases, and checks each blocked word with IndexOf(..., OrdinalIgnoreCase). Runs locally on the sender before broadcast.
Wiring
Section titled “Wiring”- Canvas with a world-space
InputFieldfor typing, aTextfor the log, and a sendButton. - Add
ChatControllernext to theInputField. Wire:input→ theInputFieldreceiver→ theChatEventHandler(see below)badWords→ inspector array
- Send button’s OnClick →
ChatController.OnSendClicked. ChatEventHandleron a sibling GameObject, wire itsloggerfield to aUdonChatLog.UdonChatLogwires itsoutputto the logText.