Hello, fellas!
Trying to solve my problem for more than an hour, looking the internet and testing stuff, I am finally asking for help!
Initial situation, using Unity 2019.3.0f6 + JB Rider (dunno if it’s related but hey, computer stuff so, who knows ¯\ (ツ) /¯ )
The main problem is that, somehow, can’t use the FindObjectOfType();
Rider say “nope”, red skwigli (?) line under it.
Ok, let’s then give it a try by myself, it’s a good challenge to explore anotther path :
If the health goes down to 0, Die() is called. Die() then call GameOver() which hold a Coroutine, EndGame() which wait for x seconds and then SceneManager.LoadScene(2) is executed.
This is supposed to work, considering that everything happen BEFORE the destruction of the GameObject.
Problem, it is not : even tho the player get destroyed, no scene is loaded afterward.
Digging a bit, learning how to debug, I found out that when I set a breakpoint around Die() well, the result is … _firingCoroutine being null
AND I DON’T GET IT.
Why is this happening now ? Is this related to the Loading process created by the Coroutine ?
The mystery is tearing me appart
Player.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Player : MonoBehaviour
{
private Camera _gameCamera;
[SerializeField] private float moveSpeed = 10.0f;
[SerializeField] private float padding = 0.5f;
[SerializeField] private int health = 200;
[SerializeField] private GameObject laserPrefab;
[SerializeField] private float projectileSpeed = 10f;
[SerializeField] private float projectileFiringPeriod = 0.01f;
[SerializeField] private AudioClip deathSfx;
[SerializeField] private AudioClip shootSoundSfx;
[SerializeField] [Range(0,1)] private float deathSoundVolume;
[SerializeField] [Range(0,1)] private float shootSoundVolume;
private Coroutine _firingCoroutine;
[SerializeField] private float delayInSeconds = 2f;
private float _xMin;
private float _xMax;
private float _yMin;
private float _yMax;
private void Start()
{
_gameCamera = Camera.main;
SetUpMoveBoundaries();
}
private void Update()
{
Move();
Fire();
}
private void OnTriggerEnter2D(Collider2D other)
{
DamageDealer damageDealer = other.gameObject.GetComponent<DamageDealer>();
if (!damageDealer)
{
return;
}
ProcessHit(damageDealer);
}
private void ProcessHit(DamageDealer damageDealer)
{
health -= damageDealer.GetDamage();
damageDealer.Hit();
if (health <= 0)
{
Die();
}
}
private void Die()
{
GameOver();
if (_gameCamera == null) return;
AudioSource.PlayClipAtPoint(deathSfx, _gameCamera.transform.position, deathSoundVolume);
Destroy(gameObject);
}
private void GameOver()
{
StartCoroutine(EndGame());
}
private IEnumerator EndGame()
{
yield return new WaitForSeconds(delayInSeconds);
SceneManager.LoadScene(2);
}
private void Fire()
{
if (Input.GetButtonDown("Fire1"))
{
_firingCoroutine = StartCoroutine(FireContinuously());
}
else if (Input.GetButtonUp("Fire1"))
{
StopCoroutine(_firingCoroutine);
}
}
private void Move()
{
// Horizontal movement (position + input on X axis)
var deltaX = Input.GetAxis("Horizontal") * Time.deltaTime * moveSpeed;
var newXPos = Mathf.Clamp(transform.position.x + deltaX, _xMin, _xMax);
// Vertical movement (position + input on Y axis)
var deltaY = Input.GetAxis("Vertical") * Time.deltaTime * moveSpeed;
var newYPos = Mathf.Clamp(transform.position.y + deltaY, _yMin, _yMax);
transform.position = new Vector2(newXPos, newYPos);
}
private void SetUpMoveBoundaries()
{
_xMin = _gameCamera.ViewportToWorldPoint(new Vector3(0, 0, 0)).x + padding;
_xMax = _gameCamera.ViewportToWorldPoint(new Vector3(1, 0, 0)).x - padding;
_yMin = _gameCamera.ViewportToWorldPoint(new Vector3(0, 0, 0)).y + padding;
_yMax = _gameCamera.ViewportToWorldPoint(new Vector3(0, 1, 0)).y - padding;
}
private IEnumerator FireContinuously()
{
while (true)
{
GameObject laser = Instantiate(laserPrefab,
transform.position + new Vector3(0, 0.57f, 0),
Quaternion.identity) as GameObject;
laser.GetComponent<Rigidbody2D>().velocity = new Vector2(0, projectileSpeed);
AudioSource.PlayClipAtPoint(shootSoundSfx, _gameCamera.transform.position, shootSoundVolume);
yield return new WaitForSeconds(projectileFiringPeriod);
}
}
}