#Interaction/Controllable system

1 messages · Page 1 of 1 (latest)

slender elbow
#

Hi guys, recently I have created an Interactable system. Currently I use two interfaces IInteractable and IControllable, to do most of my interaction logic. ```c#
public interface IControllable
{
void SubscribeToInput(InputSystem_Actions inputActions);
void UnsubscribeToInput();
}

public interface IInteractable
{
void Interact(IInteractor interactor);
}```
The IInteractable class is detected on objects via raycast by my PlayerInteractor monobehaviour, and calls Interact() on it, interactables with IControllable subscribe to input through the IInteractable Interact() event (example, player interacts with steering wheel, now they control the car). IInteractable takes IInteractor, aka the player controller, and calls the playher controllers subscribe/unsubscribe methods.

public void Interact(IInteractor interactor)
{
    this.interactor = interactor;
    interactor.controller.SubscribeControllable(this);
}

public void SubscribeToInput(InputSystem_Actions inputActions)
{
    _inputActions = inputActions;

    _inputActions.Player.Disable();
    _inputActions.ShipHelm.Enable();

    _inputActions.ShipHelm.Move.performed += OnMove;
    _inputActions.ShipHelm.Move.canceled += OnMove;
    _inputActions.ShipHelm.Look.performed += OnLook;
    _inputActions.ShipHelm.Look.canceled += OnLook;

    _inputActions.ShipHelm.Exit.started += OnExit;
}

public void UnsubscribeToInput()
{
    if (_inputActions == null)
        return;

    _inputActions.ShipHelm.Move.performed -= OnMove;
    _inputActions.ShipHelm.Move.canceled -= OnMove;
    _inputActions.ShipHelm.Look.performed -= OnLook;
    _inputActions.ShipHelm.Look.canceled -= OnLook;

    _inputActions.ShipHelm.Exit.started -= OnExit;
}```
This is my first issue I feel, that interactable should not be in charge of what is enabled and disabled on the input system, as they probably shouldn't have authority over it (separation of concerns etc).
#

The player controller currently has authority over subscribing and unsubscribing input to IControllables and does so like: ```c#
public class PlayerController : NetworkBehaviour, IInteractor
{
private InputSystem_Actions inputActions;
public PlayerController controller { get { return this; } }

private List<IControllable> currentControllables;

public override void OnNetworkSpawn() {}

public void SubscribeControllable(IControllable newControllable)
{
    if (currentControllables.Contains(newControllable))
        return;

    currentControllables.Add(newControllable);
    newControllable.SubscribeToInput(inputActions);
}

public void UnsubscribeControllable(IControllable oldControllable)
{
    if(!currentControllables.Contains(oldControllable))
        return;

    oldControllable.UnsubscribeToInput();
    currentControllables.Remove(oldControllable);
}

}

#

I feel this design works pretty well, and is modular as I can also reuse IControllable for anything which requires player input, such as movement and camera movement.. But I am unsure if this is the right way to go about it. I have an unhealthy obsession with making everything perfect, so I often ask AI tools about the quality of my code, which they always over analyse and eventually confuse me.