Следующая сцена не загружается - PullRequest
1 голос
/ 08 мая 2019

Моя проблема в том, что когда все враги убиты, загружаемая сцена не загружается. Я добавил сцену в настройку Build (она имеет индекс 3), но она все еще не загружается. Сценарий, который я создал, прикреплен к пустому объекту, а не напрямую к спрайту (это нормально?). Может кто-нибудь сказать мне, почему сцена не загружается? Спасибо.

Это изображение для того, чтобы показать вам пустой инспектор объектов EnemySpawner enter image description here

EnemySpawner Script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class EnemySpawner : MonoBehaviour {

[SerializeField] GameObject EnemyPreFab;
[SerializeField] int MaxEnemies = 30;
[SerializeField] float EnemySpawnTime = 1.00001f;
[SerializeField] GameObject FirstWaypoint;
int CurrentNumOfEnemies = 0;
public LevelManager myLevelManager;
public int maximumnumberofhits = 0;
int timesEnemyHit;



IEnumerator SpawningEnemies()
{
    while(CurrentNumOfEnemies <= MaxEnemies)
    {
        GameObject Enemy = Instantiate(EnemyPreFab, this.transform.position, Quaternion.identity);
        CurrentNumOfEnemies++;
        yield return new WaitForSeconds(EnemySpawnTime);
    }
}

void Start()
{
    StartCoroutine(SpawningEnemies());
    timesEnemyHit = 0;
    if (this.gameObject.tag == "EnemyHit")
    {
        CurrentNumOfEnemies++;
    }


}

void OnCollisionEnter2D()
{
    timesEnemyHit++;
    if (timesEnemyHit == maximumnumberofhits)
    {
        CurrentNumOfEnemies--;
        Destroy(this.gameObject);
    }

    if (CurrentNumOfEnemies == 0)
    {
        myLevelManager.LoadLevel("NextLevelMenu");
        Debug.Log("LevelLoaded");
    }
   }

}

Скрипт LevelManger:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class LevelManager : MonoBehaviour {
 public void LoadLevel(string name)
 {
    print("Level loading requested for" + name);
    SceneManager.LoadScene(name);
  }
}

EnemyShooting Script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyShooting : MonoBehaviour {


[SerializeField] float EnemyLaserSpeed = 10f;
[SerializeField] float EnemyLaserFireTime;
[SerializeField] GameObject LaserBulletEnemyPreFab;
[SerializeField] int MaxNumberOfHits = 1;
int CurrentNumberOfHits = 0;
Coroutine FireCoroutine;

void OnTriggerEnter2D(Collider2D collider)
{
    if(collider.gameObject.tag == "PlayerLaser")
    {
        if(CurrentNumberOfHits < MaxNumberOfHits)
        {
            CurrentNumberOfHits++;
            Destroy(collider.gameObject);
            Score.ScoreValue += 2;//The user will be rewarded 1 point
        }
    }
}



void DestroyEnemy()
{
    if(CurrentNumberOfHits >= MaxNumberOfHits)
    {
        Destroy(gameObject);
    }
}

private void Fire()
{
    FireCoroutine = StartCoroutine(ShootContinuously());
}

void BecomeVisible()
{
    Fire();
}

IEnumerator ShootContinuously()
{
    while (true)
    {
        GameObject LaserBulletEnemy = Instantiate(LaserBulletEnemyPreFab, this.transform.position, Quaternion.identity) as GameObject;
        LaserBulletEnemy.GetComponent<Rigidbody2D>().velocity = new Vector2(0, EnemyLaserSpeed);
        EnemyLaserFireTime = Random.Range(0.5f, 0.9f);
        yield return new WaitForSeconds(EnemyLaserFireTime);
    }
}
// Use this for initialization
void Start () {

    BecomeVisible();
}

// Update is called once per frame
void Update () {

    DestroyEnemy();

   }
}

Сценарий EnemyPathing:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyPathing : MonoBehaviour {
[SerializeField] List<Transform> WayPoints;
[SerializeField] float EnemyMovingSpeed = 5f;
int WayPointIndex = 0; 

void EnemyMoving()
{
    if (WayPointIndex <= WayPoints.Count - 1)
    {
        var TargetedPosition = WayPoints[WayPointIndex].transform.position; //The position of where the enemy needs to go
        TargetedPosition.z = 0f;
        var MoveThisFrame = EnemyMovingSpeed * Time.deltaTime;
        transform.position = Vector2.MoveTowards(this.transform.position, TargetedPosition, MoveThisFrame);

        if(transform.position == TargetedPosition)
        {
            WayPointIndex++;
        }
    }

    else
    {
        Destroy(gameObject);
    }
}
// Use this for initialization
void Start () {

    transform.position = WayPoints[WayPointIndex].transform.position;

}

// Update is called once per frame
void Update () {

    EnemyMoving();

 }
}

Ответы [ 2 ]

2 голосов
/ 08 мая 2019

Проблема

Вы проверяете наличие столкновений на SPAWNER;когда кто-то попадает в Спавнер, он начинает отсчитывать врагов.Но у Spawner нет скриншотов, поэтому его нельзя ударить.Код изменения сцены никогда не может быть вызван.

Таким образом, игра, основанная на коде, выглядит следующим образом:

  1. Spawn X врагов,
  2. Hit SpawnerX раз,
  3. (Удалено: уничтожить Спавнера)
  4. Изменить сцену.

Я предполагаю, что это концептуально неверно, и вы действительно хотите проверить столкновенияна порожденных врагах, которые затем подсчитывают количество уничтоженных врагов и изменяют сцену, когда они все мертвы.


Решение

Концептуально, что вы хотите:

  1. Spawn X врагов
  2. Подсчитать переменную для каждого врага
  3. При смерти врага отсчитать
  4. Когда 0, сменить сцену

Так, как мы это закодируем?

Ну, каждому врагу нужна ссылка на объект, который содержит счет.Вы можете сделать это несколькими способами, когда я лично делаю это, у меня обычно есть только один спавнер, который отвечает за всех, поэтому я делаю это синглтоном, на который можно ссылаться откуда угодно:

EnemySpawner

public class EnemySpawner : MonoBehaviour 
{
    public static Spawner Instance = null;
    int CurrentNumOfEnemies = 0;
    // ... etc

    void Start() 
    {
        if (Instance == null)
             Instance = this;

        // Spawn enemies like you do already, CurrentNumOfEnemies++ for every spawned
    }

    public OnEnemyDeath() {
        CurrentNumOfEnemies--;
        if (CurrentNumOfEnemies < 1) 
        {
            // You killed everyone, change scene: 
            LevelManager.LoadLevel("Your Level");
        }
    }

}

Вражеский скрипт (я не знаю, как выглядит ваш текущий код, но вот минимальное решение, основанное на том, как я ДУМАЮ ваш код выглядит):

void OnDestroy() 
{
    // This will run automatically when you run Destroy() on this gameObject
    EnemySpawner.Instance.OnEnemyDeath(); // Tell the EnemySpawner that someone died
}

Этобудет работать только в том случае, если у вас есть только ОДИН спавнер.Если у вас их несколько, вам нужно будет отправить ссылку на экземпляр его создателя каждому появившемуся противнику.Я могу показать вам, как это сделать, если хотите.


Бонусное содержимое

LevelManager не обязательно должен быть в GameObject, вместо этого он может быть статическим:

  1. Удалите скрипт LevelManager из любого GameObject
  2. Измените свой код LevelManager на:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public static class LevelManager 
{
    public static void LoadLevel(string name)
    {
        Debug.Log("Level loading requested for" + name);
        SceneManager.LoadScene(name);
    }
}

Теперь вы можете использовать его из ЛЮБОГО, без необходимостиинициализировать ссылку на любой скрипт или GameObject:

LevelManager.LoadLevel("My Level");
2 голосов
/ 08 мая 2019

myLevelManager.LoadLevel("NextLevelMenu"); никогда не выполняется, потому что вы уничтожаете объект в if-тесте выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...