Adding spawn points to instantiated RPM model

Hi, wondering if anyone knows in unity best way to create spawn points for a RPM instantiated model from the character creator. Trying to get items to spawn in hand.

In the avatar loading script, you can add a method that instantiates the spawn point.

One way to do it is: In the method you can use the Transform.Find to get the RightHand object and then you instantiate the spawn point under the found gameobject (Check Unity Instantiate). When instantiating you will be able to also define the initial position and rotation of the spawn point if needed as shown in the Unity doc.

1 Like

Thanks Gonzalo! had some time off work to stop having a headache figuring this out. Will let you know how it goes!

1 Like

@Gonzalo_RPM I’m having issues finding the handpoint in the instantiated armature, maybe I’m going about this in a way more difficult way than I should be.

using System;
using System.Security.Cryptography;
using ReadyPlayerMe.Core;
using UnityEngine;

namespace ReadyPlayerMe.Samples.QuickStart
{
    public class ThirdPersonLoader : MonoBehaviour


    {
        PlayerInteraction playerInteraction;

        private readonly Vector3 avatarPositionOffset = new Vector3(0, -0.08f, 0);
        
        [SerializeField][Tooltip("RPM avatar URL or shortcode to load")] 
        private string avatarUrl;
        private GameObject avatar;
        private AvatarObjectLoader avatarObjectLoader;
        [SerializeField][Tooltip("Animator to use on loaded avatar")] 
        private RuntimeAnimatorController animatorController;
        [SerializeField][Tooltip("If true it will try to load avatar from avatarUrl on start")] 
        private bool loadOnStart = true;
        [SerializeField][Tooltip("Preview avatar to display until avatar loads. Will be destroyed after new avatar is loaded")]
        private GameObject previewAvatar;

        public GameObject interactor;
        public GameObject spawnPoint;
        

        public event Action OnLoadComplete;
        public Transform handPoint;
        
        
        private void Start()
        {
            
            avatarObjectLoader = new AvatarObjectLoader();
            avatarObjectLoader.OnCompleted += OnLoadCompleted;
            avatarObjectLoader.OnFailed += OnLoadFailed;
            
            if (previewAvatar != null)
            {
                SetupAvatar(previewAvatar);
            }
            if (loadOnStart)
            {
                LoadAvatar(avatarUrl);
                Instantiate(interactor);

                handPoint.transform.SetParent(handPoint.transform);


            }
            playerInteraction = GetComponentInChildren<PlayerInteraction>();
        }

        void Update()
        {
            // //Runs the function that handles all movement
            // Move();

            // //Runs the function that handles all interaction
            Interact();

        }

        public void Interact()
        {
            //Tool interaction
            if (Input.GetButtonDown("Fire1"))
            {
                //Interact
                playerInteraction.Interact();
            }

            //Item interaction
            if (Input.GetButtonDown("Fire2"))
            {
                playerInteraction.ItemInteract();
            }

            //Keep items 
            if (Input.GetButtonDown("Fire3"))
            {
                playerInteraction.ItemKeep();
            }
        }

        private void OnLoadFailed(object sender, FailureEventArgs args)
        {
            OnLoadComplete?.Invoke();
        }

        private void OnLoadCompleted(object sender, CompletionEventArgs args)
        {
            if (previewAvatar != null)
            {
                Destroy(previewAvatar);
                previewAvatar = null;
            }
            SetupAvatar(args.Avatar);
            OnLoadComplete?.Invoke();
        }

        private void SetupAvatar(GameObject  targetAvatar)
        {
            if (avatar != null)
            {
                Destroy(avatar);
            }
            
            avatar = targetAvatar;
            // Re-parent and reset transforms
            avatar.transform.parent = transform;
            avatar.transform.localPosition = avatarPositionOffset;
            avatar.transform.localRotation = Quaternion.Euler(0, 0, 0);
            handPoint = avatar.transform.Find("HandPoint");

            var controller = GetComponent<ThirdPersonController>();
            if (controller != null)
            {
                controller.Setup(avatar, animatorController);
            }
        }

        public void LoadAvatar(string url)
        {
            //remove any leading or trailing spaces
            avatarUrl = url.Trim(' ');
            avatarObjectLoader.LoadAvatar(avatarUrl);
            
        }

    }
}




the spawn point its supposed to make isn’t connected to the armature as intended


I’ve added all the layers in the hierarchy and its still not finding it

Hello,

In the code, you are looking for the object with the “HandPoint” name. If I understand correctly, you want to find the RightHand object, right? Then you should use that name instead, and it needs to be written exactly the same as in the hierarchy, so in this example, “RightHand”.



Hi Amel,

Yes i have the right name, i printed the hierarchy to make sure its exactly the same. It still isn’t finding it however

Hello,
You need to remove the Neck from the path. The RightShoulder is under the Spine2 gameobject

Thanks Amel! that actually helped, do you have any idea how I now reference this transform from another script. Tried using a tag but it wont find it


        // Find the GameObject with the "Hand" tag
        GameObject handObject = GameObject.FindGameObjectWithTag("Hand");

        if (handObject != null)
        {
            // Get the transform of the hand object
            Transform rightHand = handObject.transform;

            // Instantiate the object at the right hand position
            Instantiate(objectToInstantiate, rightHand.position, rightHand.rotation, rightHand);