#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 предполагаю, что вы использовали второй подход с сопрограммами: Потому что я не заметил, что последовательность успеха и последовательность сбоев на самом деле воспроизводили разные частицы и звуки, поэтому вы не можете объединить их так легко, как я думал ^^