Why is my Input Class not deleted when changing scenes ?

public class Navigation : MonoBehaviour
{

    private PlayerInput pI;
    public int i;
    public GameObject[] options;

    // Start is called before the first frame update
    private void Awake()
    {
        pI = new PlayerInput();
        pI.UI.Enable();
        pI.UI.Confirm.performed += enter;
        pI.UI.Return.performed += retour;
        pI.UI.SlideLeft.performed += slideLeft;
        pI.UI.SlideRight.performed += slideRight;

    }

PlayerInput is a generated C# class from the new Input System and Navigation is just a script called on a specific scene. It works well but I noticed that when loading a new scene after this one, these functions are still launched although the Navigation script is not in the new Scene.

        pI.UI.Confirm.performed += enter;
        pI.UI.Return.performed += retour;
        pI.UI.SlideLeft.performed += slideLeft;
        pI.UI.SlideRight.performed += slideRight;

I tried to access the GameObject inside one of those functions and got an error (which makes sense because the script is not here) but I can't get why the functions are still running...
I searched a lot on the forums but I couldn't find anything, so if you guys have any ideas what I could be missing, let me now !
Sorry for the inconvenience

Up ! Any help please ?

How do you know they are “still running”? Don’t guess and just go by behavior, find out for sure. I would suggest proper debugging, perhaps with Debug.Log to confirm, and consider using the second parameter to this method to see which object is calling it, in case you have this script attached elsewhere https://discussions.unity.com/t/748729/14

Hello, thank you for answering !
I just created a new project and put a script (generated C# class from the new Input System) on an Object in the first Scene.

using UnityEngine;
using UnityEngine.InputSystem;

public class Hello : MonoBehaviour
{
    private InputTest input;
    private void Awake()
    {
        input = new InputTest();
        input.Enable();
        input.UI.confirm.performed += testT;
    }

    public void testT(InputAction.CallbackContext context)
    {
        if (context.performed)
        {
            Debug.Log("still running", this);
        }
    }
}

I also created a second scene with just a cube (no scripts attached).
When loading the second scene (async or not), the functions from the script are still launched

I am using the Input System 1.3.0 - January 05, 2022

So I I think it’s not a bug and maybe that’s how it’s supposed to work but then is there a way to disable these functions by entering a new scene?

Thank you in advance !

I only see one scene in your (small) screenshot and one Debug.Log statement? Where are you changing scenes?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class LevelLoader : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(LoadAsynchronously("A"));
    }

    // Update is called once per frame
    IEnumerator LoadAsynchronously(string scene)
    {
        yield return new WaitForSecondsRealtime(0.5f);
        AsyncOperation operation = SceneManager.LoadSceneAsync(scene);
    }
}

This is my script for changing scene, it’s just a simple script set on a GameObject in the firstscene.
I don’t know what I am supposed to show you, I just created a simple project with one object and 2 scripts.
But is it how it’s supposed to work or is it a bug ?

I think the “bug” comes from this part showed earlier:
input.UI.confirm.performed += testT;
Could it be possible that it always launch the “testT” function even when the scene changed ?

You should really be calling Dispose on that PlayerInput instance when leaving the first scene, assuming it's one that's generated from the Input System editor. Instances of input assets created this way aren't attached to the scene in any way and will hang around in memory across scene changes. Another issues, although related to the first, is that it's good practice to remove event handlers when you're done with them. If this is the behaviour that you want, then when changing scenes, you should do something like

        pI.UI.Confirm.performed -= enter;
        pI.UI.Return.performed -= retour;
        pI.UI.SlideLeft.performed -= slideLeft;
        pI.UI.SlideRight.performed -= slideRight;

It wouldn't be completely necessary if the instance of the PlayerInput class is properly destroyed, but it's a good habit to get into regardless.

1 Like

Thank you for your help!
It worked:)