Search Unity

Player keeps cloning when they die, how do I prevent this?

Discussion in 'Scripting' started by FoxyWithTheMoxy, Jan 16, 2021.

  1. FoxyWithTheMoxy

    FoxyWithTheMoxy

    Joined:
    Jan 16, 2021
    Posts:
    5
    So for context, I'm making a Side scroller game and I've been watching tutorials on how to do so to get a better understanding of Unity. I watched a tutorial on a death function for Unity and after writing the code, the player character keeps cloning every time they die and respawn even though this is not what I want.

    Tutorial I was watching: Player Death & Respawn | 2D Platformer in Unity #9 | 2D Game Dev Tutorial - YouTube

    Here are the scripts I have at the moment:
    LevelManager
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using Cinemachine;

    public class LevelManager : MonoBehaviour
    {
    public static LevelManager instance;

    public Transform respawnPoint;
    public GameObject playerPrefab;

    public CinemachineVirtualCameraBase cam;

    private void Awake() {
    instance = this;
    }

    public void Respawn () {
    GameObject player = Instantiate(playerPrefab, respawnPoint.position, Quaternion.identity);
    cam.Follow = player.transform;
    }
    }

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

    public class PlayerDeath : MonoBehaviour {
    private void OnCollisionEnter2D(Collision2D collision) {
    if (collision.gameObject.CompareTag("Hazard")) {
    Destroy(gameObject);
    LevelManager.instance.Respawn();
    }
    }
    }

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

    public class PlayerMovement : MonoBehaviour {
    public float movementSpeed;
    public Rigidbody2D rb;

    public float jumpForce = 20f;
    public Transform feet;
    public LayerMask groundLayers;

    float mx;

    private void Update() {
    mx = Input.GetAxisRaw("Horizontal");

    if (Input.GetButtonDown("Jump") && IsGrounded()) {
    Jump();
    }
    }

    private void FixedUpdate() {
    Vector2 movement = new Vector2(mx * movementSpeed, rb.velocity.y);

    rb.velocity = movement;
    }

    void Jump() {
    Vector2 movement = new Vector2(rb.velocity.x, jumpForce);

    rb.velocity = movement;
    }

    public bool IsGrounded() {
    Collider2D groundCheck = Physics2D.OverlapCircle(feet.position, 0.5f, groundLayers);

    if (groundCheck != null) {
    return true;
    }

    return false;
    }
    }

    I tried creating a new Prefab to see if that works but the problem continued persisting, any help?
    (Also the code was done in Eclipse)
     
  2. mikeohc

    mikeohc

    Joined:
    Jul 1, 2020
    Posts:
    215
    You can perhaps just teleport the player to the respawn point instead of instantiating it. Always destroying the player can take memory.

    Maybe try :
    Code (CSharp):
    1. if (collision.gameObject.CompareTag("Hazard")) {
    2. Respawn();
    3. }
    4.  
    5. void Respawn() {
    6.     transform.position = respawnPoint.position;
    7. }
    And remove the respawn from LevelManager.

    my advice:
    1. instantiate ONCE at start of level.
    2. respawn just means teleport player to location
    3. create a list/array of respawnPoints for future checkpoints
    4. now you can teleport to any checkpoints if you add more condition - e.g. if (collide2ndCP) respawnPoint = RP[2];
     
  3. FoxyWithTheMoxy

    FoxyWithTheMoxy

    Joined:
    Jan 16, 2021
    Posts:
    5
    Tried the above code but it didn't work, got an error saying
    "Assets\Scripts\PlayerDeath.cs(12,25): error CS0103: The name 'respawnPoint' does not exist in the current context"

    With the following code:

    Level Manager
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using Cinemachine;

    public class LevelManager : MonoBehaviour
    {
    public static LevelManager instance;

    public Transform respawnPoint;
    public GameObject playerPrefab;

    public CinemachineVirtualCameraBase cam;

    private void Awake() {
    instance = this;
    }
    }

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

    public class PlayerDeath : MonoBehaviour {
    private void OnCollisionEnter2D(Collision2D collision) {
    if (collision.gameObject.CompareTag("Hazard")) {
    Respawn();
    }

    void Respawn() {
    transform.position = respawnPoint.position;
    }
    }
    }

    How does one instantiate it once at the start of the level? (Going by the original code).
     
  4. mikeohc

    mikeohc

    Joined:
    Jul 1, 2020
    Posts:
    215
    Try to understand the code before using it, what I wrote was a guide, and wouldn't work if you just copy and pasted into your project.

    but try this, to instantiate at the start simply do:
    Code (CSharp):
    1. //LevelManager script
    2. GameObject playerPrefabClone;
    3. void Start(){
    4.     playerPrefabClone = Instantiate(playerPrefab, respawnPoint.position, respawnPoint.rotation);
    5. }
    6.  
    7. public void Respawn(){
    8.     playerPrefabClone.transform.position = respawnPoint.position);
    9.     cam.Follow = playerPrefabClone.transform
    10. }
    And keep the rest of your code as original but remove
    Destroy(gameObject);
    in PlayerDeath.
     
  5. FoxyWithTheMoxy

    FoxyWithTheMoxy

    Joined:
    Jan 16, 2021
    Posts:
    5
    Figured it out, I kept the LevelManager and PlayerMovement as the original but I changed the PlayerDeath as such:
    PlayerDeath
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class PlayerDeath : MonoBehaviour {

    private bool hasEntered;
    private void OnCollisionEnter2D(Collision2D collision) {
    if (collision.gameObject.tag == ("Hazard") && !hasEntered) {
    hasEntered = true;
    Destroy(gameObject);
    LevelManager.instance.Respawn();
    }
    }
    }

    The player doesn't clone anymore and everything works perfectly now!
     
    mikeohc likes this.