Merging the Third Person Controller Course with the RPG Course

No, look at my edit

yup, found the script, but this got us into a new problem:

‘currentCraftingTable’ is of type ICraftingTable not just CraftingTable… do we create a new variable instead, or do we cast it as ‘CraftingTable’ type…? (Idek if that’s possible, just a wild guess)

No, you add the method to the interface, too. It’s now part of the contract

public interface ICraftingTable
{
    // ... existing stuff
    void CraftingTableClosed();
}

It’s totally possible because CraftingTable is an ICraftingTable, but we don’t want to have any reference to CraftingTable here, so we won’t be casting anything.

Yup, added it too, but it still didn’t solve the problem that my player no longer responds to inputs once you open the UI, and yes the button is placed in the proper place in the action map. Here is the StateMachine again, which I suspect is the main problem:

using RPG.Crafting;

namespace RPG.States.Player
{
    public class PlayerCraftingState : PlayerBaseState
    {
        private CraftingTable target;

        public PlayerCraftingState(PlayerStateMachine stateMachine, CraftingTable craftingTable) : base(stateMachine)
        {
            target = craftingTable;
        }

        public override void Enter()
        {
            target.CraftingTableClosed += OnCraftingTableClosed;
            target.NotifyCrafting();
        }

        public override void Tick(float deltaTime) {}

        public override void Exit()
        {
            target.CraftingTableClosed -= OnCraftingTableClosed;
        }

        private void OnCraftingTableClosed() 
        {
            stateMachine.SwitchState(new PlayerFreeLookState(stateMachine));
        }
    }
}

Your player won’t respond to input while the table is open. There is nothing in the crafting state handling input. Generally, movement doesn’t happen while someone is in a crafting menu. I remember now that you want to walk away from the table to close it, so you will have to implement all the code from the movement state in here as well. Or crafting shouldn’t actually be a state

even when it’s closed AFTER he reaches to it and opens it, he still doesn’t respond to input… like, it just permanently destroys the connection between the player and the controls :sweat_smile:

OK not really, for this case I want the player to be frozen in state until he clicks the ‘x’ button to close the UI, and only then is he allowed to move away from the Crafting Table, so I want to reactivate the input only after he walks away from the table (both the player input and the cinemachine camera rotation in this case… completely pausing the game at that point is not my ideal solution tbh)

If the input doesn’t work after the table closes it’s possible that the event didn’t fire. Put a Debug.Log in OnCraftingTableClosed to confirm. If it doesn’t fire it means nothing is telling it to.

This is much easier to work with. Because the ‘Crafting’ state doesn’t handle input, the player won’t be able to move. Once the table closes and the event is fired, the player will return to the freelook state (like in your code) and input will get handled again. You just have to make sure that event is actually fired

OK so… when you hit the ‘L’ button, you can interact with the UI, but once you hit that button (the ‘L’ button, my temporarily assigned key for interacting with the Crafting Table), you are permanently disconnected from all your controls

and the debug doesn’t get called for some reason

Frankly speaking, unlike what Brian did, where he pauses the game fully if any UI opens, I don’t like this approach. Personally, I want my old approach, where you can still have the game work around you as usual if you got UI open, and maybe add in the cinemachine rotation freezer until you’re done with some of the UI elements

I believe the pause should only work for the pause menu, and that’s it :slight_smile: (but that’s for another day. For now, I just want the construction saving system to work, and the Crafting UI)

You are not ‘disconnected’, the state just doesn’t handle input.

And there’s the problem. You need to find out why.

It’s probably because you are using the ShowHideUI but, like we did in your previous version, you also need to call CraftingSystem.CloseCrafting(). The UnityEvents made it easy

Are we talking about this function, in ‘ShowHideUI.cs’?

public void DisableCraftingTable() {

            craftingTableUI.SetActive(false);
            Debug.Log("Crafting Table deactivated");

        }

P.S: I made a copy of ‘ShowHideUI.cs’, for the crafting table, called it ‘ShowHideCraftingUI.cs’, as follows:

using GameDevTV.UI;
using UnityEngine;
using UnityEngine.Events;

namespace RPG.Crafting
{
    public class ShowHideCraftingUI : MonoBehaviour
    {
        // A unity event to allow us to hook up handlers in the inspector
        [SerializeField] UnityEvent onModalActive;

        private void Start()
        {
            // Subscribe to the OnModalActive event
            ShowHideUI.OnModalActive += OnModalActive;
        }

        private void OnDestroy()
        {
            // Unsubscribe from the OnModalActive event
            ShowHideUI.OnModalActive -= OnModalActive;
        }

        public void OnModalActive()
        {
            // Handle the event
            onModalActive.Invoke();
        }
    }
}

Probably. You pasted a ShowHideCraftingUI script above (here) that has a UnityEvent. Just add CraftingSystem.CloseCrafting() to the list in the inspector. Although the crafting system also closes the window.

It was there the entire time… :sweat_smile: - and the issue persisted through it all

If it helps, here is the ‘CraftingSystem.CloseCrafting()’ function:

// Bound to the 'Close Button'
        public void CloseCrafting()
        {
            if (!craftingWindow.gameObject.activeSelf)
            {
                // If the crafting UI is already closed, there's no need to clean it up
                return;
            }

            // let the crafting table know it's being closed:
            currentCraftingTable.CloseCraftingTable();

            // Unsubscribe to all the events
            currentCraftingTable.CraftingStarted -= OnCraftingStarted;
            currentCraftingTable.CraftingProgress -= OnCraftingProgress;
            currentCraftingTable.CraftingCompleted -= OnCraftingCompleted;
            currentCraftingTable.CraftingFailed -= OnCraftingFailed;
            currentCraftingTable.CraftingCancelled -= OnCraftingCancelled;
            recipeOutput.ItemRemoved -= OnOutputRemoved;
            
            // Cleanup the UI
            Cleanup();
            // Close the Crafting UI
            craftingWindow.SetActive(false);
            // remove the reference to the crafting table
            currentCraftingTable = default;
        }

OK, So that’s perfect. And the code looks fine, too. Now, let’s see the CloseCraftingTable code

sure, it’s in ‘CraftingTable.cs’:

        public void CloseCraftingTable() 
        {
            CraftingTableClosed?.Invoke();
        }

This is fine, too. And the rest is like you pasted? Show me where you change the state to crafting

the only connection left is in ‘PlayerFreeLookState.cs’, and this is what it looks like:

        private void InputReader_HandleCraftingEvent() 
        {
            if (stateMachine.CraftingFinder.FindNearestTarget()) 
            {
                PlayerCraftingState nextState = new PlayerCraftingState(stateMachine, stateMachine.CraftingFinder.CurrentTarget);
                stateMachine.SwitchState(new PlayerFacingState(stateMachine, stateMachine.CraftingFinder.CurrentTarget.transform.position, nextState));
            }
        }

and yes, the subscriptions to this function are properly implemented, and there’s a proper CraftingFinder connection (otherwise the initial UI won’t even open up to begin with :sweat_smile:)

So now we have more states. I looked at the PlayerFacingState above (didn’t read it all so I may be missing something) but it looks ok. Can we confirm that the player is actually in the PlayerCraftingState?

If it is, you’ll need to follow the code all the way from the close button click. Put Debug.Log in the ShowHideCraftingUI.OnModalActive(), CraftingSystem.CloseCrafting(), CraftingTable.CloseCraftingTable() and PlayerCraftingState.OnCraftingTableClosed()


Edit
There is one other thing I suspect may be a problem, but let’s see how we go with this first. I don’t know how to solve the other one, yet.

I believe it should be, because the enter function of that state calls the Crafting System UI, and that’s what it does, so yes I think it is

And surprisingly… none of the debuggers get called, and when I go to the Crafting Quit Button, this is the attached function that I found:

should I change that to ‘CraftingSystem.CloseCrafting()’ by chance?

Privacy & Terms