2
\$\begingroup\$

I've been using the new input system to simulate touch in my game, it works perfectly but only with the input manager(which is a singleton for the ease of use), when I add the PlayerMover script it returns me nullReference. The error appears in two scripts at the same time. The input manager is in the scene.

enter image description here

InputManager script(with default execution order of -1):

public class InputManager : Singleton<InputManager>
{
    private PlayerInput _playerInput;
    public Action<Vector2> _OnScreenTouched;
    private void Awake()
    {
        _playerInput = new PlayerInput();
    }
    private void OnEnable()
    {
        _playerInput.Enable();
    }
    private void OnDisable()
    {
        _playerInput.Disable();
    }
    private void Start()
    {
        _playerInput.Player.Turn.performed += ctx => ScreenTouched(ctx);

    }
    private void ScreenTouched(InputAction.CallbackContext context)
    {
        _OnScreenTouched?.Invoke(_playerInput.Player.Turn.ReadValue<Vector2>());
        
    }
}

Singleton class:

public class Singleton<T> : MonoBehaviour where T : Component
{
    private static T _instance;
    public static T Instance
    {
        get
        {
            if (_instance == null)
            {
                var objs = FindObjectOfType(typeof(T)) as T[];
                if (objs.Length > 0)
                    _instance = objs[0];
                if (objs.Length > 1)
                    Debug.LogError("There is more than one" + typeof(T).Name + "in the scene.");
                if(_instance == null)
                {
                    GameObject obj = new GameObject();
                    obj.hideFlags = HideFlags.HideAndDontSave;
                    _instance = obj.AddComponent<T>();
                }
            }
            return _instance;
        }
    }
}
public class SingletonPersistent<T> : MonoBehaviour where T : Component
{
    public static T Instance { get; private set; }
    public virtual void Awake()
    {
        if (Instance == null)
        {
            Instance = this as T;
            DontDestroyOnLoad(this);
        }
        else
        {
            Destroy(gameObject);
        }

    }
}

PlayerMovement script:

public class PlayerMovement : MonoBehaviour, IMovable
{
    [SerializeField] private float _movementAmmount;
    private InputManager _inputManager;
    private Camera _camera;

    private void Awake()
    {
        _inputManager = InputManager.Instance;
        _camera = Camera.main;
    }
    private void OnEnable()
    {
        _inputManager._OnScreenTouched += Move;
    }
    private void OnDisable()
    {
        _inputManager._OnScreenTouched -= Move;
    }

    public void Move(Vector2 screenPosition)
    {
        if (screenPosition.x <= Screen.width / 2)
        {
            transform.position -= new Vector3(_movementAmmount,0,_camera.nearClipPlane);
        }
        if (screenPosition.x > Screen.width / 2)
        {
            transform.position += new Vector3(_movementAmmount, 0, _camera.nearClipPlane);
        }
    }
}

Interface for PlayerMovement:

public interface IMovable
{
    void Move(Vector2 screenPosition);
}
\$\endgroup\$
4
  • 3
    \$\begingroup\$ FindObjectOfType returns not an array, thats FindObjectsOfType \$\endgroup\$
    – Zibelas
    Dec 3, 2022 at 9:42
  • \$\begingroup\$ I‘ll test it out when I get home. Thank you very much. \$\endgroup\$
    – koogel
    Dec 3, 2022 at 9:44
  • \$\begingroup\$ And for your Persistent Singleton, usually you are as well checking if the instance is not the current one: something like if (Instance != null && Instance != this) \$\endgroup\$
    – Zibelas
    Dec 3, 2022 at 9:49
  • \$\begingroup\$ @Zibelas since PersistentSingleton.Instance has only a private setter, there's only one line that could set it to be equal to this, which occurs after the null check. Awake() is called only once per instance, so there's no need to check that this variable was not previously set by the same instance. (At least, without some very unusual reflection shenanigans being pulled to bypass the private restrictions) \$\endgroup\$
    – DMGregory
    Dec 3, 2022 at 13:47

1 Answer 1

1
\$\begingroup\$

It appears I made a typo, thank you @Zibelas for pointing that out.

Instead of using FindObjectsOfType I used FindObjectOfType.

FindObjectsOfType returned the array, while FindObjectOfType returned a single object. Trying to cast that single object T to an array with as T[] caused objs to be set to null.

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .