Home > front end >  Trying to Invoke method: CollisionHandler.NextScene couldn't be called
Trying to Invoke method: CollisionHandler.NextScene couldn't be called

Time:09-17

using UnityEngine;
using UnityEngine.SceneManagement;

public class CollisionHandler : MonoBehaviour
{

    [SerializeField] AudioClip success;
    [SerializeField] AudioClip crash;

    [SerializeField] ParticleSystem successParicle;
    [SerializeField] ParticleSystem crashParicle;

    AudioSource audioSource;
    float delayTime = 2f;

    bool isTransitioning = false;
    void Start()
    {
        audioSource = GetComponent<AudioSource>();
    }

    void OnCollisionEnter(Collision other)
    {
        if(isTransitioning)
        {
            return;
        }
        switch (other.gameObject.tag)
        {
            case "Friendly":
                Debug.Log("It's OK friend");
                break;
            case "Finish":
                SuccessSequence();
                break;
            default:
                CrashSequence();
                break;
        }

        void SuccessSequence()
        {
            isTransitioning = true;
            audioSource.Stop();
            successParicle.Play();
            audioSource.PlayOneShot(success);
            GetComponent<Shutle>().enabled = false;
            Invoke(nameof(NextScene), delayTime);
            //NextScene();
        }

        void CrashSequence()
        {
            isTransitioning = true;
            audioSource.Stop();
            crashParicle.Play();
            audioSource.PlayOneShot(crash);
            GetComponent<Shutle>().enabled = false;
            Invoke(nameof(ReloadScene), delayTime);
            //ReloadScene();
        }

        void ReloadScene() //dit gebruiken wij om respown met gebruik van scene reload funcite te gebruiken
        {
            int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
            SceneManager.LoadScene(currentSceneIndex);
        }

        void NextScene()
        {
            int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
            int nextSceneIndex = currentSceneIndex   1;
            if(nextSceneIndex == SceneManager.sceneCountInBuildSettings)
            {
                nextSceneIndex = 0;
            }
            SceneManager.LoadScene(nextSceneIndex);
        }
    }
}

i am building a basic game where a ship flies from one place to the other. when it crashes or succeeds it should do a couple of functionality before it re-spawns or move on the next level. so i need to invoke the functions. whenever i try to do that i get the following message: "Trying to Invoke method: CollisionHandler.NextScene couldn't be called."

CodePudding user response:

Any good reason why your methods are all nested under the OnCollisionEnter as locel functions? ;)

Unity's messaging system doesn't find local functions - since they literally only exist for this one method - but works only with class level methods.

It should rather be

priate void OnCollisionEnter(Collision other)
{
    if(isTransitioning)
    {
        return;
    }
    switch (other.gameObject.tag)
    {
        case "Friendly":
            Debug.Log("It's OK friend");
            break;
        case "Finish":
            SuccessSequence();
            break;
        default:
            CrashSequence();
            break;
    }
}

priate void SuccessSequence()
{
    isTransitioning = true;
    audioSource.Stop();
    successParicle.Play();
    audioSource.PlayOneShot(success);
    GetComponent<Shutle>().enabled = false;
    Invoke(nameof(NextScene), delayTime);
    //NextScene();
}

priate void CrashSequence()
{
    isTransitioning = true;
    audioSource.Stop();
    crashParicle.Play();
    audioSource.PlayOneShot(crash);
    GetComponent<Shutle>().enabled = false;
    Invoke(nameof(ReloadScene), delayTime);
    //ReloadScene();
}

priate void ReloadScene() //dit gebruiken wij om respown met gebruik van scene reload funcite te gebruiken
{
    int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
    SceneManager.LoadScene(currentSceneIndex);
}

priate void NextScene()
{
    int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
    int nextSceneIndex = currentSceneIndex   1;
    if(nextSceneIndex == SceneManager.sceneCountInBuildSettings)
    {
        nextSceneIndex = 0;
    }
    SceneManager.LoadScene(nextSceneIndex);
}

Alternatively to Invoke you could make it all routines which in my eyes is better to control, understand and maintain then "magic" Invoke calls ;)

priate IEnumerator OnCollisionEnter(Collision other)
{
    if(isTransitioning)
    {
        yield break;
    }

    switch (other.gameObject.tag)
    {
        case "Friendly":
            Debug.Log("It's OK friend");
            break;
        case "Finish":
            yield return SuccessSequence();
            break;
        default:
            yield return CrashSequence();
            break;
    }
}

priate IEnumerator SuccessSequence()
{
    isTransitioning = true;
    audioSource.Stop();
    successParicle.Play();
    audioSource.PlayOneShot(success);
    GetComponent<Shutle>().enabled = false;

    yield return new WaitForSeconds(delayTime);

    NextScene();
}

priate IEnumerator CrashSequence()
{
    isTransitioning = true;
    audioSource.Stop();
    crashParicle.Play();
    audioSource.PlayOneShot(crash);
    GetComponent<Shutle>().enabled = false;

    yield return new WaitForSeconds(delayTime);

    ReloadScene();
}

priate void ReloadScene()
{
    int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
    SceneManager.LoadScene(currentSceneIndex);
}

priate void NextScene()
{
    int currentSceneIndex = SceneManager.GetActiveScene().buildIndex;
    int nextSceneIndex = currentSceneIndex   1;
    if(nextSceneIndex == SceneManager.sceneCountInBuildSettings)
    {
        nextSceneIndex = 0;
    }
    SceneManager.LoadScene(nextSceneIndex);
}
  • Related