Having Issues Building Items At Runtime

Tanman555

New member
I've really glad the UMA integration has been released along side UCC 2.1.1. I've been attempting to create my own custom spawner that would allow me to build any character model that has bones and a ragdoll setup. I've noticed the UMA integration has an ItemPickup Script, which the character then adds a list of items to their inventory. But their isn't any script in the integration that allows ItemBuilding for these items.

So I've attempted to use the ItemBuilder class to build my items. They appear on the character (all at once, even when I pickup afterwards), but there's a load of errors I encountered coming from both the Items and ChildAnimatorMonitor Scripts.


Code:
NullReferenceException: Object reference not set to an instance of an object

On Item.cs
C#:
m_Character = m_CharacterLocomotion.gameObject;
On ChildAnimatorMonitor.cs
C#:
m_Character = m_CharacterLocomotion.gameObject;

The ItemAction.cs and ItemPerspectiveProperties.cs scripts also have the same error. When I quit the game, I get several EventHandler errors.

Code:
EventHandler.GetActionList error: target object cannot be null.
UnityEngine.Debug:LogError(Object)
Opsive.UltimateCharacterController.Events.EventHandler:GetActionList(Object, String) (at Assets/Opsive/UltimateCharacterController/Scripts/Events/EventHandler.cs:152)
Opsive.UltimateCharacterController.Events.EventHandler:UnregisterEvent(Object, String, Action`1) (at Assets/Opsive/UltimateCharacterController/Scripts/Events/EventHandler.cs:613)
Opsive.UltimateCharacterController.Items.Item:OnDestroy() (at Assets/Opsive/UltimateCharacterController/Scripts/Items/Item.cs:1157)

I've tried to fix some of the errors.
C#:
            //m_CharacterLocomotion = gameObject.GetCachedParentComponent<UltimateCharacterLocomotion>();
            m_CharacterLocomotion = m_GameObject.transform.root.gameObject.GetComponent<UltimateCharacterLocomotion>();

This did not work. Although some of the errors did go away, I received the same error on the same scripts. Here's the method I'm using to build my character's items.
C#:
        protected override IEnumerator ItemBuilder_BuildItem()
        {
            yield return new WaitForSeconds(0f);

            if (AllySpecificComponentsToSetUp.bBuildCharacterCompletely)
            {
                if (SerializedAddableItem == null) Debug.LogError("No SerializedAddableItem on character");

                InventoryBase inventoryBase;
                Animator _animatorOnCharacter;
                if (SerializedAddableItem != null && AddableItemsList != null && AddableItemsList.Count > 0 &&
                    (inventoryBase = spawnedGameObject.GetComponent<InventoryBase>()) != null &&
                    (_animatorOnCharacter = spawnedGameObject.GetComponent<Animator>()) != null)
                {
                    foreach (var _addableItem in AddableItemsList)
                    {
                        //Build Items
                        Transform _handAssignmentTransform = _addableItem.HandAssignment == ERTSItemBuilderHandAssignment.Left ?
                            _animatorOnCharacter.GetBoneTransform(HumanBodyBones.LeftHand) :
                            _animatorOnCharacter.GetBoneTransform(HumanBodyBones.RightHand);
                        ItemSlot _handAssignmentItemSlot = _handAssignmentTransform.GetComponentInChildren<ItemSlot>();
                        int _handAssignmentSlotID = _handAssignmentItemSlot.ID;
                        GameObject _builtItem = ItemBuilder.BuildItem(_addableItem.ItemName, _addableItem.ItemType, _addableItem.AnimatorItemID, spawnedGameObject,
                            _handAssignmentSlotID, /*AddToDefaultLoadout*/true, /*AddFPPerspective*/false, /*FPObject*/null,/*FPObjectAnim*/null,
                            /*FPVisibleItem*/null, /*FPItemSlot*/null, /*FPVisibleItemAnim*/null,/*AddTPPerspective*/true,
                            /*TPObject*/_addableItem.Base, /*TPItemSlot*/_handAssignmentItemSlot, _animatorOnCharacter.runtimeAnimatorController, /*ShadowCastMat*/null,
                            _addableItem.Type == ERTSItemBuilderItemType.Melee ? ItemBuilder.ActionType.MeleeWeapon : ItemBuilder.ActionType.ShootableWeapon, _addableItem.ItemType);

                        //PickUp Items
                        if (_addableItem.MyItemPickup != null)
                        {
                            _addableItem.MyItemPickup.DoItemPickup(spawnedGameObject, inventoryBase, _handAssignmentSlotID, true, true);
                        }

                        Vector3 _position = Vector3.zero;
                        Vector3 _rotation = Vector3.zero;
                        //Set Specific Position and Rotation Only If ItemType Has
                        //Been Assigned in the Inspector
                        if (AddableItemHasSpecificPosition(_addableItem.ItemType, out _position, out _rotation))
                        {
                            _builtItem.transform.localPosition = _position;
                            _builtItem.transform.localEulerAngles = _rotation;
                        }
                        //else
                        //{
                        //    _builtItem.transform.localPosition = _addableItem.LocalPosition;
                        //    _builtItem.transform.localEulerAngles = _addableItem.LocalRotation;
                        //}
                    }
                }
            }
        }
 
Looks like some other people had similar issues to mine.
https://opsive.com/forum/index.php?threads/runtime-pickup.894/
https://www.opsive.com/forum/index.php?threads/problem-with-runtime-pickup.703/
The issue doesn't seem like it has anything to do with ItemBuilding at runtime. I don't know why there's an issue with the Item finding the UltimateCharacterLocomotion script on my player. I can confirm that this script does exist on the built character. Very weird.

All of my base prefabs are literally just the ItemPickups with all of the scripts and colliders removed. They appear completely normal in the inspector (although they do spawn all at once).

Still looking for a solution.
 
m_CharacterLocomotion is assigned within Awake which gets executed immediately after the Item component is added. The item isn't positioned under the character until later so that's why you are getting the error. This looks like I'll need to expand support so items can be created at runtime.
 
Great suggestion! I've already fixed some of the errors just by setting the parent earlier in a few methods on the ItemBuilder. In particular, the parent needs to be set earlier inside of the AddThirdPersonObject() and BuildItem() methods. Seems like I fixed 9 errors so far, 11 more to go.
 
Top