RandomItemDropper with UCC

Ando5000

Member
Hello,

I have a question about RandomItemDropper script. Ive attempted to replicate the same functionality from your Enemy in the UIC demo scene, but in the UCC integration demo scene. For now I am using a crate with a UCC health script on death event to look @ RandomItemDropper to activate the Drop() method. This part works fine and ive been able to get some things to drop if i plug in some of the pickup prefabs that are already in the scene. But I cant seem to get the pickup prefab to drop properly like ive seen in the UIC scene. In the UIC scene it seems to drop a generic bag that gets passed the droppable items values thats available in the enemy inventory? In my scene i get the following error when i try to use a similar prefab. (copied it and created a new version with my database)

Could not find prefab attribute: PickupPrefab.
UnityEngine.Debug:LogError(Object)
Opsive.UltimateInventorySystem.DropsAndPickups.ItemPickupVisualListener:SetVisualInternal(Item) (at Assets/Opsive/UltimateInventorySystem/Scripts/DropsAndPickups/ItemPickupVisualListener.cs:83)
Opsive.UltimateInventorySystem.DropsAndPickups.ItemPickupVisualListener:UpdateState() (at Assets/Opsive/UltimateInventorySystem/Scripts/DropsAndPickups/ItemPickupVisualListener.cs:49)
Opsive.UltimateInventorySystem.DropsAndPickups.ItemPickup:UpdateState(ItemObject) (at Assets/Opsive/UltimateInventorySystem/Scripts/DropsAndPickups/ItemPickup.cs:75)
Opsive.UltimateInventorySystem.DropsAndPickups.ItemPickup:Start() (at Assets/Opsive/UltimateInventorySystem/Scripts/DropsAndPickups/ItemPickup.cs:55)

Ive set up the other scripts as ive seen used in the UIC demo scene and made sure it was using my database. Unfortunately I keep getting an error when it tries to drop the prefab and i cant seem to figure it out.

Attached is a screenshot of my inspector setup for both my Crate gameObject that has the inventory and itemdropper script as well as the ItemPickup Prefab. Thanks for the help! Couple hours of flustration now, figured its time to ask.
 

Attachments

  • UCC- inventory test.PNG
    UCC- inventory test.PNG
    40 KB · Views: 4
  • ItemPickup.JPG
    ItemPickup.JPG
    71.7 KB · Views: 4
Last edited:
Hi Ando5000,

The error you are getting is about the Item Pickup Visual Listener component that is looking for an attribute on your items. It says that the PickupPrefab attribute is missing.

1595247773175.png

Essentially this allows me to customize the how the dropped item will look like.
So for example my materials can look a certain way, my swords could use the weapon models, etc...

If that's a functionality you are not interested in, you can remove the Item Pickup Visual Listener component that is next to your item pickup component. Then it should just work.

I hope that helps
 
Thanks for the reply. I think the integration demo scene covered a lot , except droppable items. I already had prefabs setting as you suggested and was still getting the error. I changed the base drop prefab that was used for health pickup to one of the pickup generic bags and i get the following error. Kinda just running circles here. Im using everything from the UCC Integration scene with nothing newly added. Ive studied the UIC demo scene over and over to see how enemy are dropping things and it looks straight forward. This seems to be an integration conflict that I cant seem to figure out.

Using UCC Is it possible to create the generic bag pickup thats passed the inventory information like you are using in UIC Enemy drops?


I have a health script attached to a crate. When the crate takes damage or dies an event triggers the drop script.


NullReferenceException: Object reference not set to an instance of an object
Opsive.UltimateInventorySystem.DropsAndPickups.ItemDropper.DropItemAmount (Opsive.UltimateInventorySystem.Core.DataStructures.ItemAmount itemAmount) (at Assets/Opsive/UltimateInventorySystem/Scripts/DropsAndPickups/ItemDropper.cs:62)
Opsive.UltimateInventorySystem.DropsAndPickups.RandomItemDropper.Drop () (at Assets/Opsive/UltimateInventorySystem/Scripts/DropsAndPickups/RandomItemDropper.cs:50)
UnityEngine.Events.InvokableCall.Invoke () (at <d1422b3fc93746018c92eda852993b93>:0)
UnityEngine.Events.UnityEvent`4[T0,T1,T2,T3].Invoke (T0 arg0, T1 arg1, T2 arg2, T3 arg3) (at <d1422b3fc93746018c92eda852993b93>:0)
Opsive.UltimateCharacterController.Traits.Health.OnDamage (System.Single amount, UnityEngine.Vector3 position, UnityEngine.Vector3 direction, System.Single forceMagnitude, System.Int32 frames, System.Single radius, UnityEngine.GameObject attacker, System.Object attackerObject, UnityEngine.Collider hitCollider) (at Assets/Opsive/UltimateCharacterController/Scripts/Traits/Health.cs:365)
Opsive.UltimateCharacterController.Traits.Health.Damage (System.Single amount, UnityEngine.Vector3 position, UnityEngine.Vector3 direction, System.Single forceMagnitude, System.Int32 frames, System.Single radius, UnityEngine.GameObject attacker, System.Object attackerObject, UnityEngine.Collider hitCollider) (at Assets/Opsive/UltimateCharacterController/Scripts/Traits/Health.cs:274)
Opsive.UltimateCharacterController.Items.Actions.ShootableWeapon.HitscanFire (System.Single strength) (at Assets/Opsive/UltimateCharacterController/Scripts/Items/Actions/ShootableWeapon.cs:954)
Opsive.Shared.Game.SchedulerBase.AddEventInternal[T] (System.Single delay, Opsive.Shared.Game.ScheduledEventBase+InvokeLocation invokeLocation, System.Action`1[T] action, T value) (at <345a537a18334b5cae14bbe9fdbc3494>:0)
Opsive.Shared.Game.SchedulerBase.Schedule[T] (System.Single delay, System.Action`1[T] action, T value) (at <345a537a18334b5cae14bbe9fdbc3494>:0)
Opsive.UltimateCharacterController.Items.Actions.ShootableWeapon.Fire (System.Single strength) (at Assets/Opsive/UltimateCharacterController/Scripts/Items/Actions/ShootableWeapon.cs:742)
Opsive.UltimateCharacterController.Items.Actions.ShootableWeapon.UseItem () (at Assets/Opsive/UltimateCharacterController/Scripts/Items/Actions/ShootableWeapon.cs:660)
Opsive.UltimateCharacterController.Character.Abilities.Items.Use.LateUpdate () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/Abilities/Items/Use.cs:632)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.LateUpdateActiveAbilities (Opsive.UltimateCharacterController.Character.Abilities.Ability[] abilities, System.Int32& abilityCount) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:1025)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.LateUpdateUltimateLocomotion () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:1011)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.UpdatePositionAndRotation () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:826)
Opsive.UltimateCharacterController.Character.CharacterLocomotion.UpdatePositionAndRotation (System.Boolean fromAnimatorMove) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/CharacterLocomotion.cs:517)
Opsive.UltimateCharacterController.Character.CharacterLocomotion.OnAnimatorMove () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/CharacterLocomotion.cs:1470)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.OnAnimatorMove () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:1753)
 
Im sure its something that can be easily added to the demo integration. We really need a working example.

I can get nolan to drop a rifle bullet and create the generic bag prefab pickup. That works great. Why I cannot get the crate to do the same thing?
 
The error you have above means you do not have an Item Pickup component on your item pickup prefab. But the screen shot you sent above shows you do have one. Are you sure you specify the correct prefab in the Random Item Dropper.

One bug I see is that UCC might not be able to pickup Item Pickups, it might only pickup inventory pickups but the RandomItemDropper only works with the Item Pickup component not Inventory Item Pickup. So I'll fix it asap.

I'm afraid that fix won't be available on the update coming out today. But I'll make sure to fix it for the next update with an example in the UCC demo.
I'll do something similar to you with a breakable crate that drop items.

If you need a fix asap I can send you the code tomorrow once I find the solution. If not the next update will probably be early next week.
 
I tried a few. I can get UCC pickups to spawn but there are errors on UIC side. I can also get the inventoryprefab to spawn , but with errors on UCC side.
 
I tried to use pretty much every prefab i seen in the integration folder just to see if i could get something to work.

If i open inventory during run time i can drop from inventory a clone of inventoryPrefab. It shows up as a blue bag no mater what item. That is great. This is what i would like to happen when i break my crate. Unfortunately using that prefab didnt work either.

I may be some of the settings, trying to get both UCC and UIC to communicate.

Can you tell me where the inventory in UCC integration handles dropping items from player inventory? Maybe i can learn more how the two communicate this way.

I wont bug you anymore today, thanks for the help in narrowing this down. Its def a key feature for any game and i think this part needs to be covered more in the integration for future users.
 
If you could send me the code fix that would be great! I have waited a long time for this and have been digging in very hard lately. If i find any more bugs or issues Ill be sure to report.
 
Can you tell me where the inventory in UCC integration handles dropping items from player inventory? Maybe i can learn more how the two communicate this way.

That's on the UltimateInventorySystemBridge component the OnItemActionDrop function. But that's way more complex than what you need.

Yes i agree with you that dropping items outside of the character items is essential. Tomorrow I'll find a solution to your problem and send you the code here with instrcutions on how to implement it. Then hopefully some time next week that fix, with an example in the integration demo, will be released in version 1.02

I'll keep you posted
 
@Ando5000

Looking at the item dropper and the pickup components I realized it was a bit limited. So I started refactoring quite a bit and ended up making improvements in a lot of scripts. I'd highly recommend waiting for version 1.02 to come out with these improvements.

If you really can't wait the easiest solution would be to change your ItemPickupVisualListener with this. And setting the new Deafualt Visual Prefab field.

C#:
/// <summary>
    /// The Item pickup visual listener will swap out the ItemPickup mesh gameObject by one specified on the item.
    /// </summary>
    [RequireComponent(typeof(Interactable))]
    [RequireComponent(typeof(ItemPickup))]
    public class ItemPickupVisualListener : MonoBehaviour
    {
        [Tooltip("The attribute name for the items visual prefab.")]
        [SerializeField] private string m_PrefabAttributeName;
        [Tooltip("The parent that will hold the item object once spawned.")]
        [SerializeField] protected Transform m_ItemObjectParent;
        [Tooltip("Default visual prefab.")]
        [SerializeField] protected GameObject m_DefaultVisualPrefab;

        protected ItemPickup m_ItemPickup;

        /// <summary>
        /// Initialize in awake.
        /// </summary>
        protected void Awake()
        {
            if (string.IsNullOrEmpty(m_PrefabAttributeName)) { m_PrefabAttributeName = "PickupPrefab"; }

            m_ItemPickup = GetComponent<ItemPickup>();
            m_ItemPickup.OnStateChange += UpdateState;
        }

        /// <summary>
        /// The item pickup item object has changed.
        /// </summary>
        protected void UpdateState()
        {
            if (m_ItemPickup.ItemObject == null || !m_ItemPickup.Interactable.IsInteractable) {
                RemoveVisualInternal();
                return;
            }

            SetVisualInternal(m_ItemPickup.ItemObject.Item);
        }

        /// <summary>
        /// Remove the game object that holds the item object visuals
        /// </summary>
        protected virtual void RemoveVisualInternal()
        {
            if (m_ItemObjectParent.childCount == 0) { return; }

            var child = m_ItemObjectParent.GetChild(m_ItemObjectParent.childCount - 1);
            if (child != null) {
                if (ObjectPool.IsPooledObject(child.gameObject)) {
                    ObjectPool.Destroy(child.gameObject);
                } else {
                    Destroy(child.gameObject);
                }

            }
        }

        /// <summary>
        /// Set the item pickup visual from the item attribute.
        /// </summary>
        /// <param name="item">The item.</param>
        protected virtual void SetVisualInternal(Item item)
        {
            RemoveVisualInternal();

            if (item == null) { return; }

            if (item.ItemDefinition == null) { return; }

            if (!item.TryGetAttributeValue<GameObject>(m_PrefabAttributeName, out var prefab)) {
                prefab = m_DefaultVisualPrefab;
            }

            if (prefab == null) {
                Debug.LogError($"The Prefab attribute value is null, please assign a default value or " +
                               $"in the attribute, make sure the item {item} has a non-null value " +
                               $"for attribute: {m_PrefabAttributeName}.");
                return;
            }

            var instance = ObjectPool.Instantiate(prefab, m_ItemObjectParent);
        }
    }

In the item dropper script you should also change the part where I call the itemObject.SetItem(item) otherwise it won't give you the correct amount of item.

C#:
if (m_DropCopies) {
                var itemCopy = InventorySystemManager.Factory.CreateItem(itemInfo.Item);
                itemObject.SetItem((ItemInfo)(itemInfo.Amount, itemCopy));
            } else {
                itemObject.SetItem(itemInfo);
            }
It may be a bit different because I made a lot of changes, I believe instead of itemInfo it'll be itemAmount for you.

Make sure you set an ItemPickup prefab (not an Inventory pickup prefab) in the random item dropper and then on the Interactable component of the pickup make sure the Character is part of the interactable layers.

In version 1.02, which should release next week, the integration will have the crates that drop item, inventory and currency pickups with (Random)Item/Currency droppers.
 
Thank you for this. I knew coming in it was still a work in progress, happy to see improvements and help with feedback. Im happy to wait for the next update and dig in. I usually read all the scripts and figure out how things are done a bit at a time. It would not do any good to continue that atm.
 
Last edited:
Yes, the update is coming later today. I'm testing version 1.02 right now and the integration that comes with it will contain the item drops in the demo scene. There are also other improvements to the integration demo scene.
 
Thanks for your hard work, we all appreciate it. Having an extendable inventory system that speaks well with UCC has been huge.
 
Top