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