Search Unity

Question Moving a runtime avatar (RPM) in my game

Discussion in 'Editor & General Support' started by lz7cjc, Aug 17, 2022.

  1. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    535
    Hi
    I need to load my ReadyPlayerMe avatars at runtime as they are over 50mb each when I preload.

    The code to do this is:
    Code (CSharp):
    1.   private void Start()
    2.         {
    3.             ApplicationData.Log();
    4.  
    5.             var avatarLoader = new AvatarLoader();
    6.             avatarLoader.OnCompleted += (_, args) => { avatar = args.Avatar; };
    7.              avatarLoader.LoadAvatar(avatarUrl);
    8.        
    9.         }
    I have been told I then need to load the avatar into a gameobject in order to manipulate its position as it always loads at 0, 0, 0
    "you need to save the loaded avatar in a gameobject variable. then set its position"

    Ideally I would like to move it to an empty gameobject that is in the correct position for my game. Please can I get some help on how to do this?

    thanks
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
    Sounds like a great question for the ReadyPlayerMe people.

    What does their startup documentation tell you about setting up your first avatar?
     
  3. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    535
    you would think that but they aren't very helpful! Think i am missing the magic word... this was their exact response:
    you need to save the loaded avatar in a gameobject variable. then set its position. I can't give you exact code, because I use playmaker visual scripting.
    There is no documentation that I can find; just a sample scene. This one is for multiple avatars, and they are moving the position but can't see how to hack that for my purpose
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. namespace ReadyPlayerMe
    6. {
    7.     public class RuntimeExampleMultiple : MonoBehaviour
    8.     {
    9.         [SerializeField]
    10.         private string[] avatarUrls =
    11.         {
    12.             "https://d1a370nemizbjq.cloudfront.net/9bcc6840-8b8b-420d-a9d8-bc9c275fce8f.glb",
    13.             "https://d1a370nemizbjq.cloudfront.net/6b0d5152-586e-4b9d-ac00-1a85ad2ef4e4.glb",
    14.             "https://d1a370nemizbjq.cloudfront.net/fabdf402-cd3a-438a-a34b-3e3ca4ab4314.glb",
    15.             "https://d1a370nemizbjq.cloudfront.net/81b6fadb-6c81-4632-ab0c-7eaf15835e40.glb",
    16.             "https://d1a370nemizbjq.cloudfront.net/567a05c0-6ac8-4c78-8cc4-e160a6fe81b2.glb",
    17.             "https://d1a370nemizbjq.cloudfront.net/b3962d36-5dec-4778-a483-185b9303b8d5.glb",
    18.             "https://d1a370nemizbjq.cloudfront.net/188ab5f4-c786-457c-a961-15fa5cd1f0d7.glb",
    19.             "https://d1a370nemizbjq.cloudfront.net/e5eff169-4d3e-4e80-a83d-98bd9949dec0.glb",
    20.             "https://d1a370nemizbjq.cloudfront.net/61c0a063-1c9a-4772-bd8c-eb6622ccc8e2.glb",
    21.             "https://d1a370nemizbjq.cloudfront.net/40e05c6c-3015-47ef-9145-fb593bc69bf1.glb"
    22.         };
    23.         private const int RADIUS = 2;
    24.         private List<GameObject> avatarList;
    25.  
    26.         private void Start()
    27.         {
    28.             ApplicationData.Log();
    29.  
    30.             avatarList = new List<GameObject>();
    31.             var urlSet = new HashSet<string>(avatarUrls);
    32.  
    33.             // LoadAtOnce(urlSet);
    34.             StartCoroutine(LoadOneByOne(urlSet));
    35.         }
    36.  
    37.         private void LoadAtOnce(HashSet<string> urlSet)
    38.         {
    39.             foreach (var url in urlSet)
    40.             {
    41.                 var loader = new AvatarLoader();
    42.                 loader.OnCompleted += (sender, args) =>
    43.                 {
    44.                     OnAvatarLoaded(args.Avatar);
    45.                 };
    46.                 loader.LoadAvatar(url);
    47.             }
    48.         }
    49.  
    50.         private IEnumerator LoadOneByOne(HashSet<string> urlSet)
    51.         {
    52.             var loading = false;
    53.  
    54.             foreach (var url in urlSet)
    55.             {
    56.                 loading = true;
    57.                 var loader = new AvatarLoader();
    58.                 loader.OnCompleted += (sender, args) =>
    59.                 {
    60.                     loading = false;
    61.                     OnAvatarLoaded(args.Avatar);
    62.                 };
    63.                 loader.LoadAvatar(url);
    64.  
    65.                 yield return new WaitUntil(() => !loading);
    66.             }
    67.         }
    68.  
    69.         private void OnAvatarLoaded(GameObject avatar)
    70.         {
    71.             if (avatarList != null)
    72.             {
    73.                 avatarList.Add(avatar);
    74.                 avatar.transform.position = Quaternion.Euler(90, 0, 0) * Random.insideUnitCircle * RADIUS;
    75.             }
    76.             else
    77.             {
    78.                 Destroy(avatar);
    79.             }
    80.         }
    81.  
    82.         private void OnDestroy()
    83.         {
    84.             StopAllCoroutines();
    85.             if (avatarList != null)
    86.             {
    87.                 foreach (GameObject avatar in avatarList) Destroy(avatar);
    88.                 avatarList.Clear();
    89.                 avatarList = null;
    90.             }
    91.         }
    92.     }
    93. }
    94.  
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
    Do you even know if the system works? You may wish to consider another system if the documentation support is that poor. Otherwise you're going to need to figure it out because it isn't part of Unity so nobody here knows about it.

    Line 41 is also suspect: if that AvatarLoader is derived in any way from a MonoBehaviour you can NEVER use the new keyword to make one. You must have an active GameObject and use .AddComponent<AvatarLoader>() from that GameObject. That's just basic "how Unity works" stuff though.
     
  5. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    535
    thanks - have gone back to them
     
  6. lz7cjc

    lz7cjc

    Joined:
    Sep 10, 2019
    Posts:
    535
    for anyone looking for a solution to this, this is how i have done it
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace ReadyPlayerMe
    4. {
    5.     public class RuntimeExample : MonoBehaviour
    6.     {
    7.         [SerializeField]
    8.         private string avatarUrl = "https://d1a370nemizbjq.cloudfront.net/9bcc6840-8b8b-420d-a9d8-bc9c275fce8f.glb";
    9.  
    10.         private GameObject avatar;
    11.         public GameObject avatarPosition;
    12.         public float xAngle, yAngle, zAngle;
    13.         private void Start()
    14.         {
    15.             ApplicationData.Log();
    16.  
    17.             var avatarLoader = new AvatarLoader();
    18.             avatarLoader.OnCompleted += (_, args) =>
    19.             {
    20.                 avatar = args.Avatar;
    21.                 // set position
    22.                 //     avatar.transform.position = new Vector3(564, 0, 344);
    23.          
    24.                 avatar.transform.position = avatarPosition.transform.position;
    25.                 avatar.transform.Rotate(0f, 180f, 0f);
    26.            
    27.  
    28.             };
    29.             avatarLoader.LoadAvatar(avatarUrl);
    30.        
    31.         }
    32.  
    33.         private void OnDestroy()
    34.         {
    35.             if (avatar != null) Destroy(avatar);
    36.         }
    37.     }
    38. }
    39.