0
\$\begingroup\$

I have a class that is an event manager, which is notifying other scripts of touch events. However, the problem is that while the first public static event - SendInteraction - works, the second event, SendDrag, does not seem to be sending the position to the subscribed class. Instead, it just prints a null reference error.

"NullReferenceException: Object reference not set to an instance of an object TouchScreenManager.Update () (at ../TouchScreenManager.cs:47)"

I have tried making the TouchScreenManager class a Singleton and removing references to the events as static, and instead creating new instances in each subscribed class in Awake() but that doesn't work either. How can I fix it?


public class TouchScreenManager : MonoBehaviour
  { 
    #region events
    public delegate void SendInteraction(GameObject item);
    public static event SendInteraction MoveScene;

    public delegate void SendDrag(Vector2 position);
    public static event SendDrag Drag;
    #endregion

    private Vector3 startPos;
    private Vector2 startPosition;
    private WaitForFixedUpdate waitForFixedUpdate = new WaitForFixedUpdate();

    void Awake()
    {
        EnhancedTouchSupport.Enable();
        TouchSimulation.Enable();
    }

    void Update()
    {
        if (Touch.activeFingers.Count == 1)
        {
            var touch = Touch.activeTouches[0];

            if (touch.phase == TouchPhase.Began)
            {
                startPosition = touch.startScreenPosition;
                startPos = Camera.main.ScreenToWorldPoint(touch.screenPosition);
                DragAndDrop(touch);
                CheckForInteraction(touch);
            }

            else if (touch.phase == TouchPhase.Moved)
            {
                Debug.Log("from the touch screen manager:" + touch.screenPosition);
                Drag(touch.screenPosition); // PRINTS FINE HERE
            }
        }
    }

This script is subscribed to this event.

public class LineGenerator : MonoBehaviour
{
    public GameObject linePrefab;
    Line activeLine;
    Vector2 capturedScreenPos;

    private void OnEnable()
    {
        TouchScreenManager.Drag += DrawLine;
    }

    private void OnDisable()
    {
        TouchScreenManager.Drag -= CompleteLine;
        
    }

    void DrawLine(Vector2 position)
    {
        GameObject newLine = Instantiate(linePrefab);
        activeLine = newLine.GetComponent<Line>();
        capturedScreenPos = position;
        Debug.Log("from the line generator: " + position); // NULL REF HERE
    }
}
````
\$\endgroup\$
3
  • \$\begingroup\$ Which line is 47 in TouchScreenManager? The place where you've commented "NULL REF HERE" does not match the error message you've shown us. \$\endgroup\$
    – DMGregory
    Oct 26, 2022 at 20:02
  • \$\begingroup\$ Line 47 in TouchScreenManager is - Drag(touch.screenPosition); \$\endgroup\$ Oct 27, 2022 at 8:15
  • \$\begingroup\$ The only way for that to throw this exception is if no listeners have been added to the event. A usual practice is to check that the event is non-null (has at least one listener) before invoking it. Have you tried that? \$\endgroup\$
    – DMGregory
    Oct 27, 2022 at 9:28

1 Answer 1

1
\$\begingroup\$

I think that you're mistaken about where the problem is occurring... I believe it's in the TouchScreenManager, after the log statement, while it's trying to call the event. I created a contrived example of this and I found that if I called the event before the other class was subscribed to it, I got the error you mentioned, at the call to Drag():

"Object reference not set to an instance of an object."

So I think you need to either wait for the other Component to get initialized, or do a null check on the event if those can be safely ignored.

Created in LINQPad:

void Main()
{
    var t = new TouchScreenManager();
    
    // This will throw because the other class isn't subbed yet.
    // Enabling the null check in the TouchScreenManager will essentially ignore the first call to the event, but it wont throw.
    t.Update();
    
    var l = new LineGenerator();
    
    // This should always work
    t.Update();
}

public class TouchScreenManager
{
    #region events
    public delegate void SendInteraction(Object item);
    public static event SendInteraction MoveScene;

    public delegate void SendDrag(string position);
    public static event SendDrag Drag;
    #endregion

    public void Update()
    {
        var newPosition = "My new position";
        Debug.WriteLine("from the touch screen manager:" + newPosition);
        
        // Enable the below line to avoid the exception
        // if (Drag != null)
        Drag(newPosition);
    }
}

public class LineGenerator
{
    public LineGenerator()
    {
        TouchScreenManager.Drag += DrawLine;
    }

    void DrawLine(string position)
    {
        Debug.WriteLine("from the line generator: " + position); // NULL REF HERE
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ Yup, that was it! Thank you. \$\endgroup\$ Oct 27, 2022 at 17:44

You must log in to answer this question.

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