Попытка вызвать метод: CollisionHandler.NextScene не удалось вызвать

#c# #unity3d

Вопрос:

 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);
        }
    }
}
 

я создаю базовую игру, в которой корабль летит из одного места в другое. когда он выходит из строя или преуспевает, он должен выполнить несколько функций, прежде чем он снова появится или перейдет на следующий уровень. поэтому мне нужно вызвать функции. всякий раз, когда я пытаюсь это сделать, я получаю следующее сообщение:
«Попытка вызвать метод: CollisionHandler.NextScene не удалось вызвать».

Ответ №1:

Есть ли веская причина, по которой все ваши методы вложены в OnCollisionEnter функции as locel? 😉

Система обмена сообщениями Unity не находит локальных функций — поскольку они буквально существуют только для этого одного метода — но работает только с методами уровня класса.

Это скорее должно быть

 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);
}
 

В качестве альтернативы Invoke вы могли бы сделать все это рутинами, которые, на мой взгляд, лучше контролировать, понимать и поддерживать, чем «волшебные» Invoke вызовы 😉

 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);
}
 

Комментарии:

1. я даже не заметил…. Черт возьми, это так неловко, лол. Спасибо

2. знаете ли вы, почему не разыгрывается часть успеха? этот все еще не работает

3. @HayyanMotsu предполагаю, что вы использовали второй подход с сопрограммами: Потому что я не заметил, что последовательность успеха и последовательность сбоев на самом деле воспроизводили разные частицы и звуки, поэтому вы не можете объединить их так легко, как я думал ^^