UCC - UIS - BT Equip Task issue

In my project I have an Enemy using 3rd person UCC and UIS which is controlled by Behavior Tree and nav mesh. I have followed the videos and instructions on how to set this up and I think it’s all working. The enemy has a couple of items in inventory (one in Loadout and a couple in Equippable) and when running, the loadout item is equipped and they all show up in the Inventory Bridge. I have setup an Item Set Rule and when running, a few Item Sets show up. All seems ok so far. However, when opening the BT and looking at the Inspector tab for the Start Equip Unequip I get an incomplete tab.

I'm reproducing my issues in the Demo located in UCC->Integration->UIS->Demo and I attached the test tree below to InventoryAtlas.

Test behavior tree:
1687807002627.png

Incomplete inspector tab:
1687807032309.png

I get a stream of console errors when opening the Inspector tab:
1687807087975.png

When using a breakpoint and inspecting I see this:
1687807321768.png
 
I think there might be a bug witht he Behaviour designer (BD) integration. Or we need to make a abstracted function in UCC so that the BD task does not need to worry about the UCC/UIS integration way of equipping items. @Justin What do you think?
 
I just tried on InventoryAtlas and am not getting an error but it only shows one ItemSet category.

1687852896161.png

My guess is that it's an initialization issue. This was fixed a few releases ago in the Ultimate Character Controller inventory in that the inventory wasn't initializing correctly at edit time.
 
So I made two changes. First in
ItemSetGroup.cs
I replaced the categoryName getter by (around line 70):
Code:
   public string CategoryName => ItemCategory?.name ?? "NULL";

That prevented the error from happening

But the cateogories are still null. That's because I was preventing the InventoryItemSetManager from initilalizing in the editor thinking it was a good idea. But turns out it wasn't.

So in InventoryItemSetManager.cs
remove the initialize function completely (around line 19 to 30)

Instead in the base class

ItemSetManagerBase.cs
add a condition to only register to the events when in play mode:
Code:
/// <summary>
/// Initializes the ItemSetManager.
/// </summary>
/// <param name="force">Should the ItemSet be force initialized?</param>
public virtual void Initialize(bool force)
{
    if (m_Initialized && !force) {
        return;
    }
    
    m_Initialized = true;
    m_GameObject = gameObject;
    m_Inventory = m_GameObject.GetCachedComponent<InventoryBase>();
    if (m_Inventory == null) {
        Debug.LogError("An Inventory component is required for an ItemSetManager.");
    }
    m_ItemSetPool = new Dictionary<IItemSetRule, Stack<ItemSet>>();
    m_CachedCharacterItemsBySlot = new List<CharacterItem>[SlotCount];
    if (m_CategoryIndexMap == null) {
        m_CategoryIndexMap = new Dictionary<uint, int>();
    } else {
        m_CategoryIndexMap.Clear();
    }
    for (int i = 0; i < m_ItemSetGroups.Length; ++i) {
        var itemSetGroup = m_ItemSetGroups[i];
        itemSetGroup.Initialize(gameObject, this);
        // Create a mapping between the category and index.
        m_CategoryIndexMap.Add(itemSetGroup.CategoryID, i);
    }

//THIS LINE HERE
    if(Application.isPlaying == false){ return; }
    
    EventHandler.RegisterEvent<CharacterItem>(m_GameObject, "OnInventoryAddItem", OnAddItem);
    EventHandler.RegisterEvent<CharacterItem>(m_GameObject, "OnInventoryDestroyItem", OnDestroyItem);
    EventHandler.RegisterEvent(m_GameObject, "OnInventoryLoadDefaultLoadoutComplete", OnInventoryLoadDefaultLoadoutComplete);
}


And now it seems to work as expected:
1688038557034.png


If you have any issue please do let me know
 
Thanks Sangemdoko, I have made those same edits and I don't get an error and the dropdown shows "content". However, it seems to show the wrong content.

I have a sample scene where I test my enemies behavior and I'm using an Atlas prefab to act as the character. My enemy's behavior tree (I have the enemy selected in the Hierarchy and see his BT in the editor) is just the one task like your screenshot and when I click the ItemSet Category dropdown in the Equip task I see the Item Set Groups from Atlas, not from my enemy. I put a breakpoint in OnGUI in UltimateCharacterControllerDrawer.cs on line 79 and it has Atlas in there like this:

1688042683267.png

My Enemy only has an "Equippable" Item Set Group and nothing on his character has anything related to grenades:

1688042858049.png

Is it a matter of not re-initializing somewhere?

Atlas does not have a BT on him and he doesn't use UIS only the UCC built-in inventory. My sample scene only has the one Enemy which has the BT and is using UIS.
 
Last edited:
Ah my mistake. I didn't realise it was grabbing the first object it could find with categories.

Justin has now updated the BD/UCC integration on the website. Make sure to download it and import it.
The task inspector now looks for the categories directly on the target gameobject.
We also do that for the other tasks too to keep things consitant.

Thank you for letting us know about this issue. And I hop this time it will be fixed for good :)
 
I downloaded a file called UltimateCharacterController.unitypackage from the "Downloads for Behavior Designer" but it's hard to know if I have the newest file since there's no version number. It's 79KB in size if that helps.

I'm now back to getting an error when opening Inspector tab, a different one than earlier. I noticed that the Initialize function in ItemSetManager.cs got restored from the new integration file (the other two changes you had above was not affected) so I commented it out again but still same error. It now fails to find an ItemSetManger all together. Is it related to UCC Inventory vs. UIS?

1688069945727.png
 
The package doesn't contain any character controller code so ItemSetManager shouldn't have been reset. I would make the changes that Santiago mentioned just to be sure.

If you step into the ItemSetManager property what is null? Does it find the gameObject? Does the GameObject have the ItemSetManager on it?
 
Yes, I made sure all Santiago's changes are made.

I can't step into the ItemSetManager since that whole property is NULL and the task or taskItemSetManager doesn't have a reference to a gameobject from what I can tell.

My Enemy does not have the ItemSetManager component on him since he is using UIS. He does have an InventoryItemSetManager component with one Equippable ItemSetGroup, it's in the screenshot from yesterday.
 
Just for sanity, I took a new clean Enemy prefab without any Opsive components on it. I did the Character setup in the Character Manager with all the checkboxes on the bottom checked. Then I did the BD->UCC Agent Setup under Integrations and added my test behavior tree with just the Equip task. At this stage, he is a behavior tree controlled enemy that is NOT using UIS and has the ItemSetManager component with one Item Set Group. I realize it shouldn't make a difference, both ItemSetManager and InventoryItemSetManager inherits from the same base class but I wanted to rule that out.

I open the BT, click on the Inspector tab for the Equip task and I get the same error as above.
 
That's very odd... It works fine on my side.

If you set the target game object here does it make a difference?
1688138949422.png

Is your character in the scene or inside a prefab?

Perhaps we're not taking into account the target properly or we're looking in the wrong place?
 
I have two prefabs in my scene. One is Atlas and is the player controlled character and the second is the Enemy. In my case a goblin with BD/UCC/UIS components. When I add the goblin as the target in this task, the error stream stops in the console and I see this in the Inspector tab:

1688139500254.png

The ItemSet Category dropdown only has one value "NULL" in it. The goblin prefab in the scene definitely has an InventoryItemSetManager component with one Item Set Group:

1688139571552.png

Inventory wise it seems to be working fine. I add two daggers to his loadout inventory and he correctly wields them on startup. He can also attack using the Start Stop Use task in the behavior tree.
 
Ah, you are editing an external behavior tree. Because the external tree doesn't have a GameObject attached to it, it's not able to retrieve the ItemSetManager. I'll prevent that error from happening on external trees.

What is the error indicating within the Behavior Designer error window when you have inputted a prefab?
 
Is external trees not a good idea? It really helps with reusing trees between different enemies. The error says:

1688152505885.png

I can't use my enemy from the scene according to that. When dragging in same enemy from my prefabs, the error goes away but the ItemSet Category dropdown is still only NULL:

1688152638751.png

That would also defeat the purpose of reusing the tree with different prefabs...
 
I did a quick test using a NON external tree and as expected, it worked just fine. I see Equippable in the dropdown and without adding anything to Target Game Object.

Is using external trees not recommended? It seems like a great feature to me. I use it a lot where I test smaller parts of a bigger tree by themselves without having to force certain conditions being met in the larger tree.
 
External trees are great for reusability but because they aren't attached to a GameObject they are not able to pull in the ItemSetManager. If you want the category to populate you will need to fill in the target GameObject, but as you said that then makes it harder to reuse.

I think the best solution for your use case is to use a SharedVariable for the ItemSetCategory and then create a new task which sets the variable value just before StartEquipUnequip executes. This will allow you to then use the same tree for multiple different types of enemies and categories.
 
This sounds like a good idea and I'm testing it again now, I was playing with this earlier. The problem seems to be that when creating a shared variable, you can choose ItemCategory as data type but the Equip task is looking for ItemSet Category? I can't make a shared variable to show up in the dropdown under the Equip task inspector tab. I've tried some different data types but nothing seems to work there, Int seems like the obvious other choice but no Int type variables show up in the drop down.

1688390284137.png

The Item Set Index is just an Int and I already have a shared variable for that field because I want to spawn enemies and have them equip different weapons.

1688390313081.png

Is there a way to turn an external tree to be NOT external? Like an import?
 
Last edited:
The equip task is looking for a SharedUInt. This is the ID of the category. You can see the ID of the category if you enable debug mode on the inspector. I would need to think about it more for how to best handle this within an external tree.

1688403097711.png

You can save the external tree to a prefab on the top of the Behavior Designer toolbar with the Export button.
 
The UInt shared variable does show up in the task inspector but that ID is too large for a UInt. It seems to only be able to hold a 32 bit max of 2147483647.

Is there a different way to solve this? All I'm trying to do is specify which weapon my enemy should wield in certain situations. For example, my enemy is patrolling between points without any weapons wielded. He spots the player and wields a ranged weapon. Player gets closer and the enemy switches to a melee weapon.
 
Back
Top