A bit of guidance needed for some custom Farming code

the built-in IK is what I’m seeking. I know how hard dealing with IK is (third year of engineering was hell for a reason), so frankly speaking, I don’t want to deal with it

If only Unity had a way to trim animations in the import settings under Animations with something like a Start and End Frame…


if only… :stuck_out_tongue:

If only Unity would fix this NRE though (I’m using 2.10.0 and it’s still there, although they told me it won’t be there!):

NullReferenceException: Object reference not set to an instance of an object
Cinemachine.Editor.CinemachineSceneToolUtility+<>c.<.cctor>b__21_0 () (at Library/PackageCache/com.unity.cinemachine@2.10.0/Editor/Utility/CinemachineSceneTools.cs:272)
UnityEditor.EditorApplication.Internal_CallUpdateFunctions () (at <57a8ad0d1492436d8cfee9ba8e6618f8>:0)

Unity’s internal bugs will always be with us… They just change shape and flavor. They’re like the Hydra, cut off one head and two grow back.

99 lines of bugs in the code
99 lines of bugs
You take one down, patch it around,
101 lines of bugs in the code.
1 Like

Well… this one if I’m not mistaken just broke my game… GG Unity

Edit: My bad, that was a coding mistake from my side. I’m currently trying this out

The boat camera is giving me NREs that are game-breaking when the game pauses or something

You’d be surprised… most of these bugs are just annoying more than anything else, and when you build to the game, that bit of code throwing the NRE won’t even be in the final game. Try turning off Live Updates in your Cinemachine Virtual Cameras.

1 Like

Where’s the ‘Live Updates’?

and I also have a problem on my other post. Apparently with my new setup, the ‘Resume’ button does not bring the game up to speed, unless I hit the escape key to unpause the game :slight_smile:

You may want to check this out

Meant to say “Save during play”… lets you adjust settings while the game is played and the settings get serialized.

  1. I fixed my bug, I’ll share a screenshot at the appropriate post

  2. I’ll go turn off ‘Save during Play’ first :slight_smile:

Fun fact: If there’s one thing I learned from this journey, is I became quite good with events. It was only a matter of time and experience

And… I just found a flaw in my code that came out of the farming system, which hurts crafting, smithing and cooking. Here’s the ‘CraftingTable.CraftRecipe()’ function:

        // Start the crafting process
        void ICraftingTable.CraftRecipe(Recipe recipe, int quantity /* <-- Quantity is a test for Farming Solutions only (something that activates 'UseQuantityUI'*/)
        {
            Debug.Log($"Craft Recipe called");
            // Set the state of the table
            // Reset progress
            CraftingPercentage = 0f;
            // Set the start time to whatever the global time is
            craftingStartTime = timeKeeper.GetGlobalTime();
            // Set the current recipe to craft
            CurrentRecipe = recipe;
            /*
            // COMMENT THE TEST OUT IF YOU DON'T WANT YOUR PLAYER TO HAVE A FAILURE CHANCE OF CRAFTING STUFF:
            // --------------------------- (TEST) If we failed, transition to the failed state -----------------------------
            // var skillStore = GameObject.FindWithTag("Player").GetComponent<SkillStore>(); // Already calculated in 'CalculatePlayerFailChance'
            // var skillLevel = skillStore.GetSkillLevel(Skill.Crafting);   // Already calculated in 'CalculatePlayerFailChance'
            var randomValue = UnityEngine.Random.value;
            // var playerFailChance = Mathf.Clamp01((skillLevel - CurrentRecipe.GetRequiredLevel()) / (CurrentRecipe.GetMaxLevel() - CurrentRecipe.GetRequiredLevel()));
            // var playerFailChance = Mathf.Clamp01(Mathf.Log10(skillLevel - CurrentRecipe.GetRequiredLevel() + 2) / Mathf.Log10(CurrentRecipe.GetMaxLevel() - CurrentRecipe.GetRequiredLevel() + 2) * 0.8f);
            var playerFailChance = CalculatePlayerFailChance(CurrentRecipe);    // Linear equation
            // global variables:
            Debug.Log($"Random Value: {randomValue}");
            craftingFailed = randomValue > playerFailChance;
            Debug.Log($"Player fail chance: {playerFailChance}");
            Debug.Log($"Crafting Failed? {craftingFailed}");
            failedAtPercentage = playerFailChance;
            Debug.Log($"Point of failure: {failedAtPercentage}");
            // ------------------------------------- END OF TEST -----------------------------------------------------------
            */
            // Set the state (the action will do it) to crafting
            currentAction = CraftingAction;

            // Crafting Quantity
            craftingQuantity = FindObjectOfType<CraftingQuantity>();

            // Remove the ingredients from the player's inventory
            var playerInventory = Inventory.GetPlayerInventory();
            foreach (var ingredient in recipe.GetIngredients())
            {
                playerInventory.RemoveItem(ingredient.Item, ingredient.Amount * quantity /* <-- Quantity is a test for Farming Solutions only (something that activates 'UseQuantityUI'*/);
            }

            // If the recipe has a Crafting cost, remove the gold from the player
            var purse = playerInventory.GetComponent<Purse>();
            purse.UpdateBalance(-recipe.GetRecipeCost() * quantity);

            // TEST - DELETE IF FAILED (FOR IDENTIFYING PLANT GROWTH HANDLERS)
            string[] uniqueIdentifiers = new string[craftingQuantity.GetCurrentQuantity()];

            if (UseQuantityUI) // If you're using the Quantity UI (The code below is dedicated for Farming only for this case)
            {
                for (int i = 0; i < craftingQuantity.GetCurrentQuantity(); i++)
                {
                    // Plant quantity based on what the 'GetCurrentQuantity()' has available, 
                    // which is controlled in 'CraftingSystem.OnCraftingInteraction()', and the 
                    // value is also updated below, after you hit the 'Craft' button on the UI
                    var availableSlots = GetComponentsInChildren<PlantGrowthHandler>().Where(handler => handler.GetCurrentPlant() == null);
                    var firstAvailableSlot = availableSlots.First();
                    firstAvailableSlot.SetCurrentPlant(recipe.GetResult().Item.GetPickup().gameObject); // Just a way to indicate that this slot is occupied

                    // TEST - DELETE IF FAILED (FOR IDENTIFYING PLANT GROWTH HANDLERS)
                    uniqueIdentifiers[i] = GetComponentsInChildren<PlantGrowthHandler>()[i].UniqueIdentifier;
                }
            }

            // Crafting has started
            CraftingStarted?.Invoke();
            // OnCraftingNotificationStarted?.Invoke(CurrentRecipe.GetCraftDuration()); // Replaced by a more generic 'Crafting Notification' System below
            eventBus.CraftingStarted(CurrentRecipe, uniqueIdentifiers);
        }

here’s the thing: if we aren’t farming, the string[array] of unique identifiers will be empty, and an empty string[array] of unique identifiers means the update function goes bad. Any idea how to fix this? @Brian_Trotter @bixarrio (and I’m guessing the restore from JToken will have the same issue)

This is the troublesome line:

            // TEST - DELETE IF FAILED (FOR IDENTIFYING PLANT GROWTH HANDLERS)
            string[] uniqueIdentifiers = new string[craftingQuantity.GetCurrentQuantity()];

and the error:

NullReferenceException: Object reference not set to an instance of an object
RPG.Crafting.CraftingTable.RPG.Crafting.ICraftingTable.CraftRecipe (RPG.Crafting.Recipe recipe, System.Int32 quantity) (at Assets/Asset Packs/bixarrio/RPG Crafting System/Scripts/CraftingTable.cs:244)
RPG.Crafting.CraftingSystem.CraftRecipe () (at Assets/Asset Packs/bixarrio/RPG Crafting System/Scripts/CraftingSystem.cs:279)
UnityEngine.Events.InvokableCall.Invoke () (at <ba783288ca164d3099898a8819fcec1c>:0)
UnityEngine.Events.UnityEvent.Invoke () (at <ba783288ca164d3099898a8819fcec1c>:0)
UnityEngine.UI.Button.Press () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:70)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:114)
UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:57)
UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:272)
UnityEngine.EventSystems.EventSystem:Update() (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:514)

and here’s where I did all the original changes


Edit: and here’s the fix:

            // TEST - DELETE IF FAILED (FOR IDENTIFYING PLANT GROWTH HANDLERS). Also ensures non-quantity UI users (Crafting, Smithing, Cooking) have a value to fall back on
            string[] uniqueIdentifiers = UseQuantityUI ? new string[craftingQuantity.GetCurrentQuantity()] : new string[0];

I only put this in ‘CraftingTable.CraftRecipe()’. For some reason, ‘RestoreFromJToken()’ did not seem to complain about this at all, so I didn’t put it in there

I singularly hate arrays because they’re so rigid in what you can do with them, and of course because they are in no way dynamic…
My tendency is to use Lists instead and in the declaration make sure they are initialized to new()

I’m not sure if this would have helped in this case (and as I’ve mentioned before, I still dont’ have adequate time to do more than glance at the massive amounts of code you’ve pasted. :slight_smile:

I am pretty sure if you spent enough time looking at my own code changes, you’ll want to change a lot of things, but for now I’m just trying to survive with what I have until you guys are more available to help out

But if it works, don’t touch it! :slight_smile:

Privacy & Terms