Mikameel
Mikameel7d ago

Avatar finger transform owned None

I added realtime transforms to the fingers of each avatar prefab, when the avatar spawns, it doest automatically set the transforms to owned locally. Eventho the realtime view of the avatar is set to local. I also have some decprecated Views in the Realtime View. from previous transforms that I removed.
8 Replies
kapa.ai
kapa.ai7d ago
Hi @Mikameel. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- It seems like you're encountering an issue with ownership of RealtimeTransforms for avatar fingers in NormalVR. Let's address this based on the information provided in the knowledge sources: 1. Ownership hierarchy: The ownership of child RealtimeViews and RealtimeComponents is inherited from the parent RealtimeView. As mentioned in the Server Authority + Ownership + Lifetime Flags documentation: "Models can have other models as children, and the ownership settings of a parent are enforced on all children. If a model is owned by one client, all other clients are blocked from making changes to the model or any of its child models." 2. RealtimeTransform ownership: RealtimeTransform components require explicit ownership to be set. As stated in the RealtimeTransform documentation: "In order to move an object with a RealtimeTransform component, your client needs to be the owner of the RealtimeTransform component" To resolve your issue: 1. Ensure that the root RealtimeView of your avatar is indeed owned locally. 2. For each finger's RealtimeTransform, you need to explicitly request ownership. You can do this by calling RequestOwnership() on each RealtimeTransform component for the fingers. Here's an example of how you might do this:
RealtimeTransform[] fingerTransforms = GetComponentsInChildren<RealtimeTransform>();
foreach (RealtimeTransform fingerTransform in fingerTransforms)
{
fingerTransform.RequestOwnership();
}
RealtimeTransform[] fingerTransforms = GetComponentsInChildren<RealtimeTransform>();
foreach (RealtimeTransform fingerTransform in fingerTransforms)
{
fingerTransform.RequestOwnership();
}
Regarding the deprecated Views in the RealtimeView: It's a good practice to clean up these deprecated references to avoid potential issues. You should remove these references from the RealtimeView component in the Unity Inspector. If you're still experiencing issues after implementing these suggestions, you may need to review your avatar prefab hierarchy and ensure that all RealtimeViews and RealtimeTransforms are set up correctly. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai7d ago
<@365574199844274177> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Mikameel
MikameelOP7d ago
@kapa.ai I have controller input trackers on avatars. they should only work if the avatar is owned locally, Should I set the Ownership of the fingers in the same script. Is this a good practice? using System.Collections; using System.Collections.Generic; using Normal.Realtime; using UnityEngine; public class AvatarAttributes : MonoBehaviour { [SerializeField] private RealtimeAvatar _realtimeAvatar;
[SerializeField] private List<MonoBehaviour> _localBehaviours = new List<MonoBehaviour>();
public bool isLocalAvatar;
// Start is called before the first frame update void Start() { if (_realtimeAvatar) { CheckIfLocal(); } } private void CheckIfLocal() { isLocalAvatar = _realtimeAvatar.isOwnedLocallyInHierarchy; if (isLocalAvatar) { InitializeBehaviours(true); }else if (!isLocalAvatar) { InitializeBehaviours(false); } } private void InitializeBehaviours(bool isLocal) { //enable local stuff if local bool toggle = isLocal;
if (_localBehaviours.Count > 0) { foreach (MonoBehaviour behaviour in _localBehaviours) { behaviour.enabled = toggle; }
Debug.Log("Initialized joined avatar behaviours, local = " + toggle); } } }
kapa.ai
kapa.ai7d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the information provided in the knowledge sources and your question, I can provide some guidance on handling ownership for avatar fingers and controller input trackers in NormalVR. Your approach of enabling or disabling local behaviors based on whether the avatar is owned locally is a good practice. However, for the finger RealtimeTransforms, you should indeed set their ownership explicitly. Here's why and how you can do it: 1. Ownership Hierarchy: As mentioned in the Server Authority + Ownership + Lifetime Flags documentation, ownership is inherited from parent to child models. However, it's a good practice to explicitly set ownership for RealtimeTransforms you want to control. 2. RealtimeTransform Ownership: According to the RealtimeTransform documentation, you need to be the owner of a RealtimeTransform to move it. You can modify your AvatarAttributes script to include setting ownership for finger RealtimeTransforms. Here's an example of how you could do this:
using System.Collections;
using System.Collections.Generic;
using Normal.Realtime;
using UnityEngine;

public class AvatarAttributes : MonoBehaviour
{
[SerializeField] private RealtimeAvatar _realtimeAvatar;

[SerializeField] private List<MonoBehaviour> _localBehaviours = new List<MonoBehaviour>();

[SerializeField] private List<RealtimeTransform> _fingerTransforms = new List<RealtimeTransform>();

public bool isLocalAvatar;

void Start()
{
if (_realtimeAvatar)
{
CheckIfLocal();
}
}

private void CheckIfLocal()
{
isLocalAvatar = _realtimeAvatar.isOwnedLocallyInHierarchy;
if (isLocalAvatar)
{
InitializeBehaviours(true);
SetFingerOwnership();
}
else
{
InitializeBehaviours(false);
}
}

private void InitializeBehaviours(bool isLocal)
{
bool toggle = isLocal;

if (_localBehaviours.Count > 0)
{
foreach (MonoBehaviour behaviour in _localBehaviours)
{
behaviour.enabled = toggle;
}

Debug.Log("Initialized joined avatar behaviours, local = " + toggle);
}
}

private void SetFingerOwnership()
{
foreach (RealtimeTransform fingerTransform in _fingerTransforms)
{
fingerTransform.RequestOwnership();
}
Debug.Log("Requested ownership for finger transforms");
}
}
using System.Collections;
using System.Collections.Generic;
using Normal.Realtime;
using UnityEngine;

public class AvatarAttributes : MonoBehaviour
{
[SerializeField] private RealtimeAvatar _realtimeAvatar;

[SerializeField] private List<MonoBehaviour> _localBehaviours = new List<MonoBehaviour>();

[SerializeField] private List<RealtimeTransform> _fingerTransforms = new List<RealtimeTransform>();

public bool isLocalAvatar;

void Start()
{
if (_realtimeAvatar)
{
CheckIfLocal();
}
}

private void CheckIfLocal()
{
isLocalAvatar = _realtimeAvatar.isOwnedLocallyInHierarchy;
if (isLocalAvatar)
{
InitializeBehaviours(true);
SetFingerOwnership();
}
else
{
InitializeBehaviours(false);
}
}

private void InitializeBehaviours(bool isLocal)
{
bool toggle = isLocal;

if (_localBehaviours.Count > 0)
{
foreach (MonoBehaviour behaviour in _localBehaviours)
{
behaviour.enabled = toggle;
}

Debug.Log("Initialized joined avatar behaviours, local = " + toggle);
}
}

private void SetFingerOwnership()
{
foreach (RealtimeTransform fingerTransform in _fingerTransforms)
{
fingerTransform.RequestOwnership();
}
Debug.Log("Requested ownership for finger transforms");
}
}
In this modified script: 1. We've added a new list _fingerTransforms to hold references to the RealtimeTransform components of the fingers. 2. We've added a new method SetFingerOwnership() that requests ownership for each finger transform. 3. We call SetFingerOwnership() in the CheckIfLocal() method when the avatar is determined to be local. This approach ensures that: 1. Local behaviors (like controller input trackers) are only enabled for the local avatar. 2. The finger RealtimeTransforms are explicitly owned by the local client, allowing them to be moved. Remember to assign the finger RealtimeTransforms in the Unity Inspector to the _fingerTransforms list. This practice aligns with the Normcore documentation and should provide a good balance between proper ownership management and efficient code organization. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai7d ago
<@365574199844274177> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Mikameel
MikameelOP7d ago
ok weird that it isnt set to local automatically as they are childs from the Avatar Realtime view.
Mechabit
Mechabit7d ago
you can add a feature request for it
maxweisel
maxweisel6d ago
RealtimeAvatar only requests the head and hands views. RealtimeView has a method to request ownership of the root and all children. We have an auto request component in the works too

Did you find this page helpful?