Creating an escape room game in Unity
Tags: gamedev, unity3d, programming, csharp
Published: 2022-12-07 20:34:32

## What and why?
I've been thinking for a while, which game prototype I could work on in my free time. Working on various prototypes and things, which differ from my normal job can be a fun way to test myself and expand my knowledge in slightly other and new things. I've come up with few ideas (which were expanded by ChatGPT, who I might cover in future posts), but ultimately I've settled with an escape room game. *First person*, *basic movement* and a *possibility* to interact with *virtually anything* were some of the key aspects I had in mind when starting this project.

So I've started working on some core components of the game. While working on these, I've figured that it might not be a bad idea to write down my progress (hopefully every or every other week). First point why this might be a good idea is some sort of restrospective. I can open any of these posts at any time and analyze the code, tell what could've been done better and so on. Other one is to keep consistent progress and try to keep the project development going. 

With all that being said, I think it's about time to look into what I've done this week and try to explain the written systems as best I can.

## The game
### Character
Most of the stuff I've done is the simple "starting ground" work. I've written a pretty simple Rigidbody Character controller script, which takes care of first-person camera and all the common operations, such as clamping the player's look rotation, so they don't go upside down and similar things.

I think the Character controller is not very interesting, as it is really basic.

### Items
One of the key components is an item system. An easily configurable code, which can be put on as component on any GameObject and should be ready to use. The very important thing when it comes to items is interaction with them. 

Say we have a key. Key is lying on the ground and I want to pick it up. In some games, you walk over the key and it picks itself up automatically. As long as it's a pretty good solution, I've wanted to come up with something more robust. 

#### IInteractableController
I've come up with a concept of `IInteractableController`. The code is pretty simple.
```cs
public interface IInteractableController
{
    void OnInteract(IInteractable interactable);
    void RegisterParentDependency(IInteractable registrable);
}
```
Its sole purpose is to call `OnInteract` function on its parent `IInteractable` dependency.

`ProximityPrompt.cs`, for example, implements IInteractableController. It handles some logic of a player being near the GameObject (the component is on) and in some way (be it click or hold of a button) triggering an OnInteract event. When this event is fired, `IInteractableController` lets its parent IInteractable know that the Interactable has been interacted with.

Then I have class `Item`, which wraps some logic above an Item concept, such as Name and if the item is Stackable.
```cs
public class Item : MonoBehaviour
{
    public string Name;
    public bool IsStackable;
    public virtual void OnInteraction(Item item)
    {
        Player.Instance.Inventory.AddItem(new InventoryItem(item.Name, 1, item.IsStackable, item.gameObject));
        gameObject.SetActive(false);
    }
}
```
_Yes, I cam using singletons and it is something I might change in the future._

As can be seen, `Item` (which is a base class for any other inheritied items) contains some metadata as well as a `OnInteraction` which always adds the item into an inventory. This is something I might want to play with, in case I have "Items" such as Door, Gate, or similar. In that situation, though, it will be a better idea to simply not inherit the `Door.cs` class from Item, but still make it implement `IInteractable`, so I get the `HandleInteraction()` function.

Ultimately, we come to the `Key` class definition, which currently looks like this:
```cs
public class Key : Item, IInteractable
{
    public IInteractableController Controller;

    private void Start()
    {
        Controller = GetComponent<IInteractableController>();
        Controller.RegisterParentDependency(this);
    }

    public void HandleInteraction()
    {
        OnInteraction(this);
    }
}
```
It has a reference for IInteractableController (which is a component on the GameObject) and in the Start function it registers itself as the parent dependency (later used for the calling the Interact event).

This is pretty much the whole logic of the Items in the game, as of now. Some stuff I will surely want to add in the future is some concept of `Use()` function in the base `Item` class, which will handle a scenario when user has an item equipped and presses the Use [E] key. That will be used for unlocking door, chests and closets.

#### Player
One last small thing is the Player structure. I wanted to keep stuff simple (that's why it's a singleton again).

```cs
public class Player : MonoBehaviour
{
    public static Player Instance;
    
    public Character Character;
    public Inventory Inventory;
    public bool IsControllable = true;

    private void Start()
    {
        Instance = this;
    }

    public void ChangeControl(bool isControllable)
    {
        IsControllable = isControllable;
    }
    
    private void Update()
    {
        if (IsControllable)
        {
            Character.ControlLogic();
        }
    }
}
```
This takes care of seperating the logic from the character movement and other events which will be happening. This so far looks like a viable solution, but time will decide if it's good.

### Conclusion
I think that's all for now. I can mention work I've done on the UI part of the game, but there is not that much code, because there is not much logic just yet.

That's it for now. I would say it's a pretty good start of the project and the game is slowly becoming a (little playable) thing.

I will see you in a bit, to talk about more code I've written.