Crafting Scroll Bar Not Scrolling

I can't seem to get the scroll bar to play nice. I can move the scroll bar, but it doesn't update the recipe list. Just to show that there are actually more items in there, I changed the scrollsize to 7, so you can see an item below. I've included screenshots of my ScrollBarPanel and ScrollContent settings as well. The code remains unchanged and the settings are exactly as they are in the demo.

Ideas?
 

Attachments

  • scrollbar.png
    scrollbar.png
    644.8 KB · Views: 11
  • settings.png
    settings.png
    51.8 KB · Views: 9
Thank you for bringing this to my attention, the start index of the list was being set to 0 each time before the list was redrawing because of the GridDisplayWithCategoryTabBinding component.

open that GridDisplayWithItemCategoryTabBinding.cs script

and change the relevant functions by the following:
C#:
/// <summary>
/// Send events before drawing.
/// </summary>
private void BeforeDrawing()
{
    SetCategoryPageCounts();
}
/// <summary>
/// Draw the grid when the page changes.
/// </summary>
private void PageChanged()
{
    m_GridDisplayWithItemCategory.SetItemCategoryDisplay(m_CategoryTabControl.CurrentTab);
   
    SetCategoryPageCounts();
   
    var newIndex = m_CategoryTabControl.PageIndex * m_GridDisplayWithItemCategory.GridBase.GridSizeCount;
    m_GridDisplayWithItemCategory.GridBase.SetIndex(newIndex);
    m_GridDisplayWithItemCategory.GridBase.Draw();
    m_GridDisplayWithItemCategory.GridBase.GridEventSystem.SelectRowButton(true);
}

I'll add that fix in the next patch
 
Thanks! Worked like a charm.

I've run into another issue, and I thought it was something I did, so I retraced my steps one by one, and I think it might be an issue with UIS. I want to set up my Crafting RecipePanel so that it will show up to six (6) Ingredient Items, but I'm getting the following error:

Code:
IndexOutOfRangeException: Index was outside the bounds of the array.
Opsive.UltimateInventorySystem.Demo.UI.Menus.Crafting.RecipePanel.ClearItemIngredient (System.Int32 i) (at Assets/Opsive/UltimateInventorySystem/Demo/Scripts/UI/Menus/Crafting/RecipePanel.cs:217)

There are a ton of other lines to that error, but I assume one would be enough to assess the issue. I included a screenshot of my setup as well.

Thanks for the help!
 

Attachments

  • Screen Shot 2020-09-11 at 6.19.45 PM.png
    Screen Shot 2020-09-11 at 6.19.45 PM.png
    394.7 KB · Views: 3
Line 217 in the RecipePanel script does not match to anything in my project. Either you changed something in code or I did, but I do not remember changing this script since the very beginning.

Having a look at the code around that line, my suspicion is the item description for each ingredient. My guess is that is what is failing.

C#:
m_IngredientDescriptionPanel.ItemDescriptionUIs[i]

Try to find the description component for the ingredients and make sure it has an array of the same length as the number of ingredients.
1600066840930.png
1600066860687.png
See here they both have an array of 4.

Side note: if you change the code make sure to backup your project often and especially before updates. Of course you'll want to copy those scripts and add them in your own folders, you'll also want to change the namespace.
Then you'll also need to replace the components on your menus to point to the correct scripts.

Also a heads up, I haven't got to reworking the crafting UI in v1.1 yet. If there are any functionality you wish for please let me know in advance so that I can take it into account. Quite a lot of the UI will change. Hopefully it'll make a lot more sense and be easier to use.
I'll still need a long time to finish v1.1 though, so you should not worry about it for now.
 
Thanks - you were correct. I just needed to make sure that the description array had the same number of elements in the inspector. I wasn't using that object, so that's how I missed it.

Future Functionality: Obviously take these as you will, but here are some things I was hoping to incorporate myself that I would love to see in a future version. All of these can be done with custom code (and likely a custom crafting processor), but a few of these appear in a lot of crafting-heavy games so may be useful to have as base features):
  • Craft items by dragging items from the inventory. This allows for experimentation and "finding" new recipes that wouldn't already show up in the recipe panel. They'd still have to exist in the database, but the user might not know about them yet. Which leads me to...
  • Ability to "add" recipes to the recipe list when you find them in the game. This could probably be implemented doing something similar to how you have the custom example for recipes by level, but it's a common enough thing in games that it might be worthwhile to have out of the box.
  • Some sort of timing bar that you hold down that fills up as you craft to give the play the sense that they are doing something in-game. (This is what I already implemented (with your help) with the TimeToCraft attribute I added to my item definitions.) Or crafting over time that you walk away from and it's complete at a later time (davecha was working on this in another forum post.)
    • In that same vein, a way to pause the crafting process (if an item takes a while and your player has run out of energy, for example) and come back to it later.
Anyway, that's my first take at some ideas that I would hope to have as features - I'm sure I'll have more as I dig further into this project. If any of these suggestions are already doable and easy, please let me know :)

Thanks for all the help - your response time and ability to share actually useful information is fantastic.
 
Your suggestions are noted. Since they are not purely UI related they might not make v1.1 but they might do a v1.1.X or v1.2 (especially suggestion 1 and 2).

Suggestion 3 is more game specificc so I'll wait a little to see if many people want a similar feature too.
 
Awesome!

Any basic suggestions on where to start with adding recipes to the Player's recipe list based on the Player receiving a new recipe in-game? That's the next thing I'll be working on related to crafting. Could I just set an isActive attribute to each recipe and then only display those? If so, how would I go about updating an attribute in the database through in-game code? Or is there a better way to do it?
 
I think the easiest way to go about it is have a List<Recipe> somewhere on your character script. You can then use that list instead of the list defined on the "CraftingInteractableBehavior" component.

The part that matters is this one:
Code:
m_CraftingMenu.SetClientInventory(interactorWithInventory.Inventory);
m_CraftingMenu.SetRecipes(m_Recipes);
m_PanelManager.OpenMenu(m_CraftingMenu);

You could replace CraftingInteractableBehavior by your own script, this way you can set the recipes however you wish.

Side note, you don't want to change the database in game ever. The database is supposed to be static data which never changes.
Items are create from the definitions in the database but they are not part of the database so they can be modified at runtime.
Recipes, categories, definitions, etc.. cannot.
As for changing item attribute values at runtime you can look at the documentation here: https://opsive.com/support/documentation/ultimate-inventory-system/attributes/
 
Thanks! I fear this one may be a little over my head at the moment; I'm just starting to wrap my head around how you have everything set up in the code. It sounds like what you're saying is that I would need to set up a new list (similar to how I can pass a Crafting Category into the interactable - see screenshot)?

If so, how would I go about generating such a list so that it would match up and interact with the recipes in the database?

Apologies for the noob question. :)
 

Attachments

  • Screen Shot 2020-09-15 at 5.58.38 PM.png
    Screen Shot 2020-09-15 at 5.58.38 PM.png
    26.9 KB · Views: 2
Yes that is correct.

So from what I understand you wish your character to learn recipes one by one correct? You could do so by picking them up, completing quests, story events, etc...

Since recipes are scriptable objects, it is very easy to get a reference to it in script through a serialized field.

So you could create a component on your character that has a public List<Recipe>. Then whenever you wish to add more recipes you simply do myRecipes.Add(newRecipe). (try to check if the recipes was already added first, you wouldn't want to have the same recipe multiple times).


C#:
public class CharacterCraftingData : Monobehaviour {
    public List<Recipe> myRecipes;
}

Then on your custom CraftingInteractableBehavior script you can replace the OnInteractinternal function:

C#:
        /// <summary>
        /// Open the craft menu on interact.
        /// </summary>
        /// <param name="interactor">The interactor.</param>
        protected override void OnInteractInternal(IInteractor interactor)
        {
            if (!(interactor is IInteractorWithInventory interactorWithInventory)) { return; }

            m_CraftingMenu.SetClientInventory(interactorWithInventory.Inventory);
            m_CraftingMenu.SetRecipes(interactorWithInventory.Inventory.GetComponent<CharacterCraftingData>().myRecipes);
            m_PanelManager.OpenMenu(m_CraftingMenu);
        }

Note that the code above is not tested but it should give you an idea of what to do.

At one point you will want the list of recipes to persist when saving the game. When that time comes I'll guide you on how to create a custom saver component if you plan to use the Inventory saving system, if not you can use other solutions out there, or your own of course.
 
Top