Community-driven PUN integration for UIS/UCC

@AlexM Hi! This script works in my project

C#:
public class PunInventoryItemPickup : InventoryItemPickup, ISpawnDataObject
{
    private object[] _spawnData;
    private object[] _instantiationData;

    private TrajectoryObject _trajectoryObject;

    protected override void Awake()
    {
        base.Awake();

        _trajectoryObject = gameObject.GetCachedComponent<TrajectoryObject>();
    }

    /// <summary>
    /// Internal method which picks up the ItemIdentifier.
    /// </summary>
    /// <param name="character">The character that should pick up the ItemIdentifier.</param>
    /// <param name="inventory">The inventory belonging to the character.</param>
    /// <param name="slotID">The slot ID that picked up the item. A -1 value will indicate no specified slot.</param>
    /// <param name="immediatePickup">Should the item be picked up immediately?</param>
    /// <param name="forceEquip">Should the item be force equipped?</param>
    /// <returns>True if an ItemIdentifier was picked up.</returns>
    protected override bool DoItemIdentifierPickupInternal(GameObject character, InventoryBase inventory,
        int slotID, bool immediatePickup, bool forceEquip)
    {
        var pickupItems = m_Inventory.AllItemInfos;
        if (pickupItems.Count == 0)
            return false;

        var isAllAdded = true;

        var characterInventory = character.GetCachedComponent<InventoryCollections.Inventory>();

        var mainItemCollection = characterInventory.MainItemCollection as ItemTransactionCollectionCustom;
        if (mainItemCollection == null)
            return false;

        var itemSlotCollections = characterInventory.ItemCollectionsReadOnly
            .OfType<InventoryCollections.ItemSlotCollection>()
            .ToList();

        for (int i = pickupItems.Count - 1; i >= 0; --i)
        {
            var itemInfo = pickupItems[i];

            if (m_RemoveItemsOnPickup)
                itemInfo = m_Inventory.RemoveItem(itemInfo);

            if (m_PickupItemCopies)
            {
                itemInfo = new ItemInfo((InventorySystemManager.CreateItem(itemInfo.Item), itemInfo.Amount),
                    itemInfo.ItemCollection);
            }
            else if (m_RemoveItemsOnPickup == false)
            {
                // Remove the item and replace it by a copy.
                itemInfo = m_Inventory.RemoveItem(itemInfo);
                m_Inventory.AddItem((ItemInfo) (InventorySystemManager.CreateItem(itemInfo.Item), itemInfo.Amount));
            }

            (var equippedItemCollection, int slotIndex) =
                itemSlotCollections.GetEquipmentItemCollectionAndSlotIndex(itemInfo.Item);

            // Can equip item.
            if (m_EquipOnPickup && equippedItemCollection != null && slotIndex != -1)
                if (equippedItemCollection.SlotIsEmpty(slotIndex))
                {
                    var itemSlotCollectionCustom = equippedItemCollection as ItemSlotCollectionCustom;
                    var equippedItemInfo = itemSlotCollectionCustom?.AddItem(itemInfo);

                    if (equippedItemInfo.HasValue && equippedItemInfo.Value.Amount == itemInfo.Amount)
                    {
                        if (_isDebugging)
                            Debug.LogWarning($"{itemInfo.Item.name} equipped.", this);

                        EventHandler.ExecuteEvent(character, "OnPickupItem", itemInfo);
                        continue;
                    }
                    else
                    {
                        if (_isDebugging)
                            Debug.LogWarning($"{itemInfo.Item.name} cannot be equipped.", this);
                    }
                }

            var canAddItemResult = mainItemCollection.CanAddItem(itemInfo);

            if (mainItemCollection.AddingToCollection != null && canAddItemResult.HasValue)
            {
                if (canAddItemResult.Value.Amount == itemInfo.Amount)
                {
                    if (_isDebugging)
                        Debug.LogWarning(
                            $"The {canAddItemResult.Value.Amount} {itemInfo.Item.name} can be fully added.", this);

                    mainItemCollection.AddItem(itemInfo);

                    EventHandler.ExecuteEvent(character, "OnPickupItem", itemInfo);
                }
                else
                {
                    if (_isDebugging)
                        Debug.LogWarning("The Item can be added but only partially.", this);

                    mainItemCollection.AddItem(canAddItemResult.Value);
                    m_Inventory.AddItem(itemInfo.Item, itemInfo.Amount - canAddItemResult.Value.Amount);
                    isAllAdded = false;
                }
            }
            else
            {
                if (_isDebugging)
                    Debug.LogWarning($"The {itemInfo.Item.name} cannot be added.", this);

                m_Inventory.AddItem(itemInfo);
                isAllAdded = false;
            }
        }

        if (isAllAdded == false)
            SortItems();

        return isAllAdded;
    }

    public object[] InstantiationData
    {
        get => _instantiationData;
        set => _instantiationData = value;
    }

    public object[] SpawnData()
    {
        var pickupItems = m_Inventory.AllItemInfos;

        // int objLength = m_ItemDefinitionAmounts.Length * 2 + (_trajectoryObject != null ? 3 : 0);
        int objLength = pickupItems.Count * 2 + (_trajectoryObject != null ? 3 : 0);

        if (_spawnData == null)
            _spawnData = new object[objLength];
        else if (_spawnData.Length != objLength)
            System.Array.Resize(ref _spawnData, objLength);

        for (var i = 0; i < pickupItems.Count; ++i)
        {
            uint itemDefinitionID = pickupItems[i].Item.ItemDefinition.ID;
            int amount = pickupItems[i].Amount;

            _spawnData[i * 2] = itemDefinitionID;
            _spawnData[i * 2 + 1] = amount;
        }

        // The trajectory data needs to also be sent.
        if (_trajectoryObject != null)
        {
            _spawnData[_spawnData.Length - 3] = _trajectoryObject.Velocity;
            _spawnData[_spawnData.Length - 2] = _trajectoryObject.Torque;

            int originatorID = -1;

            if (_trajectoryObject.Originator != null)
            {
                var originatorView = _trajectoryObject.Originator.GetCachedComponent<PhotonView>();
                if (originatorView != null)
                    originatorID = originatorView.ViewID;
            }

            _spawnData[_spawnData.Length - 1] = originatorID;
        }

        return _spawnData;
    }

    public void ObjectSpawned()
    {
        if (InstantiationData == null)
            return;

        // Return the old.
        for (var i = 0; i < m_ItemDefinitionAmounts.Length; ++i)
            GenericObjectPool.Return(m_ItemDefinitionAmounts[i]);

        // Setup the item counts.
        int itemDefinitionAmountLength = (InstantiationData.Length - (_trajectoryObject != null ? 3 : 0)) / 2;
        if (m_ItemDefinitionAmounts.Length != itemDefinitionAmountLength)
            m_ItemDefinitionAmounts = new ItemDefinitionAmount[itemDefinitionAmountLength];

        m_Inventory.MainItemCollection.RemoveAll();

        for (var i = 0; i < itemDefinitionAmountLength; ++i)
        {
            var itemDefinitionID = (uint) InstantiationData[i * 2];
            var itemDefinition = InventorySystemManager.GetItemDefinition(itemDefinitionID);
            var amount = (int) InstantiationData[i * 2 + 1];

            m_ItemDefinitionAmounts[i] = new ItemDefinitionAmount(itemDefinition, amount);
            m_Inventory.AddItem(itemDefinition, amount);
        }

        Initialize(true);

        // Setup the trajectory object.
        if (_trajectoryObject != null)
        {
            var velocity = (Vector3) InstantiationData[InstantiationData.Length - 3];
            var torque = (Vector3) InstantiationData[InstantiationData.Length - 2];
            var originatorID = (int) InstantiationData[InstantiationData.Length - 1];

            GameObject originator = null;
            if (originatorID != -1)
            {
                var originatorView = PhotonNetwork.GetPhotonView(originatorID);
                if (originatorView != null)
                    originator = originatorView.gameObject;
            }

            _trajectoryObject.Initialize(velocity, torque, originator);
        }
    }
}
 
Hi guys

i'm using ucc + uis + pun2, i'm followed this post to make inventory work in a coop scene.

I'm trying to figure the best way to share a storage across the players, for that i tried to import a storage house in my test scene.

Basically i have two pun characters in this scene, each player can interact with the storage menù but storage inventory isn't updated for the other player in scene. (its seems that every pun character use its own Storage Menu)

I tried with the option "Bind to panel owner" in storage ui:
inventory.png

uis2.png

uis3.png


and this is the Storage object
storage inventory.png
Nuovo progetto.png

this is a short video of the problem
 
Top