khoi
khoi2w ago

Avatar Physics Interactions

I'm building a VR game where you can push/hit someone and make them move (similar to Orion Drift ball where you can push someone and make them fly backwards). What is ideal architecture for this? Thinking about using an RPC to send a rigidbody.AddForce event to your client when I intersect your avatar on my side. Considered having your local avatar have networked physics on them but not sure that makes sense from a multiplayer PVP perspective (eg the person hitting should be the source of truth). So proposal is: I push your avatar on my client, trigger collider event happens, then it sends an RPC to your client which does the physics on your side. Your avatar maps to your rig, which just got pushed on your client, so everyone sees you move.
18 Replies
kapa.ai
kapa.ai2w ago
Hi @khoi. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- I'll help you understand the best approach for avatar physics interactions in NormalVR. Your proposal to use RPCs for physics interactions isn't the recommended approach in Normcore. The documentation specifically warns against using RPC messages:
"Before we dive into this recipe, I'd like to warn you against using RPC messages... we believe this is a bad pattern. It puts the burden on you, the developer, to ensure that all state that is changed in response to an RPC message remains in sync across all clients." Recipe: RPC Events
Instead, Normcore has built-in solutions for networked physics that would be more appropriate for your use case. Recommended Architecture Normcore's RealtimeTransform component is designed specifically for networked physics interactions. Here's how you could structure your avatar physics: 1. Use RealtimeTransform with Rigidbody: Add a RealtimeTransform component to your avatar with a Rigidbody component. This will automatically handle physics synchronization. 2. Ownership Management: Normcore uses an ownership model to determine which client is the source of truth for an object. For physics interactions:
"Normcore solves this by simulating physics locally when you interact with an object. For the local client, changes appear instant. If you toss a ball to another player, they're watching your simulation of the object while it's in flight. However, as soon as they interact with it, Normcore switches to their client's simulation so it appears to have zero-latency on their client as well." Why Normcore
3. Automatic Collision Ownership: When physical objects collide, Normcore can automatically handle ownership transfer:
"When a rigidbody collides with another one, Normcore automatically claims ownership of the colliding rigidbody so the collision renders seamlessly on all clients." Why Normcore
4. Player Avatar Ownership: For player avatars, you typically want to maintain ownership:
"We want to ensure that each player prefab can only be modified by the player that owns it. Rather than setting ownership of every component on the player, we can set ownership of the root RealtimeView, and the server will block all other clients from making modifications to any RealtimeView or RealtimeComponent model." Ownership and Lifetime Flags
For player avatars specifically, you'll want to set "Maintain Ownership While Sleeping" on the RealtimeTransform:
"In this case, we want to retain ownership of the Player RealtimeTransform at all times. In order to do that, we'll want to set it to Maintain Ownership While Sleeping." Creating a Player Controller
Important Considerations 1. Rigidbody Hierarchy: Be careful with parent-child relationships:
"Rigidbodies cannot have parent game objects unless the parent never moves." RealtimeTransform + Physics
2. World Space Synchronization: For Rigidbodies, Normcore synchronizes in world space:
"Rather than synchronizing the localPosition and localRotation properties of the transform, it synchronizes the position and rotation properties of the Rigidbody, which are in world space instead of local space." RealtimeTransform + Physics
By leveraging Normcore's built-in physics synchronization rather than RPCs, you'll get more reliable results with less code and fewer potential desync issues. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@412870643533479936> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Mechabit
Mechabit2w ago
just so you know if you use Realtime Transform with this kind of message based send force there will be at least 1 second delay before the other play looks like they are moving due to the interpolation
khoi
khoiOP2w ago
i see!
khoi
khoiOP2w ago
how would you do it otherwise? also we are having a bug with the RPC where we use model.FireEvent(xxx) and then the EventDidFire() is logging like 400 times? based on this recipe: https://docs.normcore.io/guides/recipes/rpc-events
khoi
khoiOP2w ago
@kapa.ai is there a bug with RealtimeCallback?
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the knowledge sources provided, there's no specific information about any bugs with RealtimeCallback in NormalVR. The documentation mentions RealtimeCallback as a way to get an event that fires once all updates have been applied to a model, but doesn't indicate any known bugs with this feature. From the Room > Common Questions section:
"When model updates are applied, they're applied one at a time, and a change event fires for that value. However, it's possible the other values from that packet hadn't yet been applied. In order to get an event that fires once all updates have been applied to a model, use RealtimeCallback."
However, the documentation doesn't provide further details about any specific issues or bugs with RealtimeCallback functionality. If you're experiencing a specific problem with RealtimeCallback, I'd recommend reaching out to the Normcore community or support team for more detailed assistance, as the knowledge sources don't contain enough information about potential bugs with this feature. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@412870643533479936> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Mechabit
Mechabit2w ago
are you on the latest version? if you need RPC like behaviour you can just increment an int model and register for change events
khoi
khoiOP2w ago
i was in the easy sync alpha, now i dont know how to upgrade to latest normcore 2.15 😅
khoi
khoiOP2w ago
there is no upgrade button in my UPM
No description
Mechabit
Mechabit2w ago
as for pushing another player there's no real good solution, you'll just have to work around the latency / interpolation or you use deterministic physics or client prediction
khoi
khoiOP2w ago
yeah we are using the RPC recipe in the docs which says to increment a trigger so i think that is what you are talking about
Mechabit
Mechabit2w ago
try it without the realtime callback section and just use a basic model with change events
Mechabit
Mechabit2w ago
https://docs.normcore.io/realtime/synchronizing-custom-data#realtime-components but instead of color make it an int and instead of changing the material fire off a unity event
Synchronizing Custom Data | Normcore Documenation
In this guide, I’m going to walk you through how to synchronize custom data in your Unity application using custom realtime components.
khoi
khoiOP2w ago
How would I send the arguments across though? eg if I wanted to send pushStrength and pushVelocity? i could sync those to the model too but then it wouldnt be guaranteed if all the data had come through yet or the order
Mechabit
Mechabit2w ago
you can add those things to the model but this method is only good for one off events if you want lots of messages to fire at the same time you need to store them in a list also everything in the model is sent at the same time they won't arrive separately (and even if they are they are reconstructed in the background so it looks like it was) RealtimeSet is good for sending lots of messages properties will get deserialised in a random order though so to make sure you have everything ready you can wait till end of frame to read the contents

Did you find this page helpful?