Unity 2D: Checkpoint generation on checkpoint reached not working properly

时间:2017-08-05 10:38:44

标签: c# unity2d

Recently I've been having some problems with my Unity project. I've been trying to generate checkpoints every 'x' units, however, for some reason, the first two checkpoints spawn successfully, but after that, nothing happens.

Here is my code in CheckpointGeneration.cs:

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

public class CheckpointGeneration : MonoBehaviour {

    public GameObject checkpointPrefab;

    int gap = 5;
    List<GameObject> previousCheckpointList;

    private void Start()
    {
        Vector3 targetPos = new Vector3(0, -2.35f);
        Instantiate(checkpointPrefab, targetPos, 
            checkpointPrefab.transform.rotation);
    }

    private void Update()
    {
        if (CheckpointController.checkpointsReached != previousCheckpointList && CheckpointController.lastCheckpointReached != null)
        {
            previousCheckpointList = CheckpointController.checkpointsReached;

            Vector3 targetPos = new Vector3(CheckpointController.lastCheckpointReached.transform.position.x + gap, CheckpointController.lastCheckpointReached.transform.position.y);
            Instantiate(checkpointPrefab, targetPos, checkpointPrefab.transform.rotation);
        }
    }
}

This is the code for CheckpointController.cs:

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

public class CheckpointController : MonoBehaviour {

    public static List<GameObject> checkpointsReached = new List<GameObject>();
    public static GameObject lastCheckpointReached;

    GameObject player;

    private void Awake()
    {
        player = GameObject.FindGameObjectWithTag("Player");
    }

private void Update()
{
        if (checkpointsReached.Count > 0)
        {
            lastCheckpointReached = checkpointsReached[checkpointsReached.Count - 1];
        }
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.tag == "Player")
        {
            checkpointsReached.Add(gameObject);
            GetComponent<SpriteRenderer>().color = new Color(0, 0.86f, 0.29f);
        }
        Debug.Log("Checkpoint Reached!");
    }

    public void RespawnAtCheckpoint()
    {
        if (lastCheckpointReached != null)
        {
            player.transform.parent.position = lastCheckpointReached.transform.position;
            player.GetComponent<PlayerManager>().isDead = false;
            Camera.main.transform.position = GameObject.FindGameObjectWithTag("CameraFollow").transform.position;
            Debug.Log("Respawning...");
        } else
        {

GameObject.FindGameObjectWithTag("GameController").GetComponent<ReloadLevel>().Reload();
        }
    }

}

Any answers would be much appreciated! Leave a comment if you need any more information, and I will edit the question to provide it.

1 个答案:

答案 0 :(得分:0)

I made changes to your code so you get idea of little cleaner code. If you do not understand something from code ask me. I also made another class for global variables. Consider using it since finding gameobjects by name is not good.

public class GlobalClass : MonoBehaviour
{
    //static objects are not seen in inspector so we will asign player to public gameobject and inside script we transfer it to static gameobject so now we can get player gameobject with GlobalClass.player
    public static GameObject player;
    public GameObject _player;

    //With this you can set all other gameobjects like your GameController or something like that

    private void Start()
    {
        player = _player;
    }
}

public class CheckpointGeneration : MonoBehaviour
{
    public GameObject checkpointPrefab;

    public float gap = 5.0f;
    public static int spawnedCheckpoints = 0; //You can alse set it as bool but with this you can maybe make to have 2 or more checkpoints

    private static Vector2 lastCheckpointPos = new Vector2(0, -2.35f);

    private void Start()
    {
        Instantiate(checkpointPrefab, lastCheckpointPos, checkpointPrefab.transform.rotation);
        spawnedCheckpoints++;
    }

    private void Update()
    {
        if (spawnedCheckpoints < 1)
        {
            SpawnCheckpoint();
        }
    }

    public static void RespawnAtCheckpoint()
    {
        if (CheckpointGeneration.spawnedCheckpoints > 0)
        {
            GlobalClass.player.transform.parent.position = CheckpointGeneration.lastCheckpointPos;
            GlobalClass.player.GetComponent<PlayerManager>().isDead = false;
            Camera.main.transform.position = GameObject.FindGameObjectWithTag("CameraFollow").transform.position;
            Debug.Log("Respawning...");
        } else
        {

            GameObject.FindGameObjectWithTag("GameController").GetComponent<ReloadLevel>().Reload();
        }
    } //Call this method when player die

    private static void SpawnCheckpoint()
    {
        Vector2 newCheckpointPos = new Vector2(lastCheckpointPos.x + gap, lastCheckpointPos.y);
        Instantiate(checkpointPrefab, newCheckpointPos, checkpointPrefab.transform.rotation); //Consider using Quaternion.identity
        lastCheckpointPos = newCheckpointPos;
        spawnedCheckpoints++;
    }
}

public class CheckpointController : MonoBehaviour
{
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.tag == "Player")
        {
            CheckpointGeneration.spawnedCheckpoints--; //with this we sent message to your CheckpointGeneration script that this checkpoint is reached
            Debug.Log("Checkpoint Reached!");
            Destroy(gameObject);//When checkpoint is reached we destroy it and will spawn new one
        }
    }
}