#udon-networking
1 messages · Page 36 of 1
yes that piece of code will hit the "return" 99 out of 100 times, and thus stopping further execution of the function
but what i dont get is if im alone in my world, i have 60 fps, once someone joins, i have 30 fps, but everyone that joins can still get 60 fps, just not me
and that makes me think that it has something to do with networking since i couldnt explain it if it isnt
Sure
when i try this, udon sharp gives me an error of " System.ArgumentExeption: Operator '%' cannot be applied on operands of type 'long' and 'int'
anyone know whats going on?
i cant seem to get it to work
what i think would work in theory, but i dont know how to do, is to set it to manual sync, and then to let everyone run the code, and only give them the current position and current target every 20 seconds or something like that. however, i have no idea how to pull that off
I know its possible to rotate the player upside down and allow them to walk on a new plane, but I have no clue how to recreate that in udon. Does anyone have any references for the nodes I could use?
anyone have an idea? im loosing my mind
T h a n k y o u
maybe on start for owner of that object run DelayedNetworkEvent of 20sec,
and also onownership changed for the another user who is now owner, also running delayednetworkevent
and inside that event you do changing vector3-position-value and manual sync, then you can call new networkevent for All, which will update position of object to that synced vector3-position-value, to not do pos updating inside Update()
and that Delayed event at the end will run Delayed event of himself, to make it loop
im a dum dum and a c# noob, how do i do that?
Something like this, is what I'd do.
i will try that as soon as i get home. thx for the help
No idea if it's better fps wise though. The previous solution should've worked just fine, it wasn't doing anything crazy.
Especially if it's only eating the fps while there is another player.
The previous solution worked fine if the script was applied to only one object. It had an fps impact of like 2 or 3 if another player was in. However I have it on 3 objects now and it makes it laggy. I don't know if it's because of hardware or my super shitty internet connection.
With this solution I won't need an vrcobjectsync anymore right?
Correct.
i am super confused. the performance is even worse with this, but only on the room owners instance
i can test build it with 4 instances. the owner has 15 fps, while all other have 60. how
i feel so dumb right now. the script works and is even better than the old one. the stuff that made lag for the room master wasnt the script. the new script actually improves the fps
the reason it performed soo poorly was because this udon behaviour was set to constant sync
How do I get integer variables to sync? When I click the check to make It synced, it doesn’t seem to actually sync
Nevermind! I'm silly! It was only not working before for other reasons! It's all good now!
I'm currently working on an object pool and I'm trying to have gameobjects spawn and be renamed to the playerID of anyone new who joins, how could I sync gameobject names after someone joins?
not the answer but you can use this https://github.com/CyanLaser/CyanPlayerObjectPool
Does "Arrays having entries change no longer cause an OnVariableChanged event" in the patch notes for the open beta mean arrays wont sync anymore when entries are updated? Or is it a fix for them not correctly calling OnVariableChanged when entries are updated?
they will sync fine but won't trigger OnVariableChanged, you must rely on OnDeserialization
they won't trigger if you just change an entry, they will if you change the array size
Thanks!
Sorry if it's a stupid question, what conditions trigger OnDeserialization?
It seems to be related to join only?
when your variables have been updated (when bytes have been deserialised into variables), other words: when syncing occurs
it's any time you receive a synced packet. that can happen because you joined the world or because the owner of a manual synced object did requestserialization, or it happens automatically 5 times a second for continuous
Right, going to have to look at how that effects my code, thanks! ❤️
Hey, I've got 2 a world which has a button that toggles a boolean value, however whenever I toggle it on the value keeps jumping between true and false.
This is the toggle procedure:
This is where it's called from:
And this is the result that it shown when playing in game with 2 players.
It shows as true right before serializing and then it returns back to false
Oh and the value is printed every frame
@rigid temple We dont really have enough context to really tell whats going wrong there. For example the synchronization of all the variables is pretty important.
In any case, you generally dont want to handle it like this.
VRChat has a P2P networking architecture, however that can be very difficult to master.
Its much easier to think in terms of a normal Client-Master architecture.
So a simpler approach would be to let the Master of the instance sync the state, and when anyone that isnt the master wants to change that state, they only tell them to change it.
Thanks so much for the reply, that clears a lot up
So should I only have the master serialize variables and have the clients call procedures on the master which would change variables?
Thanks for the advice though I've made my script work in the way you stated
but my god the error I had should've been so obvious
Hindsight is most certainly always 20/20.
true haha
Not sure what im doin but my audio wont play when I press the button. The other stuff works and ive tried different ways of doin this. Can anyone tell me where I went wrong?
You can't have two events with the same name. You just need to join them:
either way, you can't have two with the same name. The next step would be to see if it's the event that's the problem (unlikely), by skipping it altogether and seeing if the code runs for the local player. If it does, then the event isn't the problem, and perhaps you haven't told it the audioSource and animator variables in the inspector
It was the nodes I had. How would you go about doing this?
In the inspector and on the udon behaviour component, you will see two slots (one for each variable) that will be empty. drag and drop the object that contains the animator and audio source onto their respective slots
you will also need to hit the dropdown menu, and make the variables public
i have already done that and it still wasnt working.
is there an alternative to the AudioSource Play node that I could use?
Is your audio source enabled and with an audio already on it? (playOnAwake disabled too) If it is a simple sound effect you could use PlayOneShot instead
So I've setup some synced variables. Within Unity how would I launch another instance of VRChat after launching the first test one to make sure the changes are persistent? Whenever I try to launch another build it resets both VRChat windows?
E.g player one sets some text to "Hello World", when player two joins later they should see "Hello World". How would I go about testing this?
I also noticed OnDeserialization isn't called by the first player to join a world. And RequestSerialization doesn't include the invoker?
Correct. Request serialization is like saying "send out all the variables I have to others so they have the latest state"
And on deserilization is when that is received.
Now of course, you dont need to send that data to yourself, you already have that data and are just sharing it with others.
There's a checkbox in build and test, can't remember thr exact text it's like reload client or something like that? I check that and then you can just but and test with one set for clients, then click last build to launch another client
I'd you don't have the last build button, there's a checkbox in the end settings tab of the sdk control panel to enable it
yeah, i was just wondering as if RequestSer called OnDeser would save one less line, thank you for the help btw 🙂
Yea you don't want requestSer inside your deserilization as that'll get you into an infinite loop
yeah lol, i ended up doing update(bool sync). then for local i do update(true) & in OnDes just update(false)
Hello to all! I had a question about Udon. What is a "networked object"? Is this an object that is not local and everyone else can see if it is moved or changed, etc.
I was not sure if I understood the concept correctly.
Trying to figure out why this whitelist system is not working. Someone suggested to match the display name with quotes on each side but I am lost on how this works with just the host and not the specified player name.
So top is functional but the whitelist name is not. They both go to the same function for the local player.
Why "Jade Furry" not just Jade Furry ?
Which isn't a networked object(this is default)'s change only affects local user. Ex) moving or teleporting. But even if it is not networked object, still you can make them networked by using udon like triggering sendcustom network event, or manual sync.
Another question: Let's say for example I have synced object in some room (position & rotation). If the player isn't in the room they don't really need to have a network update to know where the object is. Any way I can turn off syncing to cut down on network requests?
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
I'm trying to make a simple video player from scratch (yes I know there is a better one on github but I wanted to make one myself) but I'm having issues loading the url from the local input field so it loads for everybody
I'm using udon sharp
I tried studying a public video player but it had 1600+ lines of codes and still couldn't figure out how it synced the link between users
Might help, Inside LoadUrlNetwork() are you making sure the player calling this has ownership before changing currentLink?
Also Debug.log() might help to determine the URL you're putting in is coming through (open log in game with right shift + backtick + 3)
It doesn't look like you're doing any management of Networking ownership.
If you want a simple example to work from the one I made for the Udon Graph is about as simple as you can get while still having a Synced Video Player: https://docs.vrchat.com/docs/udon-video-sync-player
Oh I fixed the issues, forgot to post, turns out I was right about the logic but udon glitched hard and deleted my custom events.
and I was pulling at straws to figure out what was wrong then just made a custom debugger to figure out what udon was even outputting.
Hi all, @violet stream asked a question in an Udonsharp channel but showed noodles. They need help with getting an Interact to toggle an object globally, this is their node setup
hi, are there any changes to the data rate of manually-synced objects?
where's the udon-sharp channel? OwO
Hello! I'm just poking around to see if anyone else has had any world-breaking changes with the latest update.
In the patch notes, I see that there is a line that reads:
Arrays having entries change no longer cause an OnVariableChanged event
..Isn't that going to cause issues with a lot of worlds?
I'm personally impacted by this change, but I'm curious to see if other people are also affected and if there are any cheeky quick work-arounds
Most people didnt use OnVariableChanged really. Its a blackbox with undocumented behaviour. Plus that callback was a relatively recent addition to the SDK.
So Im not so sure if it really broke a lot of worlds.
Please note that it never properly detected when an entry changed. It only triggered a change when you received synced data because that process always created a new array from scratch, and that never applied to the owner. That behavior was inconsistent between different clients and merely a side-effect of how synced arrays worked, so it was fixed.
The actual change made was that arrays do not get recreated from scratch anymore, instead if it's the same array it just fills it up. That also helps a bit with garbage collection, too, so it was worth doing regardless of the impacts on onvariablechanged
Hmm then that changelog might have poor wording as it makes it sound like that was the previous behaviour which was now changed.
I suppose a more detailed description would be:
"Arrays will no longer be reconstructed after being deserialized when an entry was changed and consequently stops the OnVariableChanged event from being fired thereafter"
Interesting. All of this information is new to me. I thought everything worked pretty good. I didn't know that this was a problematic system
Also, to clarify, I'm using UdonSharp if that makes any difference. I figured I'd ask here first though as it seems like a general Udon change
yeah, this is a general udon change
Its not problematic. Its simply just that "change" is contextual.
the previous behavior was problematic because the other clients would detect a change when the owner would not
Ohhh I'm beginning to see what's happening here.
Hrmmm.. I'll have to investigate what's going on in my worlds a little more.
I appreciate the explanation!
Arrays are containers for other things. You can change the contents, or you can change the container.
Both is a change, but it depends on what you care about
onvariablechanged doesn't include any context like the index, so I wouldn't expect it to ever do a deep equality check. And besides, changing the contents of an array doesn't really have the same hooks in it as changing a variable itself, so it might be hard to detect in the first place.
If there was ever a way to detect a change to the contents of the array, it would have to be a completely different event. So this new behavior of onvariablechanged should be less undefined and more reliable
Yeah. My intuition wants to think the following:
- Array is defined and set to sync manually
- A single element of that array changes value and RequestSerialization is called.
- All clients fire the fieldchangecallback for that sync'd array on Deserialization as at least one element has changed.
I had my code configured to operate under those rules
Im curious, what happens when the serializer does change the array reference, but fills it with the same values? Will it get a new reference on the deserializer side as well? or will it "wrongly" not do that?
Because if its the latter, then you just reversed the problem I suppose, which would probably be less common of an issue, but might still be akward
I'm still shocked that not a lot of people leveraged the fieldchangecallback, I thought that was a great way to make sync'd arrays event-driven 😅
Well as you can tell, reference types are weird like this. But most reference types cant be synced anyway.
Except for arrays...
hi
fieldchangecallback is a nice convenience, like you can use it to update the state of some other script or an animator when a value changes. But when you start getting into multiple synced values and arrays and everything, better off just using ondeserialization
Yeah - my specific use-case is fixing up my multiplayer Bejeweled world which is basically array-hell due to the nature of the game, so this might take some doing
I'll figure it out though. Again, appreciate the explanation. I learned a lot!
I have a world that utilizes manual syncing heavily, and none of the synced variables are arrays (https://vrchat.com/home/launch?worldId=wrld_54123524-3329-4091-bdb1-1c43e86451d9). This update broke it. The behavior I’ve observed is that serialization is called properly, but values are not received and can only update when ownership changes.
Argh wrong link hold on
Funny enough, I'm looking more thoroughly through my old Bejeweled project and have actually come to realize that this project preceded FieldChangeCallback, so yeah, there might actually be something wrong with syncing in general
Anecdotal: I have a friend of mine that runs a large karaoke world with a pretty fancy queue system. That world has also fallen victim to this update. I feel like something's up
if it's not syncing a VRCURL then that's known and a fix will roll out in the first patch https://feedback.vrchat.com/bug-reports/p/1201-url-sync-appears-to-be-limited-to-a-certain-number-of-characters-on-a-singl
doesn't sound like the nesos are related to VRCURLs though, that could be a new one
I'm a dork and misread the patch notes. I conflated OnVariableChanged with FieldChangeCallback 😅
That being said, there still does seem to be something up with syncing. I'll keep poking around and see if I find anything more substantial than just conjecture
fieldchangecallback is the udonsharp implementation of onvariablechanged
you are right to treat them the same
The plot thickens
i spent so much time today finding out about the VRCURL 127 character limit bug and thought i was going crazy earlier. thanks for posting about it. it's nothing new for the video player to break but this one drove me mad because it only happens under certain conditions 
So! I must humbly admit that I suspect that this current update has exposed a couple issues with how I programmed my world a very long time ago. This was one of my first ever VRC projects, so some of the code is pretty questionable and I think this update has caused some array operations to not work correctly because they weren't written correctly to begin with. They just worked by happenstance until now 😅
Namely, I was performing comparisons/copys to array references rather than checking elements discretely. Why this worked in the past? Luck, I guess. Now everything has been re-written with the techniques I know now and we're back in action. In retrospect, this was a pretty dumb mistake on my part, but hey it happens!
Just thought I'd drop this info here on the off chance that I sent someone down the wrong path. I'd recommend keeping an eye out for patterns like
myArray1 = myArray2
and replacing it with
System.Array.Copy(myArray1, myArray2, SizeOfArray);
Also, beware of array comparisons like myArray1 == myArray2. Comparing references is different than comparing the contents of the arrays. I wrote a AreArraysEqual function for that.
What the hell is this? I just noticxed I was getting spammed with this in the console ```2022.05.27 08:48:41 Error - [Network Transport] Received serialization data for id 99, but we have no serializers for that object.
2022.05.27 08:48:41 Error - [Network Transport] Received serialization data for id 99, but we have no serializers for that object.
2022.05.27 08:48:41 Error - [Network Transport] Received serialization data for id 100, but we have no serializers for that object.
2022.05.27 08:48:41 Error - [Network Transport] Received serialization data for id 100, but we have no serializers for that object.
etc```
And also ```2022.05.27 08:53:52 Error - [Network Processing] Could not locate object with path :65/
2022.05.27 08:53:52 Error - [Network Processing] Could not locate object with path :65/
I've never seen these errors before
are you deleting any synced objects?
No...
The world was working fine until it suddenly started spamming that when the update happened
what world? Do you have any details about what this world is doing?
The neso world I just posted about. All the nesos were working fine until the latest update happened, then the nesos started not being able to sync variables and that error started appearing
THe world continuously (with manual syncing, which means every 3-6 seconds generally) syncs many small NPCs with more than 13 synced variables each (why I had to switch to manual syncing in the first place ;p)
does it do any instantiating?
No
Is it true that any interactivity that is not related to things that have to sync info/states/etc between players, can have this Udon Behavior syncing set to "none" ?
For example: local toggle active button, local UI interface browsing, UI sliders that have only a local effect and other things like that?
Yes
Is there a way to have a section of code execute for only the first person who joins the instance?
Laziest way is to just check if they the master or own the gameobject
Thank you, I'll give that a try.
Was given the challenge of making a MMD station that syncs as close as possible. But at this point I feel like im fighting network IK.
All tests are done On local build and test. Tested with 2 clients and then 3. The results are from the 2 client test.
I have 3 setups.
Setup 1 :
Uses server time (GetServerTimeInMilliseconds()) and then sets a start time for people to be moved to the stations.
Results: Client A see's client B with a slight delay. Client B see's client A with a slight delay. Both clients are doing the animation perfectly in sync on each of there clients but the other client from there perspective is offset.
Setup 2 :
Uses Unix time (System.DateTimeOffset.Now.ToUnixTimeSeconds()) and then sets a start time for people to be moved to the stations.
Results: Same as setup 1.
Setup 3 :
Use server time (GetServerTimeInMilliseconds() + the time it took for the receiving client to get the start time message) and then sets a start time for people to be moved to the stations.
Results:Client Also same as setup 1 but feel I need to do a online tests.
Setup 1 was also tested online but with slightly worse results than the local tests.
Theorized Solutions:
1: Away to access the player animator to set a bool true to play the animation. (assuming network ik Is not the battle)
2: Away temporary disable the network IK of the other clients local.
3: Away to play a animation on another client locally with out a station or/and them having to play the animation locally.
The reason I feel like network IK the last hurdle is to my understanding stations just replace the local player animator. Thus even if you get both clients to play the animation at the exact same time down to the millisecond, network IK causes a viable delay as the animation I see other clients playing is the delayed data from there network IK and not just a animation.
ALL input on this would be appreciated, anything from a crazy theory to a correction in my understanding of how something works.
Also would be nice if someone confirmed my understanding of how stations work and how they react to network IK.
If you use the action layer that should completely override network IK
But I'm not sure if stations have the ability to set that
Unsure what layer stations even replace.
Cant seem to find any documentation on this too. If anyone knows that would also be nice info.
So, my game is currently facing some severe networking delay especially with people on quest. One issue that popped up is that my game "favors the shooter", but I'd like to make it so that clients that kill assailants while their assailants are experiencing degraded network throughput will not die whenever their assailants' networking catches back up. Is there some way to "remove" a player on the local end?
I think I figured it out. I'm going to have the assailant send a custom network event and the assailed set a property on their object to a value. When the assailant receives OnDeserialization, they'll check their own health and then tell their target to die if they're not already dead
nvm that won't work
oh well
If anyone ever finds my wall of text and wonders did I ever solve it. I found my solution why try fight network ik when I can just use a shader to offset playback on the screen. Ended up just using multiple cameras that only render 1 player each then offsets there playback on screen based on there network ms or with a manual override if you need to offset someone more or less. While still taking advantage of server time to get it as close as possible to begin with.
Yes the dancers will still be out of sync but on the "screen" they will be in sync.
As always the solution is sync by not syncing.
Anyone know if this is safe? Like it won't crash the game or freeze other Udon behaviours
(from my very limited testing it hasn't crashed the game... yet)
Or if there's a better way to wait for the network to settle before proceeding because this is basically while(!Networking.IsNetworkSettled){}
Eh, that looks kinda bad. It might work, but I think it's safer to let everything else run and periodically check if the network settled instead. I personally never had to do that though. What kind of logic do you have to delay in your example?
Waiting to take ownership of an object to run logic that requires the local player to have ownership over it
Unless Networking.SetOwner() blocks and it... just works without forcing it to wait?
Because I tried it in U# without making it wait for the network to settle and it seemed to work fine
Yeah it appears to be unnecessary to wait for the network to settle when taking ownership of an object to modify stuff on it (or at least it just hasn't broken yet)
Yeah, I think after the objects does SetOwner, it assumes it's correct.
And withholds whatever data it wants to send until then.
would be really nice if you could just add arguments to custom events and use them like RPCs in any other engine, then you wouldn't even have to take ownership of the object to move data around (would only work with really basic serializable types like int, string etc. though)
SDK4 
sorry if this has been asked before, but is there any issues with syncing right now for people? a game i made that has been working perfectly for months is broken right now. basically anything requiring manual sync is breaking but network events are working.
I could probably identify the problem but would need some kind of details on what you're doing. Are you doing instantiation? Are you using OnVariableChanged/Fieldchangecallbacks? What are you trying to sync? Any other details you think would be relevant?
its been a really long time since ive even looked at the code. i want to say this particular one uses onvariablechanged to inform everyone of state changes, its pretty old. uses manual sync, when it syncs it compares the previously stored temp variable to the synced one, then updates the temp, while doing whatever processing for the users.
everything is based around synced arrays of ints i want to say...i dont have access to the code on my computer right now unfortunately and i really havent touched it since i got it consistently working.
i dont mind having to rewrite stuff if vrc updated how udon works, it was written when i kind of had to do hacky stuff still to get certain things working. i know theres been a ton of udon updates and whatnot, i guess i just wanna see if things have changed enough where old code might break.
itd be hard for me to describe things enough without getting the code up again haha, i think it's been...basically since manual sync became a thing that i wrote this. i guess i'm more just looking to see if this is something that is temporary as in things are weird tonight in particular, or things are weird this update in particular, or nothing has changed for other people and i'll have to revisit the code to modernize it a bit with udon
right, that's what I thought. There's been a change to how onvariablechanged with synced arrays works. Basically the old way, it would constantly trigger whenever you received any ondeserialization because it would have to recreate the array from scratch every time. Now, it only needs to recreate the array if the length has changed. So onvariablechanged doesn't trigger every time.
If you were using it because you expected it to trigger when any of the contents changed that's not how it worked previously and not how it ever will work. You should just use OnDeserialization and do your own checks
hm...you know i think i saw the event onvariablechanged and assumed i used that because i knew i used an event of some sort. but now that you mention ondeserialization i'm sure i used that and have a function that compares arrays. you're having to jog my memory a bit haha, sorry. but i'm sure it's something on my end just being way way way out of date since if there was a common issue it'd be well known by now. i think i'll take some time this week and either debug it or just rewrite the whole thing(bleh).
well this change to onvariablechanged on arrays has affected a handful of people now, you're not the only one. But it's one of those things that I've always told people to avoid in the past because it was undefined behavior and didn't provide any advantage over ondeserialization anyway
that's because it's not connected to any event
every frame unity freezes until all scripts finished processing, calling an infinite while loop will crash your script after freezing for 10 seconds
use the update event instead
that gets called every frame
then check if the network is settled
mm
yeah i was wondering if the udon vm is multithreaded or something
either way it doesn't matter
Approximately what's the limit to the number of physics objects (say they're all constantly moving) that can be synced between players at a tolerable frame rate without much desyncing issues?
For example, like 100 (or more? less?) rolling rigidbody spheres
Wonder if anyone can help me? I have a gun system in place but when people use the second grip (Like a forward grip), it isn't synced on the other players end. Meaning on your end, you are aiming at them, but visually on the other person end, they are not. It doesn't effect damage or anything, just makes the visuals look wonky.
This doesn't sound like vrc object sync behaviour where the position and rotation is sent over the network, maybe tell us how you are syncing this first.
Reading your description leads me to believe that each gun is tied to a player, and the state of holding the gun is synced but not the position and rotation.
what is the current limit on bytes that can be synced?
me and my friend fixed said issue in a graph, but thanks for responding
I have absolutely no mods installed, but when I play the "The Devouring" map with a friend (only when the friend comes in) the ghost freaks out and ends up glitching all over the place to the point where things are unplayable. Anyone have any idea why? I deleted all cache and tried to make VRChat as vanilla as possible and it still happens (my first thought it was because of mods, but I just ruled that out, by uninstalling everything)
The ghost doesn't have any issue when my friend plays teh map with his friend, but if anyone joins me while I play, the ghost glitching makes it basically become unplayable.
Because it only happens while a friend joins, I assume it's a network issue, so I figure this channel is the best place to post about it. Let me know if I'm mistaken and there's a better place to post this question.
The button I prepared does not work, where is the problem?
what does not work?
aren't you ambled to press the button?#
Question!?
When a user sends out a customNetworkEvent does that user trigger the event locally? Or do they receive their own event in a loopback fashion? Eg. the send the event out to the server and it gets back to them?
I want to build a udon script that compares timestamps of events to see who was the one triggered it in the first place.
The reason i'm doing that is because i'm trying to make a honeypot for modded clients that can trigger udon events.
That way if they're the first to trigger it, and the is no other way in world to do so i'll know who the script kiddie is.
network events are executed immediately when sent, no waiting for ping or anything
So theoretically, if I was to have the users record a server timestamp at the time of the event along with their id and sync that and append it to an array
then the one who triggered it should always show the lowest time?
yes
Nice!
getting a timestamp from every player is not trivial though. You can't just have everyone add to a synced array because they would interrupt eachother. You would have to either set up a timer so that everyone takes their turn, or you set it up so every player has their own separate object that they can send it through independently
Or just iterate over a list of players and make them the owner of a single game object one at a time as it runs through and collects the data.
Once they're the owner of that object send the data and transfer ownership back to the master.
Rinse and repeat until you've got all the time stamps.
Or maybe it could be easier than that! Just set a player tag with their timestamp value.
player tags are not synced
Ah, Right.
anyone have any resources on how to read the shift tilde 6 menu?
like I'm almost hitting the max out apparently but all I've got is 5 object syncs
with an udonbehaviour with one udonsynced bool
when i sawed an object from pool. how could I know if all player is ready to see the object
hitting max what?
max kb/s sent out (18.000kb/s)
Remember to set the udon scripts that don't need syncing to none or manual.
For example, TP Doors
just did that actually, it helped some, but the "boss battle" which has max 5 molotovs and the enemy that walks around seems to hit that cap somehow
boss is set to manual, only syncs when someone teleports to the arena or joins late
molotovs have to be continuous as they're physics object
only synced bool is if its lit or not
so I'm kind of at a loss
I can screencap the debug screen I was talking about
so if I'm reading this right, the only things currently actively sending data out are the molotovs at the very bottom as per "BpsSince" column?
Oh god, I'm running into this bug face first now. It happens when the master leaves and a new one is chosen. There is a while loop in the ObjectPool source code that it appears to get stuck in.
so im trying to make a group of objects respawn and this is my graph, can anyone tell what went wrong or what needs to be plugged in for them to respawn
Your variables don't appear to match the inspector so you may need to compile/reload
like start over?
or what would compiling mean
click these buttons
alrighty did that and now im here
You would then need to have that udon behavior on an object in the scene and assign the obects in the newVariable_1 array
this is what it looks like on the object
when I try to assign my objects to the sync target I get the crossed out symbol
You would need to drag the VRCObjectSync components into that slot
perfect worked great, thank you graphing sage @quaint rain
Trying to sync a slider that has an animation, i tried two methods but i dont get it working. The animation doesnt even wanna work on the second one. x)
Anyone knows what to do?
I'd recommend displaying the animator value on both clients somehow. It will make it a lot easier to confirm which parts work and which don't if you can see what it is.
Second picture doesn't even set the animator value for example. It stays at zero.
Yeah i realized that right after.
So, it looks like players that aren't the local player have a much smaller hitbox/it's located at their feet. This causes issues with my killbox based setup for guns and knifes where you'd expect the player capsule to be the collider that will trigger the OnPlayerTriggerEnter. Is there any way around this issue/is it only an issue in the local testing clients?
I'd like to continue to use Triggers and events such as OnPlayerTriggerEnter versus the approach I seem forced to take which is rigidbodies on killboxes and having a trigger collider follow the player
I think that's only when you test locally. Have you tried opening two clients and testing if your system works properly in VRC?
I have not, but I suppose I can trial the system. Would be bad if it all doesn't work tho D:
I would appreciate it if someone can help me on this.
The float needs to be Udon Synced and you should use Manual sync and after the user lets off the adjustments, RequestSerialization()
Only the Network owner (by default, the Master) can adjust UdonSynced values. You need to Networking.SetOwner to the player trying to adjust the value in order for this to happen. There is no other way to do so as you cannot send values over the network via Event calls
Idk the Slider interface, if it offers calling a Function once it's been let up
looks like it's the same in non local tests. Just using normalized player colliders now
Is there a way to intercept instigators for network events
Are you looking for something like OnOwnershipRequest ?
I haven't really used it myself, but it sounds like it would do what you want since it returns a bool, which you have control over.
No. You're able to SendCustomNetworkEvent(nameof(function), All or Owner);
But on the receiving end, idk if you can tell who sent it
In the debug log, you are able to see who the instigator is though
for example: "Running [eventName] at the behest of [username]"
I wanna avoid abusing synced variables as there is overhead with forcing a queue system when things should be running in parallel
Oh, I completely misread your question. Afaik, there is no such thing for sending events. Only way to identify senders is ownership.
is there some documentation somewhere about syncing variables in udonsharp?
I see lots of stuff about Udon graph, but I only know udonsharp, which there seems to be a lot less information of
I have some variables that are storing random numbers, and some variables storing object locations. how can I keep these synced between all the players?
it all behaves exactly the same, it's just different syntax. Instead of checking a box, you add [UdonSynced] to it
something like this? is that all I have to do? the random number assigned to each variable will be the same for all players? (I think how it works is the instance owner runs the randomizer function, and then sends it to all the other players correct?)
sorry, Ive been trying to learn udonsharp pretty hard recently
that's part of it, yes. Once you're ready you need to make sure that you take ownership, set the variables, and then if it's manual sync call RequestSerialization
what do you mean take ownership ?
Synced variables work by having one person tell everybody else what the variables are. The person who has authority to do that is the owner. You can set owner at any time with Networking.SetOwner
Isnt the owner set to the instance master by default?
that is correct
and RequestSerialization is just saying "hey everything is set you can sync now" when on manual sync
yes
alright thanks phasedragon!
I've got an udon graph that is activated by a button, sends a custom network event to set an animator bool to true which plays an animation lowering a DJ booth down from the ceiling, to it's ending location. This all works fine for all in the instance, but late joiners see the booth still up in the ceiling, and I can't figure out how to get it to play the descending animation for them so it's down on the stage where it belongs. Can anyone help? I tried "onplayerjoin" but I guess that's wrong. So I set a synced variable "isDown" and did "onDeserialization" checking if it's true, then setting the animator bool but it doesn't work. Help would be greatly appreciated https://gyazo.com/9c59854f5142d05323562353d2cd53c1
I will even PAY someone to help me with the above.... will ANYONE please help? DM me... I'm sure this is super simple for someone other than me.
Hmmm tricky. At first glance, keep in mind that only the owner of an object can set a networked variable. Are you certain that OnDeserialization actually happens?
Consider adding some Debug Logs to help you find what might be wrong.
If you're ever in a situation where Udon is not doing something that you want it to do, a good way to diagnose it is to add Debug Log nodes with unique text. Put them right before you try to do something important, put them right after you try to do something important, and just put them anywhere that might be important in general. Then when you run your UdonBehaviour, you can observe the log to see how far it's getting and whether or not it is doing what you expect.
At first glance your graph looks like it might work, though it could be simlified (to make it easier to find the issue). I might try that later when I get home...
Here's what I'd change:
- Change
Allon the network event toMaster, because only the master will be able to set the synced variable. If this causes other players to stop seeing your animation, then you've narrowed down your problem: It that means your synced variable wasn't getting set! AndOnDeserializationnever happens, breaking your late joiner sync.
Less relevant: - If you'd like the stage animation to be a toggle, you negate the variable before setting it in your custom event.
- Instead of
OnDeserializationyou could useOnVariableChanged. Though it's probably not the cause of your issues. - Instead of having three
SetBoolnodes, you could probably just have one. Either in a custom event, or by simply connecting your flow ports to it.
... Wish I had access to the SDK right now, because I could send you a graph to try out 😄
im not using udon to create my worlds, YET i keep getting errors from Udon thats preventing me from creating my worlds, ive had to delete specific files now three times to get my world working then reload my entire world maker, why is udon being a pain in the ass?
-- Looking for input on a networking issue --
I'm using an object pool that spawns a game object and then assigns a new synced string value to it.
When the game object's string gets updated, it searches for a game object in the level locally, with a matching name and extracts data from it so that it can display custom information on all clients
-- The Error --
If the room master spawns the object, it updates perfectly across all clients
If a non-master spawns the object, it shows up perfectly, then disappears as the master then overwrites the values to null, then reappears with null values for seemingly no reason, and errors ensue..
I am transferring ownership of the object pools and the gameobject that it spawns, before updating any synced variables.
If anyone has a moment to talk about this , I would be truly grateful
--EDIT--
Nevermind, [Right Shift + ` + 6] showed me the issue clear as day. When transferring ownership, it seems that it doesn't transfer the ownership of child game objects as well, and will only transfer the specific one. In my case, that wasn't changing ownership of the game object whose Udon script was giving me grief.. Posting this edit incase anyone else runs into a similar error in the future. Apologies for my negligence.
I have a GameObject with VRC Object Sync on it, which is moved by a Nav Mesh Agent.
Despite having Object Sync on it, it often appears to be in different locations for different clients.
I don't know what can be done to make it sync, since it already has Object Sync on it. I assume the Nav Mesh Agent is causing Object Sync to not work? I'm new to networking, so not sure how to diagnose exactly what is wrong here. If anyone has any ideas, I would greatly appreciate it.
Maybe the NavMeshAgent and the VRCObjectSync are conflicting with each other? You could try letting the Owner of that object use NavMeshAgent to set the position and then disable the agent for everyone else.
The VRCObjectSync will position the object for the other clients.
Hmm, ty, I'll give this a shot and report back
No, still appearing in different positions for different clients
I added this to the NavMeshAgent's gameobject's UdonBehavior's Update() method:
agent.enabled = Networking.IsOwner(Networking.LocalPlayer, gameObject);
Maybe having a NavMeshAgent on at all just disables VRCObjectSync's behaviour
But I have seen VRC worlds with NavMeshAgents that multiple people could see in the same position, so there must be some way of syncing their locations
That's odd. I'm fairly sure what you did should work. Are you instantiating the agent or something?
The agent exists at the start of the simulation, it's not spawned on the fly
Just in case: both of those components have to be on the same object.
Are you also sure that the code doesn't break?
Could you describe the actual problem more? Are the agents just on different positions for each client? Are you moving the agent somehow? Posting your full code might also be helpful.
I might need to test it out myself since I haven't used NavMesh in a while, but that won't happen today.
Yep, the VRCObjectSync and NavMeshAgent are on the same object.
Yes indeed, the code does not crash according to the log file.
Sure, for each client, the agent is just in a different position, I think it also targets different people. Sometimes I will notice its rigidbody hit a player where that player cannot see it. It moves differently, so on one client it may be stopped, and on another it's moving, or they may be moving in different directions, just everything is different it seems.
I'm currently testing implementing it this way: https://youtu.be/xVXXS7HX7Og (39:28), if this also fails I'll put the relevant code in here 👍
I implemented the system as shown in the video, what now occurs is, for the owner of the session, the agent moves smoothly and apparently correctly (and targetting is correct on the owner and other clients), but for other clients, the agent most of the time is stopped, then occasionally updates its position, and sometimes has a small stretch of moving smoothly.
Huh, I just spent like 10 mins selectively pasting relevant code, posted it here, bot immediately deleted it all and told me to not spam, lost it all 😆
I'll re-do it for you in a DM.
The way the agent moves is quite similar to this:
#world-development message
As for the code you send me, it definitely looks a bit sus. The biggest issue is that non-owners are setting the target for the owner. You need to make it so only the owner decides where the AI is going. So make it calculate the distance to the closest target and set the target for itself. Every non-owner just skips the update loop and disables the agent. The VRCObjectSync should take over the job of sending the position data.
That odd movement might either be because of what I wrote above with non-owners deciding the target and causing confusion. That, or because that's just how VRCObjectSync works. Sadly, we don't really have much control over it so there is not much you can do. I'd recommend using manual sync for stuff like instead. But that might make it a bit more complicated.
Thank you! Shall give this a shot and report back, might be tomorrow as it's getting late. This is the first networking code I've ever written so figured it's bound to be sus in some way 😆
Your suggestion appears to have worked!
For anyone with a similar issue, main changes were that I checked whether the local player was the owner and disabled the agent and return;d in the Update() method if not, and enabled it if so. That seemed to fix it. Also worth watching that video I linked, I now set the target player using their method.
Quick question, can instantiated objects be synced yet? Or do we still need to do workarounds with pre-generated object pools?
Still not possible.
Are those scripts of yours set to "None" for their sync method?
Do you see those 300 when you open the debug menu? There should be a list with the networked objects.
But otherwise, I don't think I had the problem you are describing yet. When I mark them as "None", they do not appear to transfer ownership.
Just remembered I asked something similar here in the link abovce
Are they actually causing massive problems when someone joins? When I asked, I just assumed it's some wrong debug message when it actually doesn't track ownership.
Oh wow, yeah that sucks. Maybe you could switch to instantiating some of your scripts?
Might make it so they won't be tracked at all for good.
Is it technically possible for 2 players to be the owner of a GameObject at the same time in their own instances? Dealing with a bug currently where my GameObject appears to be running as if it is owned by both players separately
Well, you could have two players disagree on who's the owner. For example, if both try to take over ownership simultaneously.
This should get resolved quickly though, so they wouldn't continue to think they're the owner. (Unless something has gone horribly wrong in your case..!)
If you would like to make certain that someone has received ownership, consider using OnOwnershipRequest
This event is triggered when someone has requested to take ownership. It includes the Player Objects for the Requester and the Requested Owner. To approve or deny the change, set a boolean value into a "Set Return Value" node. This logic runs locally on both the requester and the owner, so be aware that disagreements in logic between the two will cause a desync. This is most likely to be expressed by the ownership transfer being unexpectedly rejected by the owner.
But in your case, it seems like there's a simpler way to find out what's going on. Are you sure the object is synching properly, under normal circumstances?
With 2 clients, the object appears to behave as if it is being separately simulated for each player. I don't understand how, since the object has VRCObjectSync, it has a NavMeshAgent which is disabled if !Networking.IsOwner(Networking.LocalPlayer, gameObject), where agent.enabled = false; & agent.updateRotation = false;, and its position is updated using transform.position = agent.nextPosition;, with agent.updatePosition = false; (I think this is so that VRCObjectSync works.)
The object's Update() method, after checking if we are the owner and aren't the target player, if we are not, just sets agent.enabled = false; and return;s
If we are the owner, it has a chance to update the target player who the agent is targetting. On every run of Update(), it checks if (targetPlayer == Networking.LocalPlayer && !Networking.IsOwner(Networking.LocalPlayer, gameObject)), and if true, we get set as the owner of the object.
What I am confused at is how the object appears to be in completely different positions doing completely different things for each player, given that only the owner of the object should be doing any movement calculations at all, and each other player should just be receiving the transform via VRCObjectSync.
Have you checked if your ownership transfer are happening as expected? As in, do both clients agree on ownership?
Or does it bounce back and forth?
It's certainly interesting that you're working with nav agents. It sounds like you've used them before?
There's an OnOwnershipTransferred method you could use instead of Update. Also a good spot to add some Debug.Log
OnOwnershipTransferred is apparently Obsolete, though it doesn't state that on the docs
there are 2 ownership transferred methods
one with the vrcplayerapi input and one without
the one without is obsolete
the vrcplayerapi it provides is the previous owner
Would OnOwnershipTransferred run on all clients or just the new owner's?
Ah, okay, so how does one determine the new owner?
if(Networking.GetOwner(gameObejct).isLocal)
Oh yeah of course
Ownership appears to be behaving as expected, I added OnOwnershipTransferred(VRCPlayerApi p), on which Debug.Log("Ownership Transferred to " + p.playerId);
Here's an examples coming out of the Logs:
2022.06.26 14:20:42 Log - [Network Processing] Sending transfer of ownership of 135 to 2.
2022.06.26 14:20:42 Log - Ownership Transferred to 2
Ah, that would change things if so lol
Yes, it does
I've had issues with it before
Also, behaviour of the agent, on better observation, appears to be that it only moves at all for the owner, and for non-owners, is completely stationary. When ownership is transferred, it freezes for the previous owner, and the version for the new owner activates from wherever it was last frozen for that player. So basically it's like there are 2 versions of it, operating independently, and each one only moves if its player is the owner. As if the VRCObjectSync is doing nothing at all.
Yes, but only ever in single player. Networking them, at least for VRC, seems to be very difficult lol
Is it possible that your Update code continues to run for non-owners? That would prevent the object sync component from controlling the position, as it would be overwritten by the (disabled) nav agent update that you manually do.
Either using a unified timer using Manual Sync and Server time or an implied timer using System.DateTime.UTCNow
Basically one person tells everyone "the animation started at t=300" and everyone being like "it's t = 350 currently. Play the animation at time = 50 (=350 - 300)"
how would that look in udon?
People's clocks are almost never synced, so server time seems like it would be more reliable...
I've seen a prefab for syncing using your local clock, but nothing for server time though, is there one knocking about anywhere?
I don't think a server clock is possible with just udon. It might be possible to run a livestream that sends the time through certain colored pixels and then interpret the video player texture and pass it onto udon, but that's a pain to do probably
Yikes, yeah that would be crazy.
Pokeyi created an animation sync prefab you can use that has configurable types of sync. I use the UTC sync mode for the zipline in my arcade world. https://github.com/Pokeyi/VRC-Animation-Sync
Yeah, that was the UTC one I mentioned before. But given how out of sync people's clocks are, even by a second or two, it seems like it would not be that useful.
Depending on the animation, a second or two out of sync may not be a big deal. Like an animation of a UFO flying over and abducting a cow, a second or 2 out of sync means nothing, but if there is a gameplay element where the first person to save the cow wins... then yeah that can be a big difference.
Quick little question/thing I've been wondering about: Why does OnPostSerialization tell me 20 bytes serialized, even when I only have one synced uint (4 bytes)?
i.e what is the overhead?
Just assuming here but it would probably also have to send the name of the variable the data is going to, which script/ object that variable is on
You could probably fire up fiddler or a similar program and chech the packet, unless they're encrypted somehow
That sounds reasonable. strings have a base allocation cost of 8 bytes and for each char, it increases by so much. I forget how much
To make an event global (or at least have each user run it) do I just shove a Interaction -> Send Custom Network Event (blah) then have Blah feed into what I'd want to happen normally? (as opposed to Interaction going directly into what I want to happen)
That is a simple way to do that yeah. However be aware of over-syncing and that events are fire-and-forget, meaning that players who join after the event, will not get the event fired for them.
Yeah that's expected. This is just for temporary, fire and forget things so no big deal there. Thanks.
So, I'm trying to "globalise" an interaction and this feels like it should work, but the whole interaction only seems to happen for the user who initialises the interaction. Am I missing anything?
The whole thing works perfectly for the person that performs the interaction, but none of it fires for anyone else.
there are several reasons why it wouldn't work
-you need the currentquote variable to be synced
-you need to take ownership before setting a synced variable
-you should have this set to manual sync
-if it's set to manual sync, you need to do requestserialization when it's finished
-you shouldn't mix network events with synced variables because they're not guaranteed to arrive in the same order they were sent
-even if you did use a network event, it's not necessary to sendcustomevent after, that just makes it happen twice
The variable is set to sync, but I didn't have Manual Sync set on the script (by accident) so that was likely it.
still would need ownership transfer at the very least
So not sure if I did something else wrong last time I tested, but it didn't run for me without "sendcustomevent" last time I tried. I'll have to redo my testing in case I missed something else.
I'm not familiar with ownership transfer. So what and why? Because only the owner can change it?
yeah, just networking set owner localplayer
only the owner can send synced variables
Cool, I'll add that in and try with manual sync on, thanks. How would you recommend handling the networked events and synced variables though? Nothing immediately jumps out as a solution there.
ondeserialization or onvariablechanged
So detach the process entirely into two separate things. That makes sense.
I'm seeing ondeserialization but not onvariablechanged, is it elsewhere?
hold alt while dragging a variable into the graph
Ahh, those still keep catching me out. I spent AGES looking for how to set a variable the other day.
Better? (with manual sync)
you need to plug localplayer into setowner but yes that should work
also if two players click it at the same time that disableinteractive would not be sufficient to stop it from playing two lines at once
It seems to work without plugging local player into that node. Do you know what it is by default? (I assumed it defauted to local/current player)
uhhh don't leave it blank
I'm surprised it doesn't crash the script
it probably just doesn't transfer
But if it didn't transfer, it wouldn't be able to set the variable, right? All test clients are hearing the same quote, which implies the value change is succeeding.
if it didn't transfer only the master would be able to send it, so you need to have all clients try it
I did
even without transferring, they can change it and trigger a change, but others won't see it
right but what I'm saying is that since you only have audio effects it might be a little unclear, because just seeing you hear it at least once is not enough, you need to be sure others hear it too
and regardless, even if a blank player does do localplayer, I've never heard of that being a guaranteed thing. only gameobjects, udonbehaviours, and transforms
I'll set it to playerlocal, but yeah..
Any thoughts on handling the racecondition? (without going into crazy amounts of workaround code, as I may just leave it at that point)
just have a bool to keep track of if it's currently playing a clip
and if so, ignore the change
Is that possible with PlayOneShot or would I need to move to a more normal playback method? POS seems pretty limited.
Ah, actually it connects to a normal audioelement so maybe not that limited. I'll poke around.
nothing to do with playoneshot, just keep track of the bool in the udonbehaviour and do the logic yourself
I asked because I need to set the bool back when the audio finishes, which I wasn't sure was possible with POS.
You are also already technically storing whether its playing or not via DisableInteractive so you could just use "Get DisableInteractive" and branch from it
DisableInteractive is just a blind timer, I wanted to replace it with something smarter later.
yeah I'm just saying to change the bool back at the same time as the disableinteractive
but technically sure you can get disableinteractive too so sure just use that
Rather than that, couldn't I just do a "isPlaying?" call?
and the delayed event doesn't need to be a guess, you can plug in the audioclip length
So I can, cool. I'll do that then. Thanks.
@frozen igloo One last question, if I'm doing requestSerialization and have the variable marked as synced, do I want "Send Change" enabled when setting that synced value?
send change just makes it trigger onvariablechanged locally, doesn't have any impacton networking as it always triggers a change when received by network
Would that cause it to fire twice, once again when RequestSerialization is called or not?
there is no change for the owner when you do requestserialization
Ok, good to know, thank you.
Unrelated but kinda related question for anyone - I've found the random range to be... not very random. Does anyone have any smart alternatives?
Random.Range not random enough? What makes you think that?
If I give it a selection of 26 objects, it VERY frequently seems to select the same few.
Hey guys, I am trying to network some AI's which I have wandering around my NavMesh. I've got it 99.99% working with destinations, animation parameters, speeds and so on all being synced manually across clients. I keep their position uniform using the VRC Object Sync component and making sure the NavMeshAgent is only receiving instructions from the Master - for every non-master client the NavMeshAgent is disabled. The only problem I am still having is that for whatever reason the ObjectSync component isn't updating the rotation of the AI! The current behavior seems to be that the AI's rotation is updated once to sync with the master when the new client loads in, and then they retain that rotation value for the remainder of the user session rather than continuously updating it. I am very confused as to why VRCObjectSync would continually update the position so well, but not the rotation? Particularly as the NavMeshAgent is disabled for non master clients. Anyone have any idea what I am missing here?
Just as a bit of extra information, I did try to hash a "good enough" fix using Transform.LookAt so at least the AI would be vaguely facing where they needed to be going. However this completely broke the animator component for some reason.
Are you sure the RNG is at fault? Or maybe your implementation? :P
Literally just doing Range 0-26 so... I was hoping it would be random enough to not have to code something smart that just appears random
Well the Unity docs say that the numbers should all have an approximately equal probability...and Im pretty sure someone would have told them if it wasnt...
Difficult to say what the issue is from your description. At least I don't have anything that comes to mind. The VRCObjectSync should also handle the rotation, unless I remember wrong. I'm guessing there is something interfering with it? That's what you need to debug and find out. Isolate the parts, like testing only the navmeshagent without the animator and your model. Just make a cube or something else to indicate the direction it faces. If you did everything right, then that will rotate properly and you have to look into your animator/hierarchy setup. If not, then you can debug the code itself.
I'll give it a go. I just don't understand why the inclusion of an animator would break an object sync component! Thanks for the response!
Is the animator on the same object as the object sync component? The object sync just writes the rotation to the current transform, so if the animator is doing something similar, there can be conflicts.
That's why I suggest isolating your script and the agent for now, until you know it works.
Good idea, maybe the trick is going to be parenting the animated component under the rigidbody/navmesh component
Generally, object sync doesn't play well with navmesh AI. I'm not sure why, but it seems that AI likes to take control of things in a way that object sync isn't able to work with. For that reason as well as just generally making things look good, usually the recommended way is to manual sync the destination and only occasionally sync the actual position just in case it gets desynced far away or stuck in a corner you can teleport it to where it needs to be
Cool beans! I'll give that a go!
does anyone know how often can I request serialization before I get rate limited or something like that?
will once a second be fine or is that too often?
when you requestserialization it will wait for a proper time anyway. If you spam requestserialization every frame (90 times a second) it will only ever go as fast as 10 times per second anyway. The speed that it accepts your requests to send data depends entirely on how much outbound data you're sending in general. If you've got some script that sends a massive array of tens of thousands of bytes, then that can cause you to get clogged which will slow down everything else. But if it's only sending like a couple of primitive variables like floats and bools, then you can send it as fast as you want, it has next to no impact unless you have a hundred objects all doing this at the same time.
TL;DR once per second is totally fine, if anything that's being safe
aight ty, still fairly new to udon networking so don't know all the rules. I'm just syncing some animator parameters so I might get a bit more aggressive with my sync timings then.
How can I set the owner of an object to whoever is holding that object in udonsharp?
I think I use SetOwner(VRCPlayerApi player, GameObject obj), but how do I put the player holding the object in the player slot?
if I have a script that has an udonsynced int variable and a function where it randomizes that variable between say 1-10, how can I ensure that all the players in my world get the same number?
Because currently, I think everyone is getting different numbers. I have a synced variable that determines which spawnpoint an object will spawn at, and sometimes they are spawning in different locations.
Im trying to make it so that one player runs that randomizer function and shares that value with everyone else, and then everyone runs a custom event to spawn the objects at the respective numbered spawnpoint
but I think whats happening is that the randomizer function is being run by everyone not just only one person
is there a better way to do this?
Make the randomiser run only on the owner of the script, request serialisation then do any local updates likr putting the int in a texbox or whater in the deserialation
What code would I use to turn off one song while turning on a new one?
toggle whole gameobject
AudioSource.Stop();
AudioSource.Play();
It depends on how you are playing the song, if you got the audio clips then audiosource.stop(), audiosource.clip = newsong, audiosource.play. if you use a video player it's gonna be more complicated
Just make sure that everyone does that if you want to have it synced
Im just using an audio clip and I would like any other song playing to stop when I play another one
But I have no idea what certain code would do that, like what exact code would turn all other songs off while playing the one song you clicked
One audiosource can only play 1 clip at a time
Don't use playoneshot as that will make more audiosources
ok im ngl im very new to this and have absolutely no idea what you are talking about
The code is as described
Are you using u#?
Does it need to be networked?
Does it need to support late join sync?
now I dont know what I need
Well those questions all make the code different in a way
Tho the most complex solution does support less complex ones
ok, can I just send the code to show what I'm talking about?
I have that
Idk where to go from there
How about you'd do a:
Custom Event(Play) -> AudioSource.Stop() -> AudioSource.clip = somesong -> AudioSource.Play()
Interact -> SendCustomNetworkEvent (All, "Play")
the audiousource and audioclip (somesong) being public variables that you set in the inspector
this will not support late join sync
and then maybe have a button that just does a AudioSource.Stop()
Clicking the button will restart the song
ok wait, can I just make a button to just stop all other songs?
Like once I click it all songs just turn off
yea
just stop the one audiosource
there's only 1 audiosource
every script will reference the same audiosource
Maybe even unsetting the audioclip will work
then you could just use the same code
well what would be the code to just stop all music in general.
interact -> audioSource.Stop()
and that will do it?
depends on what you got this far
I have the same code for like 20 blocks that all play different music
so I don't need to make it to any specific code? It will just stop all audio sources?
I'm sure if you try to play an audiosource with no clip it will just not play
well yea I know that
it will stop 1 audiosource
you can't stop all audiosource's as that would include people's voice's
even if they all have the same code?
To stop all audiosources you're gonna have to iterate through all of them in an array and stop each one
So I would have to make a stop button for every one of them?
set both variables to public
and in the inspector set it so they all use the same audiosource
and for it to stop playing just set no clip
in the udonbehaviour
So how do I get the string one
I wasn't able to set it in the SendCustomNetworkEvent Node
anyway it would be string -> const string
it should just be the same name as the customevent and NOT start with an underscore
And what exactly does this do-
Which thing?
The whole code
It stops the audiousource if it was playing then sets the audioclip in the audiosource then play that new clip
and the sendcustomnetworkevent just makes it so everyone that is currently in the world does the same
So would it be like a playlist of the music, or just stops a song while another gets played? or neither?
Ok sweet. But what about the code I showed you? Do I just keep it there
Just adjust your code to the one I sent
I see, ok
so how i fix my synced variables
to stop a song playing you're gonna have to press a separate button tho..
I can adjust it to, if you press the same button again, it stops playing it
Lemme test this first just to make sure I didn't screw anything up
well I screwed something up
this would be the code to add the stoping on the second click
make sure to always set the audioclip in the inspector with this code, else it'll give you an exception at the AudioClip.Equals node
no just change your code until it matches the screenshot I sent
Ok so basically get rid of my original code?
Well I really appreciate you trying to help, but no matter what I do it's not working. So ima just leave it as is. Thank you again.
- I can't play the music at all
- I have no idea where the code is supposed to go even tho I tired it everywere
like I did everything you said/showed me and it's just not working
Is there a way to sync a gameObject with something like VRC Object Sync when the gameObject gets manipulated in some way with an Udon Sharp script?
Hiii im new to the udon network stuff, but is there a way i can sync animations with a simple onInteract()
VRC Object Sync can do that, Just make sure to set ownership with the SetOwner function to the person trying to manipulate it.
does anyone know where the VRChat servers are located? particularly the servers that hosts avatars and world?
They use AWS for that, with their own CDN. So technically globally.
Thanks!
Hi dear VR chat world Devs,
I'm working on a script ( Udon noodles) let's call it script "A". It is meant to be drag and droppable on a lot of objects, animating them. / Triggering behaviours. On another game object i write my global variables with script "B" and recall them in script A via update method every frame. The data contained is at max three vector3 data with a little downstream processing. Everything ment to be synced for everyone at all times.
My concern now is, that if I use the update method every frame. And the script is on many game objects, that the overall performance will suffer too much since the data only changes on fixed events occurring at highest speed every 30ms
Will this script break my world performance or is it ok to use update method. On a global sync script of that size?
Thank you so much for sharing your knowledge, and helping to have better performing worlds ❤️
definitely best to avoid update for something that's not changing
you can instead use onvariablechanged
hi maybe sobody know if i got like a fish that make only swim animation can i use like only a object sync to other ppl see the same fish the same position. also would that work on cinemamachine track cards how it callet so also a object sync would that work?
This would be meaning to broadcast the event "on changed" to an array of objects that hold the reviewing script. However (since I cannot dynamically add objects to an array or pool during runtime?) this would mean me manually filling a gigantic array Wich i want to avoid. Is there a way to broadcast an event to all objects in the scene?
You're gonna have to find all the objects one way or another. If they're all a child of one specific object then it's not a big deal to do getcomponentsinchildren on start at runtime.
Alternatively, you could reverse the responsibility - rather than the one script finding all the other scripts, you could have all the other scripts find the one script using gameobject.find. then register with it and add itself to an array. if it's near the top of the hierarchy it's not a big deal.
If you want to be really thorough and really safe though, you could make an editor script which searches the scene and populates the public variables
But no matter what you do, you certainly shouldn't be doing any of this in update
