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
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 (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⌠- 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 )
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?