#udon-networking

1 messages · Page 3 of 1

cold laurel
#

Oh my god

#

I hate dyno

#

I spent so long writing that

#

Can a mod bring the message back? I am not writing it all again...

#

"No spamming" what a trigger happy bot. It was literally one message

humble girder
#

Maybe try to call some active mod to get the message back?

cold laurel
#

@misty temple Hey, sorry to ping you. I wrote a long explanation on mobile about polymorphism and dyno nuked my message for no reason. Do you have a copy of the message contents somewhere in the bot logs? And if so, could you please send it to me?
Thanks in advance!

arctic marlin
#

Ahhh, into the void

cold laurel
#

:(

arctic marlin
#

return polymorphismExplanation;

cold laurel
#

The string was too long to be synced :p

cold laurel
frozen igloo
# cold laurel <@95750670816129024> Hey, sorry to ping you. I wrote a long explanation on mobil...

When inheriting from a class if the class has virtual or abstract methods you can override them. This means that if the method is called your implementation is called instead.

Let's say you have a lot of enemies that you all want to take damage.
You could then create a class Enemy and implement your

protected virtual void TakeDamage(float damageToTake)
{

}

protected is an access modifier just like private and public. It means any inheriting class has access to it but not external classes. So it's pretty similar to private.

Then you could create a class for each enemy and inherit from the Enemy class like so:

public class Slime : Enemy
{
        protected override void TakeDamage(float damageToTake)
        {
                //stuff specific to slimes
                base.TakeDamage() // you can also call the base implementation of the method if you want to. But this is optional.
        }
}
merry juniper
#

???

#

awesome my question got deleted

frozen igloo
# merry juniper awesome my question got deleted

here's your question:

so by reading a bit about the VRC networking I noticed that post requests are not allowed which is hell, as it makes overcomplex a simple problem of syncronization. so, I have a question. I'm trying to have 3 things synchronized

  1. a random number that's generated each 30 seconds
  2. a value that is added each 30 minutes (for a map changing system)
  3. the timer to keep all players game running under the same conditions

so, provided that VRC disallows GET request from a website.
I read that the way of addind synchronized objects is by doing a pool so my idea is to make

Obj_manager >> has component pool and indexes:

  • Obj_timer -> for variables - has started, has ended
  • Obj_random_event ->> for variable random event (just the random number)
    and
  • Obj_map_changer ->> to synchronize the map ID (with a switchcase it will change ambience wo it only needs to sync a single value)

how can I tell the object pool which variables inside the objects are being synchronized in order to keep those three for the game

merry juniper
#

thanks

frozen igloo
#

hm, I think an object pool is way overcomplicating what you need. It sounds like you literally just need one object with a synced variable

#

for what it's worth - you can effectively get strings and images from the web. https://docs.vrchat.com/docs/string-loading

sending arbitrary data to the web is restricted to prevent mass amounts of personal data being exfiltrated, such as precise tracking data over a period of time which can be used to de-anonymize someone and track their IP address.

VRChat

Load text files from the internet in your VRChat worlds

#

but regardless, none of that is relevant because sending to/from the web is absolutely not the right tool for simply syncing with other players in the instance. That's what realtime networking is for, with synced variables and network events

merry juniper
#

oh ok, im actually trying to use an API, so users can control the game from a browser, or give more flexibility and reduce download size, I noticed there are some worlds of 500mb which is kind of exagerated, and for a poor 256gb SSD it's painful to have such worlds, also PHP gives me more control, and will allow me to have just 1 object managing all the game events

frozen igloo
#

when you join a vrchat world, you have to download and unpack the whole thing. If your goal is to save download size then you need to make separate vrchat worlds

#

you're going waaaay off into the weeds here trying to come up with a solution that won't work when there are already solutions that do work. It would help if you more clearly stated what your actual goal is

merry juniper
#

now

#

for the variable synchronization on Udon

#

how could I determine which are the specific synchronized variables (without graphs)

frozen igloo
#

right but udon already has ways to sync

#

in udonsharp, you add [UdonSynced] Attribute before the variable

#

this only applies to primitives like float, bool, int, string, and arrays of those

merry juniper
#

ok, perfect im just using Int

#

so, in case of a random event selector

#

I would do:

[UdonSynced] randomval = math_random_idk_func();

#

right?

frozen igloo
#

the basic method for syncing is to:

  • Take ownership
  • Set the variable
  • (if udonbehaviour is manual sync) RequestSerialization

Then other players receive OnDeserialization, which is the event that says "I have received synced data" and you can use the variable

frozen igloo
merry juniper
#

????

frozen igloo
#

just post pictures

merry juniper
#

sorry

#

so, would it be something like that?

frozen igloo
#

can you post a picture of it?

merry juniper
frozen igloo
#

a few things:

  • You definitely don't want to be deciding on a new random variable on update, that would make it change every frame, roughly 90 times per second. You probably want to store a float of the last time that a map was chosen, and check if enough time has elapsed before choosing a new random variable

  • IsInstanceOwner indicates the person who created the instance, which may be someone who isn't even in the instance anymore. It has no bearing on networking. You need networking.IsOwner(gameObject), which indicates the person who has ownership (and the person who can send synced variables) of the object this script is running on.

  • In OnDeserialization, randomvar will simply be the new value set by the owner

  • For a random function, you'll probably want Random.Range

  • As this is a variable that only needs to be updated very infrequently, it would be best to set this to manual sync. To do that, you can put [UdonBehaviourSyncMode(BehaviourSyncMode.Manual)] before the public class.

  • If you set it to manual sync, you need to do RequestSerialization after setting the variable, which will send it to other players

merry juniper
#

wait, update happens per frame and is synced with the drawing?

frozen igloo
#

if by drawing you mean rendering, then yes

amber sluice
#

(just ignore this)

#

Why is my code being deleted?
Our Moderation Bot Dyno can be quite mad about you posting code in here due to the many spaces you usually end up with.
In cases like this it’s best to just post a screenshot of your code or only a small part of it.

merry juniper
#

oki

merry juniper
#

thanks for the advice

#

but then how can I make a timer?

#

I saw a tutorial where someone added a counter in there

frozen igloo
#

if you just need to make an event happen some time in the future, you use SendCustomEventDelayed. However, as this timer is over a long time period and the previous owner may have left in that time, that's not necessarily the best way to do it.

You need a synced timer, so one way to do that is to have a synced float representing how much time is left. Then a local float representing the last time that it was checked. Occasionally, you check the time by taking the difference between previous time it was checked and the current time, and subtracting that from the time left. If it's negative, then that means time is up.

This doesn't cover how to sync it, but at least that's a timer system that would be capable of being synced when you're ready for it

merry juniper
#

but, i mean, it's a delayed event repeated, I read from unity and people use the update from monobehaviour, as a while(1) is a terrible option to do

frozen igloo
#

while loops aren't inherently bad, they're just unsuited for this application because udon code runs on the main thread, and there is no way to Wait(1) while on the main thread. So if a while loop gets stuck looping in the main thread, it will freeze the entire application

merry juniper
#

as it happens with any game

#

that's where my question comes in

#

how could i use the timer on other thread?

#

like

#

to avoid update

frozen igloo
#

udon only runs on the main thread

#

if you want a wait function to only check once a minute, then you can use SendCustomEventDelayed that calls itself

merry juniper
#

recursivity?

frozen igloo
#

kinda, but not technically because it's not being called immediately

#

just queueing it up to be called later

merry juniper
#

ohhh so delayed event makes a stack of events and once a determined time happens, it calls the last event from stack right?

frozen igloo
#

nothing to do with stacks, but yes

#

it's just a list of events and times to call them

merry juniper
#

sorry im used to c++ xd on c++ queues are called stacks sjsjsj

#

okok thank you for the support!

cold laurel
lone zealot
merry juniper
#

are managed pretty much the same the changes are 1. the order of "attendance", 2 on the stack you can't remove an element from the center, but are pretty much the same stuff

merry juniper
#

already explained the similarities, yes I admit i made a mistake mixing them up, but they are still pretty similar, and as described before it looked as a stack

cold laurel
cinder spade
cinder spade
weary girder
#

When you make multiple calls to RequestSerialization() from different classes, will the calls be made (and processed by others) in the same order?

cold laurel
#

RequestSerialization(); Just marks the gameobject as having new data that you want to be synced. If you change the data again and call RequestSerialization(); again before VRC has actually gone around and synced stuff, your previous RequestSerialization(); wouldn't do anything.

#

If you have a sequence of events that you need to be synced you need to store that sequence and sync it in it's entirety.

#

You can do this in OnPreSerialization() as it gets called right before vrc is about to sync data.

cold laurel
# weary girder When you make multiple calls to RequestSerialization() from different classes, w...

So it would go like:

Action happens => add it to the sequence of actions that have happened since the last sync and RequestSerialization();
Action happens => add it to the sequence of actions that have happened since the last sync and RequestSerialization();
etc.
(The above can happen many times before VRC comes to sync the gameObject.)

OnPreSerialization() You transfer the sequence of actions to your synced field. And clear the stored sequence of actions since the last sync. (since we just synced it)

Synced field gets read and sent.

Synced field gets set for remote players.

OnDeserialization() runs for remote players.

weary girder
#

what about multiple objects?
I have say, a parent object, tells a child object to change its values, that child object RequestsSerialization
Then the parent does some more work, makes its own value changes and calls RequestSerialization on its self.

#

I feel like the most 'safe' thing to do would be to move my state data in the parent object and have a single source of truth and data sync. Child objects would then keep functions, set themselves to no-sync and just get and set state on the parent.

cold laurel
cold laurel
arctic marlin
#

So when a person hits the next button they become an owner.

#

It does the IntractableCards() inside this script but then has to call another script: PlaysTurnsTopic to do the Rotate Turn()

#

If that script is on another gameObject, correct me if I'm wrong, but if you want all the UdonSynced data to be synced, you need to call
Networking.SetOwner again, but on that SEPARATE script on that SEPARATE gameObject.

#

If that script is on another gameObject.

regal scarab
arctic marlin
#

The while loop?

regal scarab
#

Yea

arctic marlin
#

Yeah, I'm pretty afraid of that thing. But it's connected to some other stuff. Hang on a second.

regal scarab
#

Ah no my bad

arctic marlin
#

This function always fires first.

#

But you're right, if that while loop for whatever reason goes first, I'm screwed.

#

I should probably add hard count-out to prevent it.

#

Something like this:

#

Not sure what the best practice is for while loops, I'm open to any suggestions cuz they terrify me.

#

But that's outside the scope of networking I think.

#

Feel free to DM me!

regal scarab
#

Currently I try to figure out the use case of Datalists because for now they are kinda useless to me. It doesn't help with real problems like sync a list of GameObjects for all players such as adding new.

regal scarab
#

Yeah it's maybe good for list of strings, ints, floats and bools but you also can just use arrays as before for it.

arctic marlin
#

Everything is an array in U# it seems. Anyways, I'll check out datalists later, you have a good one.

regal scarab
#

Yea I don't understand why they don't just implement existing Lists and Dictionaries and Newtonsoft. I mean it's there already and you don't have to install something for it XD

sterile bison
#

String and Int on same Udon, if i manual sync the Integer, will the already existing string cause any problems, like try to serialize itself depsite its value being unchanged?

lone zealot
celest egret
#

Hi,
I'm trying to spawn an object for my admins but they appear on people randomly...
what am I doing wrong?

cold laurel
frozen igloo
#

You could have all users do it locally, but if you did then you wouldn't want to use a vrc object pool because that's synced

cold laurel
#

there shouldn't be any need for networking here tbh

celest egret
#

oh, so the syncing of the pool is messing it up

cold laurel
#

I'm not sure, but it's extra complexity for little reason.

celest egret
#

Hi, so I'm trying to come up with a simple room counter. An example would be we'd have 10 rooms the doors to each room shows how many people are inside.
My idea for it is to have a trigger surrounding the room and on PlayerTrigger Enter and Exit, set the ownership of the script to said player and increase / decrease the counter and sync it with everyone else.
The issue with this is that if the player exits the room before the ownership is set and the variable is synced, the counter gets messed up.
Does anyone have a better idea to pull this off?

cold laurel
celest egret
cold laurel
#

np :)

celest egret
# cold laurel I'm not sure, but it's extra complexity for little reason.

also back to thise one with the object pool, I made it so that only the instance owner controls the pool. but there is one main issue that makes it useless and I couldnt figure out why.
If you join an instance that already has an instance owner other than you, you'll see the objects and everything works perfectly fine. but as soon as someone else joins which would result in the instance owner redistributing the pool objects, everything will be gone for you, but the new player will see them fine. just like you did before. so it always works for the last player who joins and breaks if someone else joins. I keep looking at the code but the logic seems fine... not sure what I'm doing wrong >w< this is hard lol

cold laurel
#

Networking should be avoided where possible

cold laurel
#

with public override void OnPlayerJoined(VRCPlayerApi player) you can just check player.displayName against your whitelisted names.

#

You can use an object pool without sync to avoid instantiating and destroying so many objects

#

OnPlayerLeft you check if they have a follower thing and return the object to the local pool.

celest egret
#

yes I'll try that ^w^ thank you ❤️

tired quail
tired quail
#

Yea its pretty inconvenient

#

wrote my own door counter and found that out pretty soon, had to make a workaround for it

meager mauve
#

Got a bit of a tough issue. This morning I had a strange error when I started up my project. Forgot to screen shot it but I rebuilt the SDK Reloaded Usharp assets and recompiled all program sources. The error cleared but for some reason ownership transfers are messed up and not updating properly. I'm using Phasedragon's simple object pool and it still works on the current uploaded version, but not in the untouched unity project. So now until I can get it to function like it supposed to I can't even upload any updates or it will break. I don't get it it's literally unedited from yesterday.

frozen igloo
#

You need to make another custom event where you perform this action, and on interact you just sendcustomnetworkevent to trigger that on all clients

#

that's SendCustomEvent, you need SendCustomNetworkEvent

#

that should do it

frozen igloo
#

set the audio source to play on wake false

sharp kraken
#

@cold laurel I guess we should continue this here. So this is the code and my understanding of it is there is a synced boolean variable and a game object variable. On start the boolean is set to be true if the object is initially enabled and false if it is not. When the button is interacted with, if the person interacting with the object is not the object's owner, they are then set as the owner of the object before the value of the boolean is flipped and serialization is requested.

On deserialization, if the person receiving the serialization is not the owner of the object, the object is set to the value of the boolean. Does that sound about right? I feel like my confusion is about when serialization is supposed to be requested, is it like this, just after the value of the boolean is set? What if I want to do this to multiple objects? Does it require multiple booleans? Can an array be used or does it require an array of booleans? Do I need another unique boolean for every instance of this script or is "IsEnabled" something that can be synced and remains local to every instance of its usage?

cold laurel
#

Light mode 😆

sharp kraken
#

You can see I don't use a lot of Visual Studio. Up until recently I would just edit stuff in notepad.

cold laurel
cold laurel
sharp kraken
#

This script is from VRChat so that's on them, I'm just trying to redo it in graph because I have some stuff already in graph and I don't want to have to completely trash it to set up syncing if I can avoid it.

#

At least I think this is an official script, it's inside of the UdonSharp project files

#

So I'm just trying to recreate what they're doing in graph

#

It's the GlobalToggleObject script if you want to have a look at it yourself

cold laurel
#

You'd only want to set the isEnabled bool in Start() if the local player is the owner. Late joiners get OnDeserialization() called.

#

The sharp script should work fine tbh

#

Assuming the sync mode is manual

sharp kraken
#

Yeah, it's just that I already have a bunch of stuff I'm doing in graph and it's used on dozens of objects that already have their references nicely set up so I'd like to be able to use this as a piece of graph I can plug into those programs without destroying all of those references.

#

I'd hope the Sharp script works or else they probably shouldn't have released it with the SDK.

#

I also need to do this with multiple objects in one program so I guess I either need to have mulitple booleans or do this with an array but I'm still hazy on how one would go about syncing multiple objects in an array and whether than could be done with one boolean or would require multiple. I'm setting all of the objects to either off or on but I need it to work on multiple objects.

#

Ideally, it would just set one boolean and apply that to an arbitrary number of objects since their values will all be the same.

cold laurel
cold laurel
sharp kraken
#

I guess that makes sense, what's being synced is the boolean so it's just a matter of making sure all the objects get that value. I still need to do this in graph if I want to avoid a bunch of extra work but I'll keep working away at it and see what I can come up with, thanks.

cold laurel
#

Good luck :D

sharp kraken
#

Is this anything? What I'm trying to do is do through all the elements of the array, checking for ownership and setting owners of each of them if the local player is not the owner and setting all of the elements of the array to the flipped value of the boolean to work as a toggle. What I'm concerned about is first does this make any sense but also will this keep flipping the value of the boolean? It shouldn't because the boolean isn't being set by the loop, or at least it doesn't seem like it.

#

The Set IsEnabled node is there as I think I actually need to change the value for OnDeserialization but I wasn't sure if there was a way to plug that directly into the SetActive node

#

Though I guess what could happen is it uses the flipped value of the boolean once and then after it sets the value of the boolean it negates the negation which wouldn't be what I would want. Not sure what to do there.

cold laurel
sharp kraken
#

I want to set 3 objects all to be off or on and sync them

#

All 3 objects will always either be off or on

cold laurel
#

it should be 1 to 1 with the active state

#

I'm not sure, but shouldn't there be a node entry for OnDeserialization()?

#

God graph is such a mess

#

😆

sharp kraken
# cold laurel why are you negating the `isEnabled` bool

It's a toggle so at some point it needs to be switched to set the active state to be flipped, right? Otherwise we're just setting the object to be active if it is and not if it isn't. I revised things a bit since I realized I wasn't ever executing the loop which seems like an important thing to do. There is an OnDeserialization node but I'm just focusing on the requesting for now

cold laurel
#

Yeah, but you would only want to do that for the owner right

sharp kraken
#

The code version of that being

cold laurel
#

when interacting

#

how is OnDeserialization() handeled in the graph

sharp kraken
#

It needs to change the value for everyone or else how is it toggling them?

cold laurel
#

Yes

sharp kraken
cold laurel
#

in the graph

#

Where's the entry point

cold laurel
sharp kraken
#

Entry point? You mean Start? I can show you all that I have but I'm just trying to recreate the steps in the code

cold laurel
#

Event

#

my bad

sharp kraken
sharp kraken
#

Yeah, just realized that

#

But you say it isn't necessary at all

cold laurel
#

yeah

#

just remove it lol

sharp kraken
#

So then this?

cold laurel
#

ye

#

is this all in one graph?

sharp kraken
#

It is, should it not be? It's all in one script in the U# version.

cold laurel
#

It should be

sharp kraken
#

I do wonder if there's an edge case reason for checking for ownership on deserialization as I'm not sure why they would include it otherwise but if it works, it works

cold laurel
#

There isn't

sharp kraken
#

I'm just not sure if my order of operations is properly set up or if I'm flipping the boolean a bunch of times when I just want to negate it once every interaction

cold laurel
sharp kraken
#

Is that not what it's doing? I'm not sure how what this code is doing is different from that. It's not flipping it OnDeserialization, just before requesting it

cold laurel
#

Is it not working?

sharp kraken
#

I'm still not 100% sure how it knows what it's serializing. I'm flipping the boolean then requesting serialization but I'm not requesting serialization of that boolean specifically. Does requesting serialization request serialization for all synced variables in the program and set them to the values for the owner?

cold laurel
#

You can't choose which synced field to serialize

sharp kraken
#

I haven't tested it, just figured I'd post it for review before doing that. The first version certainly wouldn't have worked but this one might.

#

Should synchronization be manual or none?

#

I'll try manual, seems right

cold laurel
sharp kraken
#

Yeah, doesn't seem to work. Unless there's something obvious, maybe there's a place where I could put a helpful debug log? 🤷

#

Could it be due to this error? Comes up whenever I compile and the references in the inspector don't seem to be updating when I remove variables so maybe it's not compiling properly even though I can enter play mode with client sim and it doesn't crash when I interact with the button, it just doesn't do anything.

#

Just copied the nodes over to another program and it doesn't compile so yeah, it's probably whatever that is

#

Seems like maybe I'm trying to access an array element that doesn't exist? But I'm either ending at the length of the array or I'm just using the 1st element of the array (at position 0) and my array had 3 elements so I'm not sure what would cause that.

sharp kraken
#

Well, now that I recreated it, I can't even compile it to set up my references so I don't think a log will tell me much. I guess I just need to recreate it from scratch, maybe I just need to make sure I'm setting the size of the array before doing anything with it. Thought I did that the first time but maybe not. Luckily, I thought this might happen so I made a screenshot of the program.

#

@cold laurel Okay, so I started recreating it and the error comes up right when I try to connect the Gameobject[] Get node to the for loop int index even though that's exactly how PlayerBush001 does it as far as I can tell.

#

I tried using an addition node to add 1 in case there was an indexing issue but that doesn't seem to be possible to hook up to the int index and starting at 1 rather than 0 doesn't do anything either.

cold laurel
#

I'm sorry, I'm not familiar with the specific quirks of graph

sharp kraken
#

I think I got it, thanks. It seems to not have any issues if I use a separate instance of the variable than I'm using for the "IsOwner" check even though it's pointing to the same Array.

sharp kraken
#

So I have this new version that runs without errors but still doesn't do anything. I'm thinking it may be because when I enter the instance, I'm automatically the owner of all of the objects and since it only runs for someone who isn't the owner, it won't run for me? Or am I confused about how that works?

#

It's also only checking for ownership of first object in the array which should have the same ownership as all of the other objects but I'm thinking if I'm not setting ownership of those objects, I'm not going to be able to request serialization on those objects which isn't ideal but I figure it should at least set the first object to be active but it does not.

sharp kraken
# cold laurel aren't you using `Start()`?

That's just an image of interact since that's what I changed, the Start stuff is all the same but I'm not setting ownership on Start, just setting the boolean equal to the 1st element of the array's active state.

sharp kraken
#

That's not in the original script but I can add it

cold laurel
sharp kraken
# cold laurel you're checking master currently

How do I hook it up? GetOwner doesn't have a boolean ouput. Should I have a loop that sets IsEnabled 3 times? I was thinking just use the 1st element as all of the objects will have the same initial value. In fact, all of the objects will be disabled by default so I'm not sure if this is even necessary.

sharp kraken
cold laurel
sharp kraken
sharp kraken
# cold laurel yes

Still no luck. Am I wrong that it's a problem that the interact only runs if you aren't the owner of the objects in the array or is ownership not granted to anyone until it's set manually? In which case that Start code won't run, will it? Since I wouldn't be the owner of anything?

cold laurel
sharp kraken
cold laurel
#

if you are the owner, just continue

#

if false

sharp kraken
#

Owner of the button?

cold laurel
#

yes

cold laurel
sharp kraken
#

Okay, well that's different. I'll try that

sharp kraken
cold laurel
#

if they're already the owner then we just run the rest

#

in both cases we run the rest

sharp kraken
#

Okay, right now the rest isn't being run at all if they are the owner so I'll need to fix that.

cold laurel
sharp kraken
#

So like this?

cold laurel
sharp kraken
# cold laurel yep

That did it! I still need to make sure it's actually syncing, not sure if that's possible to test on my own but it works for me and I can get some people in to test it. Appreciate the help, I'm not looking forward to having to remember how all of this works for more advanced cases but at least I can sync an array toggle by just copying this code 🙏

cold laurel
sharp kraken
sharp kraken
#

Alright, so I tested with multiple clients and it's not encouraging. The first instance that loads up needs to press the button once to turn the object on whereas the second person needs to press it twice and neither of them seem to be synced with the other. Also neither person can turn the object off regardless of the number of times they press the button.

cold laurel
#

just do it on interact directly.

sharp kraken
sharp kraken
#

Hooking up flow to the Set IsEnabled node allowed for the object to be toggled locally but still no syncing so I tried setting up Start this way. It didn't make sense so me why I was getting the ownership of an element of the array if what matters is ownership of the button but this didn't seem to fix anything. The first person to interact with the button can immediately toggle the object locally but once it's been toggled once, for the other player to toggle it, they need to press it twice which seems to me suggests that they're having to interact with it once to get ownership and again to execute the rest of the code even though it should all be connected.

cold laurel
sharp kraken
sharp kraken
#

I'm not really sure why I'm bothering with the owner at all in Start but I thought you said I was supposed to.

cold laurel
sharp kraken
#

Isn't that what setting it on Interact does?

#

This is what it was before I changed it but that also didn't seem to be working so I tried to fiddle with it.

cold laurel
sharp kraken
#

Okay, I'll try that. All the original script uses start for is to set the value of IsEnabled and all of the objects should be disabled to begin with anyway so as far as that goes it shouldn't be necessary.

sharp kraken
# cold laurel Just remove all of start

Removing start didn't seem to change anything for better or worse. It still takes 2 interactions to start toggling the object and there's still no sync. Here's the full program as it stands now.

sharp kraken
#

Alright, so I found one tiny issue, that code was never actually requesting serialization (must've gotten missed when I initially recreated the graph). 😅 Alas, adding it after Set IsEnabled gets flipped didn't seem to fix anything, it's still not synced but progress maybe?

#

I'm just requesting serialization after the boolean is flipped since that is ultimately what is being used to set everything on deserialization.

cold laurel
sharp kraken
#

I still haven't tried it with other people but I imagine if it doesn't work with multiple local clients, it won't work with remote players either.

cold laurel
sharp kraken
cold laurel
#

I honestly don't know, this looks like it should work fine.

#

I'm sorry that I can't help that much with graph.

#

I just don't see any value in learning it for myself

sharp kraken
#

No worries, appreciate the assistance. I should probably just take this to #udon-general since no one looks at this channel even though it seems more relevant here.

#

I could use the Udon Sharp toggle script even though it would be more work but I'd still have to rewrite it to handle arrays which I would need to get asistance with but I guess that's plan B.

cold laurel
#

If you just did this in sharp it would be so much simpler imho

sharp kraken
#

Yeah, it's just a matter of having to swap out all of my existing references which would be annoying since there are dozens of instances of the existing non-synced script being used whereas if I can do it in graph, I can just plug the new nodes into the existing program.

#

But if I can't get it working in graph, I guess I gotta do what I gotta do

spice crypt
#

I’m looking for a good freelance site to hire someone to code. Looks like people with udon experience is actually a little bit more difficult to find. Anyone have any advice on where to look?

spice crypt
weak mirage
#

they have channels for world devs aswell

spice crypt
weak mirage
#

there isn't really a dedicated community for people that do commissions with udon aside from vrctraders as far as I'm aware, but you could always ask people individually

spice crypt
#

That’s what it’s looking like due to how specific Udon is, the only thing im seeing online is the ability to hire for company projects where you post projects on hiring pages, but that’s an entirely different level. Due to needed a company/website. I’m just going to have to dig a bit deeper on the people I deal with I suppose and do some manual networking. Thanks for your time though, I’m hoping someone else here might have some insight.

torn sundial
#

What you even need done? Its either gonna be something you could learn yourself or just cost you a lot of money. You wont find much outside of asking people for commissions, udons just a niche limited c#.

cold laurel
tired quail
#

Yea, as dev by trade I go by the hour and at least $40 an hour

cold laurel
#

For the low low cost of $28000 USD you can have your very own VRC vehicle system :D

tired quail
#

HAHA. Fr fr. Makes me feel bad when I work on my own passion projects instead of all the commissions I get asked to do XD
Like Ccmon self, you could be making money!

cold laurel
bitter path
#

anyone knows why the data can be just not sent even tho it called the RequestSerialization()?

#

*might've figured it out

bitter path
#

nop, didn't

humble girder
bitter path
humble girder
bitter path
#

it will just ignore it if it tries to transfer ownership to owner

#

update, seems to be the problem if sent not from the instance master

#

master doesn't receive the value for some reason

#

or more like it doesn't receive only the "" string
left is non-master trying to send stuff
right is what master received

#

also OnPostSerialization*, forgot to change text in debug log

#

ok this one is more readable, i need to make a better debug log UI
second SEND log tells that empty string was sent, but instance master on the right didn't receive it at all

#

is there something obvious that i am missing?

#

yes i do

#

i forgot to actually set the variable to have this value

#

yep, works perfectly now
that was a long 2hrs of troubleshooting because of this one line

#

and late joiner sync works now, that is enough coding for today

cold laurel
bitter path
#

is there any reason why it would ignore me setting local position/rotation to 0 when it definitely was called?
same happens with the rotation

#

is it too early to start moving object before "OnPlayerJoined" appeared on joining player's side?:

#

10s delay before sending data doesn't help

#

and it doesn't look like it waits 20s at all

quaint rain
bitter path
quaint rain
bitter path
#

even tho i almost feel like swapping them for custom events

quaint rain
bitter path
#

i mean
function gets called
it does
game just ignores the values it sets

#

it outputs the log message exactly where it should be fired, but later check in FixedUpdate if the same variables shows them not set to Quaternion.identity and Vector3.zero

quaint rain
#

Yes that should be working assuming you aren't applying different values somewhere else, I was just assuming you may have had your other custom events set as private as well whilst trying to use SendCustomEvent

bitter path
#

does one object firing RequestSerialization cause all the other objects to serialize the data too?:

quaint rain
#

No, only for the object you called it on

bitter path
#

but on all the scripts attached to this object, is it?

#

i feel like the serialization of sync script also causes serialization in the main one

#

both on the same object

quaint rain
#

Yeah calling RequestSerialization on one component will serialize for all Udon Behavior components on that object

bitter path
#

might've got an idea then

#

i guess i will have to abandon and idea to use FieldChangeCallback's in this case

#

or make them not apply the values directly
that might work

#

nah, will have to use custom network events, i guess, thats annoying

bitter path
#

The issue was actually because Udon seems to sync the variables on join, not only when I requested the serialization, even for manually synced objects , so values the objects were getting were contradicting and the one that was sent last stayed there

wild basin
#

Hello quick question!
2 years ago, I made a Brick Breaker games in VRC and the ball was pretty laggy in multiplayer 😦
Does the physics synchronisation got improved since this point?

#

Else I'll try to dig some new ideas and even participate on the jam 😄

quaint rain
wild basin
#

Ohhh nice! thanks a lot!

quaint rain
#

That setup is quite good but you would have to test if it works well for your usage

wild basin
#

I will only have one ball at a single time and bricks
Other players will have to help or disrupt the gameplay of main player

#

I guess it should not be that heavy for the bandwith

cold laurel
cold laurel
cold laurel
#

There are also many ways you can ensure you're only processing the synced data once.

bitter path
#

the whole trying to networking in vrc turned out to be a race condition management game lol

#

or more like hide-and-seek

#

starting to understand where to search for them

frozen igloo
# bitter path The issue was actually because Udon seems to sync the variables on join, not onl...

I get the impression that if you're running into this problem, you might be using networking incorrectly, or expecting it to behave differently from how it actually does.

Start with the basics. If you want to send data to other users on a manual sync object, you do

-Take ownership
-Set variables
-RequestSerialization

And then when you want to create the logic for receiving that data, you simply implement OnDeserialization. In that event, all the variables will be up to date.

There are several pitfalls that you may run into when you diverge from this basic implementation, here's a couple:

If you use FieldChangeCallback to respond to synced data, the changed events will arrive immediately as each individual variable is changed, meaning that if the callback for one variable depends on a different variable, it may or may not be updated yet.

If you send variables through manual sync and then events with network events, those two things take a different route and usually the variables will arrive first, but this is not guaranteed if there is heavy traffic. It is not recommended to mix and match so that the resulting event is dependent on synced variables.

bitter path
bitter path
#

i simplified the code so 1 scripts takes care of everything and in more controlled manner, now it works, at least i didn't manage to break it in 10min of trying to do so

cold laurel
#
TLX

In this TLX Spring 2021 session, FairlySadPanda explains how to use the UNU update to make networked games and content that doesn't suck or break.

Check out other talks from the TLX Spring 2021 event at https://www.youtube.com/playlist?list=PLTgqlzYxsEMxiUvVaqBcD5OL9MpdmkiSH

Learn more about Prefabs TLX at https://tlx.dev

Follow TLX on Twitte...

▶ Play video
rich wharf
#

Awesome!! Thank you @cold laurel

bitter path
#

oh, that is nice, thank you

cold laurel
#

Know how to do what

hardy harbor
cold laurel
#

Probably :p

hardy harbor
#

I'll switch it over then lol :p

wild basin
#

Wow there is game dev conference in VRC 🤣 That's so cool ! Thanks for sharing!

meager mauve
#

Ok I want to hit a button and and have an object is set active for everyone, even late joiners. will this work?

meager mauve
#

Sigh...

cold laurel
#

You need to have a synced bool

#

[UdonSynced] private bool isOn;

#

you need a method for the toggle to call

meager mauve
#

Oh.... ok

#

I'm glad they make the calls for this stuff simple.

cold laurel
#

in that method you set the local player to be the owner, set the value of your isOn bool to be the same as the toggle value, and then RequestSerialization()

#

I'd suggest having a different method for actually applying this change with the for loop.

#

Then just call that event in OnDeserialization()

#

You'll also have to update the toggle with the new value but without triggering the OnValueChanged

meager mauve
#

Well that complicates things for me lol I'll have to see if I can logic that out.

cold laurel
meager mauve
#

Thanks. It still amazes me how many different things they have created libraries for.

#

Like so....?

#

well minus the Request inside the for loop

cold laurel
# meager mauve Like so....?

You need to set the local player as the owner before trying to sync the isOn bool.
Also, please move the for loop into it's own method and call it from OnDeserialization() as well.

meager mauve
#

I could just do the ownership request at the start right?

#

Or set owner in this case.

cold laurel
#

no

#

you need to do it every time the button is interacted with

meager mauve
#

Oh right ok.. That makes sense.

#

That's solid right?

cold laurel
#

can you show the whole thing again

meager mauve
#

sure

cold laurel
#

And don't call EventToggle(); from OnDeserialization()

#

You will create a massive feedback loop

#

and everyone will die

meager mauve
#

Oh my

cold laurel
meager mauve
cold laurel
#

You need to call ColliderArray() in OnDeserialization()

meager mauve
#

Oh...

#

Networking is hard....

cold laurel
#

I don't think so.

meager mauve
#

I'm just too new to it I suppose lol.

cold laurel
#

You'll get the hang of it.

tulip sphinx
#

I just need a random int value that is consistent for every player in this world's instance and different in another. I dont need to change it, I dont need to give any player any control over it, it just exists. Like idk, today you join - walls are red, next time they're blue.

cold laurel
tulip sphinx
#

pic 2 - first two steps, pic 3 - third. But i guess if i wrote it in pseudo code it would make more sense

#

i have no idea what im doing since udon networking docs is a... thing

cold laurel
#
  • On Start check if the local player is the owner of this object.
  • If so, check if a random number has already been generated.
  • If it hasn't, generate a random number.
#

you will need a synced int, and a synced bool

tulip sphinx
#

Step 4- how do I actually access it from everywhere

cold laurel
#

(there's probably a way to do this that doesn't require the bool but whatever)

tulip sphinx
#

i ignore bool since uninitialized int is 0, and initialized is greater than

cold laurel
tulip sphinx
#

2nd pic

cold laurel
#

Add a second branch that only proceeds if the local player is the owner of this gameObject

tulip sphinx
#

Is the first player is always owner of all objects by default?

cold laurel
#

yes

cold laurel
#

Then in OnDeserialization you just apply the the things the random number impacts.

meager mauve
#

ColliderArray is not firing do I need to add it to the OnValueChange list.

cold laurel
tulip sphinx
meager mauve
cold laurel
# meager mauve

yeah, it's not being called because you stopped calling it

#

you need to have it here at the bottom

meager mauve
#

LOL ok

cold laurel
#

OnDeserialization() is only called for remote players

meager mauve
#

Oh got it.

tulip sphinx
cold laurel
tulip sphinx
#

Ok, how do I access this data in 3rd pic. I.e. send this into animator. Is having the same name for int is enough? Somehow i doubt it

cold laurel
#

Are you sure you only want to do those things on interact?

#

I thought you wanted the world to automatically look different

tulip sphinx
#

this part of the world is disabled and i already have script that enables it on interact

#

And I dont get OnDeserialization part as well, ok it deserialized, what do i grab and where do i store it

cold laurel
tulip sphinx
#

maybe next time

tired quail
# cold laurel

Also, isOwner checks if the user is the owner and returns a bool, it doesnt set the owner which is what I assume they're trying to do

cold laurel
#

I totally overlooked it

#

lmao

#

Bit tired

tired quail
#

is if the non owner clicks it it just wont update, lol

#

or it will only do it locally? idk, its weird in that case

cold laurel
# meager mauve

You need to SET the owner.
Networking.SetOwner(Networking.LocalPlayer, gameObject);

meager mauve
#

Oh thanks fo the heads up.

tired quail
#

Is there any sort of queue for network events, or is it possible for them to get skipped under some circumstances?

EG: Say i have a list and when a user pressed a button it adds that users username to the list.
If two users press the button at the same time, could they interfere with each other or will they both happen in succession and they both get added?

#

Adding them to the list just being

Take ownership of object
Add name to list
request sync

#

Or is there a way to detect that there's a pending change and to wait to apply your local change until after that's been synced

frozen igloo
frozen igloo
#

you are describing synced variables. And the limitation there is that only one person can have ownership of a specific object at a time. So if two people click it at the same time, one will likely stomp on top of the other. Synced variables are only "eventually consistent", meaning that eventually everyone will agree on the state. It does not guarantee that every individual intermediate state is synced on all clients

#

if you expect multiple people to need to send data through synced variables at once, then you should have multiple objects where each player can send their data through independently

tired quail
#

True sorry, wrong words. I just meant any data occurring over the network, not udon-networked events specifically. I should've been more specific,

#

I dont expect everyone to be trying to press the button at the same time, but I want to make sure to handle any possible edge cases just in case.

frozen igloo
#

if this is something where the users are manually pressing the button, then one way to handle it is to immediately detect and provide feedback that you have been stomped on. For example, if you press the button and add yourself to the list, something lights up. If you get removed from the list, it turns off. So if you click it and it immediately turns on then back off, you can just click it again and you'll be good

tired quail
#

Yea, that seems like the simplest solution. 🤔

frozen igloo
#

alternatively, if this is something like a lobby system, pressing a button is not the only way to do it. You could also have a square/circle on the ground where people step into

tired quail
#

In could as you say, have a whole bunch of data objects and assign one to each user to store each users data, but i feel like one data object would be a little more efficient than one per user.

frozen igloo
#

well if this is a complicated game world, then it's possible you'd need player objects for other reasons anyway

#

once you have them, then adding one small thing to them is not a huge deal

tired quail
meager mauve
#

Ok so I suck at Networking. I can't for the life of me figure out why this isn't working.

#

I'm literally just trying to toggle 3 objects on Oh...Never mind I just realized....

#

I think

#

The objects were not synced.

#

I can't sync the array. GameObject. Hummm

#

Anyone have any idea's? I'm sure it's just something simple I'm overlooking.

cold laurel
meager mauve
#

Oh so just SetActive(isOn)

cold laurel
#

yea

meager mauve
#

Thanks again.

meager mauve
#

General Networking question. Can I have a locally toggled parent object with a Networked toggled child object?

meager mauve
#

Ok thanks

high elm
#

is there a better way to do what im doing here? this feels wrong.

#

i dont think the networked event should be firing locally but im not sure how to stop it from doing that.

#

or rather in a way that doesn't send the net event locally and only receives remotely.

humble girder
high elm
#

ok cool.

cold laurel
high elm
#

probably not but i'll keep that in mind if it ends up causing problems, thanks.

tulip sphinx
# cold laurel Please watch this <@960486335095914526>

Ok, I watched this and it was a complete waste of my time except verifying that network events are indeed trash. It did not clarify to me in the slightest how to reuse my variable nor it contained any proper full examples, let alone that I never mentioned using U#.

#

So ok I butchered some default examples and got this, no idea if it works/syncs for now
`using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class World1 : UdonSharpBehaviour
{
[UdonSynced]
int SyncedInt;
public override void OnDeserialization()
{
Debug.Log(SyncedInt);
}

public void Start()
{
    Networking.SetOwner(Networking.LocalPlayer, gameObject);
    SyncedInt=123;
    RequestSerialization();
    Debug.Log(SyncedInt);
}

}`
but at least I get log output

#

but then i try to reuse it and get 0

#

Does Client Simulator even works with networking properly? If it does then I have problems. If it doesnt, how do I even debug

#

Should output 1 on start, 3 on second player joined, 6 on third etc since its fired for every player. But it just goes 1 2 3

#

ah I have no game object

cold laurel
#

Yeah because all the clients are trying to take ownership of the same object at the same time????

#

If you just want to count how many players have been in your instance you can infer that from the ID assigned to the player

tulip sphinx
#

Im just trying to make sure this runs for every player

tulip sphinx
cold laurel
tulip sphinx
#

Ok, anyway. How do I access variables

cold laurel
#

What do you mean?

tulip sphinx
#

Across the scripts

#

Other than player tags

cold laurel
#

I am so confused

tulip sphinx
#

Look a bit higher

tulip sphinx
tulip sphinx
#

Expected: "local1" "remote2", "local2" "remote3" etc on each Spawn Remote Player. Actual: "local1", "local1" etc. Deserialization does not fire.

#

ignore sssss

#

First "Thats me" fires, no deserialization at it as well but i guesss i dont need one as an owner

#

Ownership does not transfers if I to believe script's preview in inspector

tulip sphinx
#

And, nope. This one transfers ownership allright, OnPreSerialization fires never, var is 0

quaint rain
#

For network testing you will need to do it in client

tulip sphinx
#

And how do I log in client

quaint rain
#

From the VRChat builder window you can launch multiple clients at once

tulip sphinx
#

*And how do I Debug.Log("asdf") in client

quaint rain
#
VRChat

These are the tools you can use to debug your worlds in-game.In order to access debug views you need two things: Launch VRChat with the launch parameter --enable-debug-guiPress Rshift + Tilde + 1-9. If you have a keyboard layout where tilde is not directly to the left of the 1 key, try using whichev...

#

To open the output log in client

tulip sphinx
#

Ok, can you also tell me how do I get access to the same variable, synced or not, in different scripts, other than player tags

quaint rain
#

You would need to use one Udon behavior to store the variable, and then in any other Udon behavior you can reference the script that has that variable and use: UdonBehaviour.GetProgramVariable("VariableName")

#

There is also SetProgramVariable that you can use to modify variables in one UB component from another UB component

cold laurel
quaint rain
#

I have never checked though

quaint rain
tulip sphinx
#

not recognized as instance, same for UdonBehavior[].Get

quaint rain
#

Don't use UdonBehavior[] it is not supported

cold laurel
#

Weren't you using U# just earlier?

tulip sphinx
#

thats the only thing Instance point offers

tulip sphinx
#

I want to recieve variable in nodes

quaint rain
# tulip sphinx

You can store the reference as a GameObject as you are here and then use GetComponent typeof UdonBehaviour

#

Probably the easiest way in Graph

quaint rain
tulip sphinx
#

Null, with/without toString

#

oh wait typo

#

nah, still null

humble girder
tulip sphinx
#

?

humble girder
tulip sphinx
#

Whats the difference?

humble girder
tulip sphinx
#

Thats irrelevant

humble girder
tulip sphinx
#

Yes I said so and i fixed it

humble girder
tulip sphinx
#

in log output

humble girder
tulip sphinx
#

Ah whatever, I give up till next time. I originally asked what I consider to be trivial thing and've been sent to watch 1hr video, then had to read god knows how much on u/u# and I still have no idea. I just spawn invisible synced prop and modify/read its coords. Works like a charm

hollow wagon
#

I am stuck here. I know I am doing something fundamentally wrong but I cant find a good solution. I have a control panel where I have buttons with IDs and I am sending the IDs to this udon script. In this script I want to check if the user is instance owner and if not instance owner I want to check if he is on the whitelist to change the variable. I am setting the variable and trigger the onchange event for everyone but it seems it doesnt work, probably because only the owner can change the synced variable? But how would I send the ID from a user to the owner then? I think my system here is overcomplicated but I have no idea how to do it better. Actually I just want to send an integer to a function and sync it between everyone.

sweet wolf
hollow wagon
cold laurel
#

SetOwner to be localPlayer, Update the value of the variable, RequestSerialization
Then OnDeserialization runs for everyone else.

hollow wagon
#

How do i set owner to local player?

quaint rain
cold laurel
#

Does graph even warn you about anything

quaint rain
#

Yeah when something is 100% broken it usually gives an error or warning 😅

cold laurel
#

😐

#

Ait

hollow wagon
#

didnt get any warning here

#

So I would do this instead. But will it actually sync the ID for everyone?

quaint rain
#

Also are you testing in client or in editor?

hollow wagon
quaint rain
#

If you hold: Right Shift, ~, 3 it will bring up the output log in client

#

As for the AntiCheat warning if you go to the settings panel in the VRCSDK you can go and find your game install and target it to launch VRChat.exe and that should allow you to launch multiple clients

sweet wolf
# cold laurel What

What, what? See examples, learn udon.
It is not necessary to constantly change the owner, you can change the variable on his behalf.

cold laurel
sweet wolf
weak mirage
#

However if it's not a button that'll be spammed by lots of players at once it's fine

cold laurel
cold laurel
cold laurel
#

Please explain how you suggest doing this.

#

Lol

sweet wolf
cold laurel
#

Obviously you don't

#

Since you can't provide a basic example.

sweet wolf
cold laurel
#

What a clown

sweet wolf
#
VRChat

This scene is ready to Build & Test or Publish, and it demonstrates many common interactive items.PrefabsThese objects show off some of the Prefabs included with the SDK which demonstrate default interactions with the VRChat components for Avatar Pedestals, Stations and Mirrors. AvatarPedestalTh...

cold laurel
#

You are blind

cold laurel
# sweet wolf

Also, sending a network event doesn't show how to "change the variable on his behalf" 😆

#

Your claim of changing a networked variable on an object you are not the owner of is still unfounded

#

There are plenty of ways to do it without changing ownership, but this is not the way lol.

sweet wolf
cold laurel
#

What a respectful, helpful and charming little fellow.

dusky bobcat
#

If I just add this and select synchronization method, should it just work? Its probably not the most optimal way for me to update it every frame but would be nice to know for testing

cold laurel
dusky bobcat
#

Basically trying to synchronise UI output

cold laurel
#

UI for?

dusky bobcat
#

VSCode, yes light theme 💀

cold laurel
#

Why

dusky bobcat
# cold laurel UI for?

Uhh not sure if I want to go into details at this point, basically a canvas that has a UI.Text component

I can add text to it using an input field and a button, after which I want that text to be synchronised between clients

dusky bobcat
# cold laurel Why

I don't know, just got tired looking at the dark theme for the past few years

#

I prob will switch back to dark theme at some point though

cold laurel
#

Are you overwriting the whole text on the UI?

dusky bobcat
#

I guess you could call it that

cold laurel
#

okay

#

That makes it a little more complicated.

dusky bobcat
#

Yes, I couldn't find a way to access individual lines of the Text component

cold laurel
# dusky bobcat

You should be using

if (!string.IsNullOrWhitespace(previousMessagesArray[i])) continue;
#

I might've messed up some capitalization I don't have my IDE open rn

#

The way you currently have it set up makes it so if two people send a message at a similar time one of them will be overridden by the other

#

Race condition my beloved

dusky bobcat
#

Well I thought of that and I have another bool for that

cold laurel
#

what

dusky bobcat
cold laurel
#

What you should be using is a player object pool

#

Then each player can have their own networked object

#

You can send data through these

#

Essentially you'd create an event buffer

#

And let the owner of the UI.text handle appending the messages

#

This way you have no race condition

dusky bobcat
#

Like I have a bool that is set to true whenever someone sends a message, it is then "processed", and then outputted, after that the bool is set to false again.

When the bool is set to true it makes it return in the "processing" function.

Though tbh right now I am less worried about that and just want to get synchronisation working at all for a test

#

I have other things to solve before I would be worried about race condition

dusky bobcat
#

Alright so with the way I have it right now it does not synchronise the textbox it seems, weirdly enough though it synchronises the input field even though I did nothing with that, must be default behaviour

cold laurel
#

Use manual sync and public override void OnDeserialization()

dusky bobcat
#

Also IsNullOrWhitespace did not work for me for some reason just marked all text as such or whatever but probably my faul, not relevant for now

dusky bobcat
cold laurel
dusky bobcat
#

will that synchronise only the variables with [UdonSynced] ?

#

as i dont want every variable to be synchronised

#

And I assume i select manual here too

cold laurel
#

What would the purpose be of having the [UdonSynced] attribute if all fields were synced regardless

dusky bobcat
#

Fair

cold laurel
dusky bobcat
#

So should i select none and only have it as [UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]

cold laurel
#

you don't need to select anything

#

just put it above your class

dusky bobcat
#

yeah but i still have to select something in the U# component?

cold laurel
#

What if, you put in the thing, and observed what happens in the inspector

dusky bobcat
#

Mb, forgot to Ctrl+S

cold laurel
# dusky bobcat Any examples on how can i manualy sync?
[SerializeField] private Text myUiText;
[SerializeField] private InputField YourInputField;

[UdonSynced] private string UiText_SYNCED;

private VRCPlayerApi _localPlayer;


private void Start()
{
    _localPlayer = Networking.LocalPlayer;
}

public void _onValueChanged()
{
    Networking.SetOwner(_localPlayer, gameObject);

    UiText_SYNCED = YourInputField.text;

    RequestSerialization();
    ApplyTextToUI();
}

public override void OnDeserialization()
{
    ApplyTextToUI();
}

private void ApplyTextToUI()
{
    // Do the thing
    myUiText.text = UiText_SYNCED;
}
#

probably a lot of wrong capitalization etc.

#

since I wrote it in discord

#

and not an IDE

#

but it should get the point accross

dusky bobcat
#

Okay thanks

#

That works perfectly, thanks a lot

hollow wagon
#

Coming back to my question from yesterday. I got confused by all the discussion here so I dont really know what to do here. So this whole script works fine for owner but it still wont work for the admin user in the upper branch. I still guess its because only the owner can change the variable. So the only way for me to do it to give temporary owner to the player? How exactly would I do it if thats the correct way to get this variable synced?

frozen igloo
#

just do networking setowner to the localplayer before changing any synced variables

frozen igloo
#

yes

hollow juniper
#

what is this and how do i get it

#

nvm i found it

hollow wagon
# hollow wagon like this?

This seems to work fine but I still have syncing issues on quest. Is there any reason why this wouldnt work on quest. Especially when a quest user is admin. Then it doesnt do anything even for me as admin getting the owner. Its like quest cant change the integer.

viscid pike
#

Why are the OnPlayerJoined and OnPlayerLeft events not working? Nothing is happening

frozen igloo
viscid pike
frozen igloo
#

more details? Again that should work

viscid pike
#

I have also updated my SDK

frozen igloo
#

is this object disabled maybe?

viscid pike
#

no it's active

frozen igloo
#

and where/how are you testing? Editor? Clientsim? local test? published?

viscid pike
#

local test and published

frozen igloo
#

the only case where this shouldn't work is editor without clientsim

#

can you just take a picture of the whole event?

viscid pike
viscid pike
frozen igloo
#

can you share a picture of the udonbehaviour component where this script is placed?

frozen igloo
#

I'm not sure what to tell you. I mean I could keep asking for pictures of various things for a while but there's gotta be something somewhere that is not set up correctly. Do you have anything weird or uncommon about how this is set up?

#

This looks like a prefab, does that prefab actually exist in the scene?

viscid pike
#

nope, I have a StringDownloader on this object if that's an issue?

frozen igloo
#

nope

#

oh, are you sure this script isn't crashing from something else before it even has a chance to get onplayerjoined?

#

or rather, are you sure this script is even running in the first place?

viscid pike
shy trout
#

Hello, I'm using OnDeserialization to keep players updated with the current synced variables on my scripts but I have never used OnPreSerialization before so I'm confused on how to use it properly and what it would look like setting it up.
I see it is defined as "This event triggers just before serialized data will be sent out, it's a good place to set synced variables that you want to be updated for other players."
I kind of get it but what would be a good example of when or why to use this event?
I'm confused on how to use it properly. for most of my scripts they are set to Manual and I call RequestSerialization from the gameObject owner when I need synced variables to be sent to everyone else

frozen igloo
# shy trout Hello, I'm using OnDeserialization to keep players updated with the current sync...

if all you're doing is setting a synced variable and then doing requestserialization, then that's all you need to do. OnPreserialization doesn't need to change that workflow, and you can keep it simple.

What OnPreserialization is good for is when you want to apply some sort of final step right before the data is sent off.

A good example of this would be if you want to sync a datalist/datadictionary. These can't sync on their own, but you can sync them through json. So OnPreserialization, you could convert it to a json string and then ondeserialization, you convert it back to datalist/datadictionary.

Another example may be a case where the precise timing matters a lot. Say you want to adjust a specific timestamp right at the moment in time it gets sent, OnPreserialization is the time to do that.

Another example may be a case where you are creating a sort of event buffer. Throughout your program, you may send a dozen events within a second, before it gets to serialize. In OnPreserialization, you could bundle up all those events into a format that can sync.

shy trout
normal sundial
#

Hi, in not sure i quite understand how the data rate limits of networking apply. If theres a doc that explains it id love a link to it, otherwise hoping someone can help me understand. From what ive been told the rate limit is about 10kb/s, of which about half (conservatively) is used for players/avatars.

Lets say that in my world i have two spheres. Players can only ever be in one of them. If they are in sphere A, they only need to sync the objects in sphere A. Likewise with sphere B. If i have 5 kb of objects i need to sync in each sphere, and assuming i am already using 5kbps of the limit for avatars and players, what happens when two players enter sphere a and b, one each, at the same time?

Does the world interpret this as trying to pull 10 kb overall, or can it do this just fine since each player is only syncing the 5 kb from avatars and then the 5 kb for their spheres?

Or am i just completely misunderstanding how syncing works

sweet wolf
normal sundial
#

Tyty 🙏

frozen igloo
#

there is pretty much no limit to how much you can receive

#

so two users sending 5kbps each only counts as 5kbps

normal sundial
#

Awesome, thanks! I think that is best case scenario for me!

#

Much appreciated, once again!

#

🙏

hollow wagon
#

Is it possible that setting variables is not possible even for owners in public instances? Do I have to set owner manually every time?

frozen igloo
hollow wagon
frozen igloo
#

you're gonna have to provide more details of what you're doing and what you're expecting to happen. Sounds like you have some custom system that is preventing you from doing things

hollow wagon
#

I basically just want to change the int variable for everyone. but its not reaching other people in public instances.

left raft
#

I'd like to do manual sync, but also sync position of grabbable object, why won't work?
Do I just need to use ObjectSync ?

frozen igloo
left raft
frozen igloo
#

I'm not quite sure what you're asking, then, do you have a question? Is there something about your code that is not working as expected?

left raft
#

Yes and yes, the position/rotation of the grabbable gameObject does not get replicated to other clients after manually setting it like above!

#

Shouldn't the position update on all the clients?
Is RequestSerialization and everything being used correctly?

frozen igloo
#

Are the variables marked as synced?

left raft
#

yes!

frozen igloo
#

And what event is the first picture in?

left raft
#

Update()!

frozen igloo
#

Is this instantiated at all?

left raft
#

not instantiated, a placed object!

frozen igloo
#

Oh, I don't see anywhere where it sets POS and ROT

#

Oh nvm that's the last image

#

I don't see anything wrong with this code, could you show me more?

left raft
#

Well what exactly, this is most of it

#

It's just a grabbable object and the position is trying to be set like that

frozen igloo
#

What happens in update before/after the first image

left raft
#

nothing that should affect the coordinate sync!

frozen igloo
#

Can you show me the synced variables and also the inspector for his object?

left raft
frozen igloo
#

Oh, well you have compile errors

#

Also this is set to continuous

left raft
#

found a workaround but it would be a handy thing to move a manual sync object around

frozen igloo
#

???

left raft
#

(compile errors are bcs I completely changed the script and mashed undo to get the screenshots)

frozen igloo
#

It should work. But I will say if the whole reason you're doing this is because you want manual sync on the same object as position sync, you're doing it wrong

#

It's a lot of work to make a good looking manual sync script, with interpolation and everything

left raft
# frozen igloo ???

As in I've found how to implement the thing just fine without manual sync but having position sync+manual sync would be king

#

yeee.

frozen igloo
#

I mean it would work but with all this undoing and compile errors I don't know what to think

#

The only problem is that it wouldn't interpolate, it'd be choppy. And it takes a lot of work to smooth that out. So you'd be better off just using objectsync and putting manual sync on a different object

left raft
#

Interpolation/prediction was the plan but it doesn't update at all
I can get the code and everything back in it's entirety and send it but it's just some other logic that doesn't touch the movement sync!
was just curious why setting coords and manually synching resulted in the object still

#

not syncing pos

#

Like if the grabbable component messes it up or there's a function I'm not aware of or smthn

frozen igloo
#

I don't see any problems with what you've posted except for how it was on continuous and you had compile errors. I can only assume there's something you're not showing me or telling me that would cause the problem, or you're not testing it correctly

left raft
#

Alright, thank you!
If there was nothing wrong with the snippet then uh must be something else

frozen igloo
#

Or, again, it's the continuous or compile errors

left raft
#

compile errors werent there when I was running the code in full, and the object was set to Manual hold up I'll get a fixed screenshot.

frozen igloo
#

Are you certain that you have tested it while it was set to manual sync

#

If it was continuous, the int array would likely cause the whole thing to not work

left raft
#

oh yes!
I'm certain!
I only set it to continuous just now while doing a continuous+ObjectSync solution.

#

Found ObjectPool which can seemingly hold and sync a whole bunch of objects

frozen igloo
#

That doesn't really fix this specific problem

left raft
#

Doesn't no

frozen igloo
#

Object pool only syncs the active state, not position

#

If you want to diagnose your manual sync script, try adding onpostserialization and debug log the serializationresult

left raft
#

I was making a dice cup, the object pool holds the dice which are synced just fine with their own components

#

before I was doing int array stuff and trying to instantiate them

#

I'll try that when I try to do this again, but it was very helpful to know that the code was seemingly correct

storm beacon
#

I've been informed that CinemachineVirtualCamera "is not supported by Udon sync". Unfortunately, how I've designed the camera system in my world uses them extensively, and I did want them to be network synced.

I had a version of this post with a code snippet but the bot unilaterally claimed it was spam and deleted it.

frozen igloo
# storm beacon I've been informed that CinemachineVirtualCamera "is not supported by Udon sync"...

I'm not personally familiar with cinemachine, but I assume that the reason why it's not compatible would be either referring to objectsync being overridden by it, or certain functions not being exposed to udon.

Either way, it should be possible to do what you want and if what you want is to simply set a certain priority, and those functions are exposed to udon, then there should be nothing stopping you from plugging values from udon sync into the cinemachine priority

wild basin
#

Ohhhhhhh that's why my particle system are not positionnate properly!

meager mauve
#

If a networked object is out side of the render distance will it stop functioning?

frozen igloo
#

and it has nothing to do with render distance

meager mauve
#

Just checking

restive cliff
#

Let's say there was a spam of SendCustomNetworkEvent, would these arrive in order?

frozen igloo
#

I'm actually not sure if the order is guaranteed. But I do know they're guaranteed to arrive as long as they aren't in the queue longer than 120 seconds. The speed of the network event queue is dependent on network conditions and ping to the region server, and 120 seconds means roughly 5k-10k events

spring sapphire
#

How can I spawn a new prefab on runtime using udonsharp on a global instance (meaning on all instances)? So I can sync data to the new object.

humble girder
spring sapphire
#

Which means they have to be already existing in the scene correct?

spring sapphire
#

okay thanks

wild basin
#

Hmmm it seems that even the object from my pool were not syncing variables.
Or i did something wrong...

Anyway, i did a different setup where my manager sync the initial data of my pooled objects and it works

#

I dont know why on my Brick gameObject
I had udon sync variables with manual network synchronisation
And calling RequestSerialization was not calling OnDeserialization

cold laurel
#

Are you sure the player calling RequestSerialization is the owner of the object?

wild basin
#

Yeah that what I said

#

I was calling Request on the owner
And OnDeserialization was not called on others

wild basin
wild basin
sand ginkgo
#

Hi, I am trying to have an object follow the object owner, and have this be seen for everyone. I don't want to use VRCObjectSync, since it is too slow to update for the game I'm working on. I basically am trying to get each player's position (via a GameObject for each player), and it Updates the position for everyone.

Here's what I have:

VRCPlayerApi ownerPlayer; 
Vector3 playerPosition;

public void AssignThisPlayerPosition()
{
  Networking.SetOwner(Networking.LocalPlayer, gameObject);
  ownerPlayer = Networking.GetOwner(gameObject);
}

private void Update()
{
  playerPosition = ownerPlayer.GetPosition()
}

It seems to work in ClientSim, but when in the VRC Client it says the API is Null.
Any assistance would be appreciated.

If there's a prefab I can get something like this from, that works too.

frozen igloo
sand ginkgo
#

@frozen igloo OK, this prevents errors with an if statement (I logged it as a warning instead, so the udon script isn't stopped). But why would the PlayerAPI return it as invalid?

frozen igloo
sand ginkgo
#

@frozen igloo I have an if statement (in the update loop) that checks if the object has been assigned, which is not shown in this code. If you want I can send the full code.

frozen igloo
#

well you do now

sand ginkgo
#

@frozen igloo Hmm, I don't know how to go about this then. I got it to work with Networking.LocalPlayer, but it doesn't work with Owner. Do you have any advice?

frozen igloo
#

oh that's a different issue then. Is this object instantiated?

sand ginkgo
#

@frozen igloo No, it's a predefined object that is always active in the scene.
(Not sure if you want me sending mentions or not lol.)

frozen igloo
#

is it none sync?

sand ginkgo
#

Manual sync

frozen igloo
#

are you trying to getowner very early, like onenable or start?

sand ginkgo
#

Yes, on Start, but also when the player interacts with a button to become a player of the game

frozen igloo
#

Start would be too early to know what the owner is, and interact only happens for the person who clicked it. If this is supposed to just always follow the owner whoever that is, you should probably use the onownershiptransferred event

sand ginkgo
#

I tried using OnOwnershipTransferred as an override method, visual studio was saying it was obsolete, and I cannot find another syntax of how to use it anywhere.

frozen igloo
#

The version with no arguments is obsolete, there's another that I think adds the new owner

#

Check how graph does it

sand ginkgo
#

I'm still getting that it's not valid even after calling it with OnOwnershipTransferred.

public override void OnOwnershipTransferred(VRCPlayerApi player)
    {
        ownerPlayer = Networking.GetOwner(gameObject);
    }

Do I even need to use the argument here?

frozen igloo
#

You could also just get owner in update

sand ginkgo
#

Well... I have no idea. When I do build and test the log still says 'Could not Execute! Connected - api is NULL!' even when it's trying to get owner every frame.

frozen igloo
#

What what that has nothing to do with vrcplayerapi

#

That's like invite notifications, which don't matter in a local test

#

Is that the whole reason you thought this didn't work? Are you actually testing the thing itself?

sand ginkgo
#

Yes. Although I think I was too focused on the logs, I don't usually see that error so I thought it was related. When I observe it looks like this worked. The object seems to follow each player on both clients now.

#

Yeah, it's working flawlessly now. This really did help, thank you very much @frozen igloo 🙂

#

Incidentally, it would be awesome to have a toggle to only show my own logs, not all VRC client logs.

cold laurel
fresh stump
#

heyoo i have a question, what will happen if lets say we have a owner of an object and all of the stuff is synced to every user, but then the owner of the object crashes and a new person joins

#

would they get blank data or would it automatically assign some1 else as a owner and retain the data

fresh stump
#

so ownership gets transfered to the oldest person which could be the master right ?

frozen igloo
fresh stump
#

YESS

#

doing a double manager syncing system since i need one script to stay owned by the master and another for updating a list of players by users

manic torrent
#

Need help with UDON! When a person enters the zone, VoiceFar becomes much smaller than the default. At the same time, it must be local. And it applies to all players. Any ideas how to do this?

frozen igloo
tough burrow
#

I think he's looking for ways to make the voice distance smaller when inside an area but just for the players inside said area ?

#

Unsure, words peepoTalk

gray kiln
#

Is there a way to only sync a variable to certain players?
Alternatively, will new players get the latest state of a manually synced var, while older players will only get updates when serialize is called?

frozen igloo
#

and I'm not entirely sure wha the second part of your question is, but anybody joining late will receive the latest serialization from each object, which is the same thing that other players may have received minutes ago

gray kiln
#

Damn, that's what i wanted to setup - newer players get a full sync of the vars current state, while older players get one inital sync and then recieve events for small modifications of the var

#

Alr, thx

frozen igloo
#

are you just trying to save data?

#

manual sync can do a lot

gray kiln
#

I think i got an idea-
I'll have one big synced var that holds all the data, and then a smaller synced var that stores recorded modifications of that data

so you sync the big var once, and then sync the small var for each change
(maybe the small one only syncs when a new player joins, since modifications are driven by rpcs to everyone)

then when the small var gets big, you internalize those changes to the big var & sync that

and then loop

#

That way you can sync a bunch of changes to a massive var over time, without constantly resyncing the massive var

frozen igloo
#

yeah, having "big data" and a separate "fast data" is a valid technique. Just be aware that this is not separated per-variable, but rather it's separated per-object. You'd need two different scripts on two different objects to do that

#

and there is no reason you need everything to be in one variable. You can have many variables on one object and they'll all sync together

gray kiln
#

Ah, but i'm trying to create a minecraft-esque 16x256x16 grid of "blocks", and i dont want to have a massive pool of block objects that could run out
i'm already doing optimizations for storing rectangular groups of the same type of block

frozen igloo
#

ah, a minecraft system makes a lot more sense

#

indeed, separating between big data and fast data is a good idea. I'd recommend having just the master control the big data and then every player has their own fast data

gray kiln
#

Oh definitely, fast data should only be synced when a new player needs it

frozen igloo
#

no, that's not what I'm saying fast data is

#

I'm saying fast data should be used for every time a player makes a change. They dig a block, they place a block, etc. And don't forget to queue up multiple block changes in case they place/dig faster than it can sync

#

and then the master receives that and applies changes to the big data, and resyncs it occasionally to make sure everyone is on the same page

manic torrent
#

Basically, I have a glass box. So I want this: when a player is inside the box, he barely can hear anyone including people near him and far from him

frozen igloo
manic torrent
#
  1. I don't want people in box hear other players
#

(except world audio)

frozen igloo
#

that wasn't a multiple choice, it was two separate questions

manic torrent
#

I mean, I want only option 3

frozen igloo
#

I understand you don't want the people in the box to hear the outside, I'm asking about the other edge cases that you're not describing

manic torrent
#

Alright, 1 sec, I'll show

frozen igloo
#

you don't need a diagram, it's a simple question

manic torrent
#

Basicaly, it is a box. When player enters it, he can't hear other players outside and inside the box

#

When he leaves it, he can hear anyone

frozen igloo
#

okay so the person in the box just can't hear anything

manic torrent
#

Ah, also, outside people can't hear people that are inside the box

#

Yep

frozen igloo
#

and people outside the box can't hear the person inside the box

manic torrent
#

Yes or they can just with lower voice range

#

2 options are good

frozen igloo
#

this is kinda complex then. What's your familiarity with udon?

manic torrent
#

Uuuh, I actually made it

frozen igloo
manic torrent
#

But the problem I have - it is not reverting back when player leaves the area

frozen igloo
#

that was what I was trying to ask in the first place omg

manic torrent
#

:omega

frozen igloo
#

okay so just onplayertriggerexit just undo everything

manic torrent
#

Yep

frozen igloo
#

set back to defaults

manic torrent
#

It has everything the same but reverted

#

For example, "when players enters trigger, volumeFar is 1.3" <- this works

#

But "when players leaves the trigger area, volumeFar is 5" <- doesn't work

#

Both have the same code, just different numbers and event

frozen igloo
#

the default VoiceDistanceFar is 25

#

if you want to return to default you should set that

manic torrent
#

Yep, I override it to 5

#

Since in my world default is 5

frozen igloo
#

that's really low

manic torrent
#

I know, thats the idea

#

Anyways, the problem is that is not reverting back

frozen igloo
#

can you show the code/nodes?

manic torrent
#

Yep, opening the project

#

@frozen igloo

#

And for when player exit trigger area

#

The first part works very good, but the second just not

#

Currently, I use "hack" with 2 scripts with "area trigger enter"

#

1 for inside of the box which is decreasing voice range

#

and the second script - on the door to the box so when they leave the box, it runs "triggerEnter" event with "reverting" back to 5

#

It works but I am 100% sure it is not the best solution since it requires more areas (4 in my case) in scene instead of 1

#

So it looks like this. Area on right side is for people that came from spawn just in case they click "respawn" while in "1,3m" cube. All "VoiceInBox" and "VoiceOutBox" scripts are in continuous sync

gray kiln
#

Will Serialization happen if there's only one player in a room?

frozen igloo
#

the serialization will be saved on the relay server so that when a late joiner comes in, they can receive that directly rather than the people in the instance having to re-send it

gray kiln
#

Alright, sick - was that changed recently? I havent developed stuff in vrchat in a while, i remember having to setup flags and resync when the first non-host player joined.

frozen igloo
#

it did change about 8 months ago, but not in a way that matters. Previously, the relay server was incapable of storing anything so when a new player joins, the other players would have to resend everything. But that was handled automatically, so if you ever did requestserialization at any point while solo, it would automatically serialize when someone joined. I would bet that the flags and resync you did manually was either unnecessary or only necessary because you were doing unconventional things, like late join sync by network event

wild basin
#

Ohhh so an instance can keep running a long time before resetting all the data? Or is there always 1 public instance that keep running indefinitely?

humble girder
wild basin
#

Ok thanks

warm ferry
#

Hi, can anyone help me with making my slider sync when you enter a specific area?

spring sapphire
#

Is there a way to create an area and boost microphone volume to be heard throughout the whole world? And rather make the microphone audio be 2D rather than 3D?

tulip sphinx
hybrid dagger
#

Looking for someone who is proficient in udon graphing to help me with a potentially major project

stone badger
#

I've omitted something important. I have a ship in my world and I have made it so it sail using a path & dolly. The first issue is that when multiple players jump onto the ship they end up in various places in space but everyone sees themselves as on the boat. So I see 2 people standing in the air 10 and 20 feet away and each of them sees the same thing. This is before the ship starts to move so I'm wondering if it has something to do with the Cinemachine dolly and the path attached to it. Any idea?

sweet wolf
stone badger
frozen igloo
# stone badger I've omitted something important. I have a ship in my world and I have made it s...

The reason this happens is because even if everybody sees the ship at the exact same place at the exact same time, there is an additional latency between the players as they send their position to each other. As a result, it is impossible to use normal, global position sync and have multiple players all in sync on a moving platform. The solution to this is that the players should be in stations, which will ignore their synced position and instead all players will see each other forced into the stations.

stone badger
#

I guess that wouldn't work as they are essentially sitting regardless.

frozen igloo
#

ultimately, if you want the players to move on the deck, you'd need a fully custom player controller. This is a really complicated topic and it has a lot of caveats, but you may have some success with this prefab: https://booth.pm/ja/items/4690338

Boby’s Planet Movement is a VRChat prefab that allows players to walk and platform around 3D planets using gravity fields. This system can be used to make space-like platforming worlds, 3D puzzles, and spacecraft multiplayer wars. The unity package file contains the main planet movement controller

stone badger
#

So am I correct in saying each player would need to have their own ship much like the car examples have?

frozen igloo
#

no, that's not the issue

stone badger
#

I have a prefab that is handling the movement on the deck. Someone was nice enough to give it to me.

#

Each player was on their ship in this case and could walk around.

frozen igloo
stone badger
#

So if I have one ship. One person could get on it and sail? Would everyone agree where the ship was?

frozen igloo
#

yes, everyone would agree where the ship was but the problem is latency

#

another solution would be to move the world around the ship instead of the ship within the world. But that would put a strict limit on how much you can do with the world, because the world couldn't be static

stone badger
#

That's not possible in this case and would preclude having multiple things to travel on.

#

Bummer.

#

How would the latency manifest itself? What would everyone see?

frozen igloo
#

player A would sync the ship and themselves to everyone else. Player B would then sync themselves at the location that they see. Then player C would see the ship where player A says, but then they'd see player B further behind because of the added latency of traveling from B to C

stone badger
#

umm... you mean if multiple players were on the ship right? I'm considering one person at a time at this point. I just need the other players to see the ship in roughly the same location in the world along with the player that is riding along.

frozen igloo
#

yeah, if everybody has their own ship then you're just facing an implementation problem, not a physics problem. In that case, you'd need to build a custom sync that matches the player's simulationtime

stone badger
frozen igloo
#

oh, I guess that's also an option. The same solution would apply

obtuse echo
#

I have a question about how to deal with disabled objects and receiving data.

From what I've noticed, OnDeserialization is not being called on disabled objects in general. Thing is, those objects are enabled shortly after, but it seems like their opportunity to call OnDeserialization is already gone.

I am encountering this with Cyan's object pool and was wondering if there is a way to quickly receive the data again? So let the network manager call OnDeserialization for me again.

My solution has been something like this so far:
After joining, send a networked event to everyone else and tell them to call RequestSerialization. This way, we still receive a OnDeserialization with the updated data.

But that doesn't seem that optimal. Is this more of a feature request or even bug?

cold laurel
#

Then OnDeserialization() should run for everyone else right after they receive the data.

cold laurel
obtuse echo
cold laurel
#

If the object is disabled for the Owner while calling RequestSerialization(), then OnDeserialization() will not be called for everyone else before the object is enabled again for the owner.

obtuse echo
#

I'll test it out later.

cold laurel
obtuse echo
cold laurel
#

That isn't shouldn't be necessary to do.

obtuse echo
#

It was for my case. Although I just can use the checkbox for the pool and it should fix all my issues. Just saw that and feel kinda dumb for never using it.

sour trout
#

So I've set up my networking so when the local player hits a note it sends a CustomNetworkEvent so the flame on the networked side will trigger. Is this a bad idea due to the number of networked events? It's purely a visual thing, I could just make the fire happen for every note locally and not sync it but I think it would be cool

#

^ for the strikeline emission and drum emission/size I'm using continuously synced variables instead. I'm not sure what is better: continuously syncing like I'm doing or even just send network event every time a drum is struck? I went with continuous for the drums because I assumed sending lots of CustomNetworkEvent is bad compared to continuous syncing?

#

The more I think it might actually be better using CustomNetworkEvents for drum hits instead of syncing as it's only one event instead of lots overtime

sour trout
#

Yeah sorry I think I've answered my own question, did some testing with VRC Quick Launcher and using CustomNetworkEvents is better than continuously syncing and it just looks nicer because it's not interpolating size/emissions

cold laurel
sour trout
cold laurel
sour trout
#

I'm just kinda worried about the impact if I scale this up to like 8 players all with synced highways

onyx path
#

does anyone know what to change to make this a public or world toggle, and not local?

halcyon zinc
#

hook the interact to a sendcustomevent note

#

and then get a custon note, name it whatev and hook it to the SetActive

cinder spade
halcyon zinc
#

right

hardy dune
#

I've got some size changing systems synced between all players: when a player interacts with a cube, all the players in the world start getting bigger, and it's reset when it's interacted with again. The problem is that the networking part works when doing build and test, but doesn't seem to work with other actual players if I publish the world to vrc. What could be the issue?

frozen igloo
hardy dune
frozen igloo
#

yes

hardy dune
# frozen igloo yes
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class syncedscalingall : UdonSharpBehaviour
{
    private VRCPlayerApi player;
    
    public GameObject thisObject;

    private float baseHeight; //currently unused
    private float currentHeight;

    public float multiplier;

    [UdonSynced] private bool active = false;

    void Start()
    {
        player = Networking.LocalPlayer;
    }

    private void Update()
    {
        if (!active) return;

        currentHeight = player.GetAvatarEyeHeightAsMeters();

        float updateMultiplier = 1 - ((1 - multiplier) * Time.deltaTime);
        player.SetAvatarEyeHeightByMeters(currentHeight * updateMultiplier);
    }
    
    public void Interact()
    {
        Networking.SetOwner(player, thisObject);
        active = !active;
        RequestSerialization();
        
        if (active)
        {
            baseHeight = player.GetAvatarEyeHeightAsMeters();
            currentHeight = baseHeight;
        }
        else
        {
            player.SetAvatarEyeHeightByMultiplier(1);
        }
        
        //SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.All, "SwitchScaling");
    }

    public void SwitchScaling()
    {
        if (active)
        {
            baseHeight = player.GetAvatarEyeHeightAsMeters();
            currentHeight = baseHeight;
        }
        else
        {
            player.SetAvatarEyeHeightByMultiplier(1);
        }
    }

    public override void OnDeserialization()
    {
        if (active)
        {
            baseHeight = player.GetAvatarEyeHeightAsMeters();
            currentHeight = baseHeight;
        }
        else
        {
            player.SetAvatarEyeHeightByMultiplier(1);
        }
    }
}
#

I also get a problem where if I use this system to shrink, the shrinking stops way before the limit, probably because it rounds the multiplier float to 0 very quickly. what would be a way to obtain a smooth scaling effect bypassing this problem?

frozen igloo
hardy dune
#

there's a lot of weird behaviours, like the script working if they interact with another object that also changes their scale

#

I can't explain why it's happening

frozen igloo
#

add some debug logs or print to a canvas text to figure out what's happening

hardy dune
frozen igloo
#

use textmeshprougui

#

or just use normal unity "Text'

hardy dune
#

how to access the text etc

frozen igloo
#

yes, make a variable called textmeshprougui

hardy dune
frozen igloo
#

I don't think TMP_Text works or something

hardy dune
#

are there some examples with TMP and udon?

frozen igloo
#

what method are you trying to use on what class?

hardy dune
frozen igloo
#

use .text =

hardy dune
#

in udonsharp, can I reference in script A a variable from another script B on another object without having a variable in script A that includes script B?

#

so, if I wanted a script with some 'global' variables that need to be used across all my scripts, I'd need to reference this script in all my other scripts?

stone badger
sweet wolf
#

Add the Udon Behavior variable, and specify it as Instans in the sendcast event.

lost tapir
#

hiii! so im trying to make this global instead of local

it is an event interaction that plays an animation when a button is pressed, what components should i add? ty!

frozen igloo
# lost tapir hiii! so im trying to make this global instead of local it is an event interact...

Add a synced bool
Set the udonbehaviour component to manual sync

On Interact:
Add Networking.SetOwner to the local player
Set the synced bool to the opposite of itself, replacing the animator setbool. Also mark "send change"
RequestSerialization

Then hold alt and drag the bool into the graph to make an onvariablechanged node. When the bool changes, you use that to set the animator bool to match the synced bool

wicked forge
#

hi, so im new to udon and use this solution I saw on a video for syncing an object's state.
What im trying to do is have an object go invisible for everyone when it's held and vice versa, and when used a particle system container empty toggles (child of the main held object)

It works mostly, the states are fixed now. The problem is when I drop it the object seems to appear visible at the world origin, and same for when enabling the particles. The object is placed at the world origin so presumably it's syncing everything correctly except the location of the object in your hand

#

and synchronization is set to manual under udon behaviour

cold laurel
wicked forge
#

the visibility object is an empty under the main parent object, which contains all the meshes for the visible part of the object

wicked forge
cold laurel
#

Yeah, you have nothing syncing the position of your object right now

#

Here's what you could do.

#

Make a separate udon behavior that is on the pickup. And the only thing this behavior does is listen for the OnPickup and OnDrop events.
Then you just forward those events to your actual script (which you have moved to a child gameobject)