Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How To Keep Track Of Dead Enemies?

Discussion in 'Scripting' started by danilo12, Sep 11, 2015.

  1. danilo12

    danilo12

    Joined:
    Jul 21, 2015
    Posts:
    64
    So, I have been trying to keep track of which enemies are dead( the goal in the game is to kill all enemies which are hidden in seceret locations trough the scene.). The thing is I have a Save/Load Game function attached to a button, and it saves the player's location, health, and experience.

    Now what I want it to do is to save exactly which enemies are dead.

    I am using a prefab for my enemies attached with an EnemyScript Component.

    Now this is the code:
    public class Enemy:Monobehaviour{
    public float EnemyHP;
    public float EnemyID;
    public int isDead;
    public int CheckIfDead;

    void Start(){
    EnemyID = transform.position.z;
    }
    void Update(){
    if(EnemyHP <= 0){
    Die();
    CheckIfDead = 1;
    }
    else{
    CheckIfDead = 0;
    }
    void EnemySave(){
    PlayerPrefs.SetInt("Enemy"+EnemyID,CheckIfDead);
    }
    void EnemyLoad(){
    int DEAD = PlayerPrefs.GetInt("Enemy"+EnemyID);
    isDead = DEAD;
    if(isDead ==1){
    Destroy(gameObject);
    }
    }
    }
    Now I have an EnemyID specific for each enemy. I have a load function attached to my load button and a save function attached to my save button, but whenever I kill the two enemies in my scene and press save, exit the game and load, only one of the enemies is dead.

    I am kind of new to Unity, been using it for 3months yes, but please don't give me a tutorial in the answer, since I know some stuff about PlayerPrefs.
    What I want to know is why does it save only one enemy and it's very buggy sometimes it doesn't even save.
    Thanks.
     
  2. goonter

    goonter

    Joined:
    Aug 31, 2015
    Posts:
    89
    It's possible that they both share the same transform.position.z. That isn't really the best value to use for a unique ID because it isn't guaranteed to be unique. You could remove that part and assign them unique ids in the inspector, or create some sort of class that assigns all your enemies unique ids.
     
  3. Craig8726

    Craig8726

    Joined:
    Jul 5, 2013
    Posts:
    79
    if you use serialization for saving you can save much more than playerprefs. you can save classes, lists etc.
    trust me its worth learning because the data you can save is much more than the few variables allowed in playerPrefs. the only thing i could'nt save with binary is prefabs.

    google binary serializer. Basically you can serialise any class as binary and deserialze back to its original state at another run of the game.

    so to use it for your needs you could have a list of all the enemy gameObjects in the scene. you can the deserialize that list when loading and cross reference that list to the original to determine if they are alive or dead.

    its a bit harder than playerPrefs but the rewards of learning it are worth it.
     
  4. danilo12

    danilo12

    Joined:
    Jul 21, 2015
    Posts:
    64
    @goonter, I checked them, they are deffinetley not sharing the same value for the position.z .. @Craig8726 I know something about serialization I have heard the term before but I really think I should stick with playerprefs since all I have to do is add this enemy saving functionallity and my game is done.
     
  5. danilo12

    danilo12

    Joined:
    Jul 21, 2015
    Posts:
    64
    By the way I tweeked the code and now its fully working... only for the first enemy
     
  6. Craig8726

    Craig8726

    Joined:
    Jul 5, 2013
    Posts:
    79
    the problem with looking at your code is every one has there own way of writing the same thing. it's difficult to get into your mind set.

    It seems to me the variables you have stored on the enemy can be stored as a list of enemies on a single script. that way it would be much easier to scan it and see which enemies are alive and which are dead. But that is the way i think about this kind of problem. Im sorry if its not much help but in my experience its much easier to have all of the data that needs to be saved away from the objects in the scene and the objects should be an extention of the background data.
     
  7. danilo12

    danilo12

    Joined:
    Jul 21, 2015
    Posts:
    64
    so if i make a list of enemies, how would i go about checking which enemy is missing from the list(once he's dead) I would really appretiate it.
     
  8. Craig8726

    Craig8726

    Joined:
    Jul 5, 2013
    Posts:
    79
    you need savable data that can corespond to the gameobjects. strings can be saved in playerprefs so you could make a list of names of the remaining enemies when saving. that way when you load a new game you know which enemies are alive or dead by whether they are on the saved list of strings.
     
  9. Craig8726

    Craig8726

    Joined:
    Jul 5, 2013
    Posts:
    79
    or whatever the defining data is as long as it is unique
     
  10. Craig8726

    Craig8726

    Joined:
    Jul 5, 2013
    Posts:
    79
    i think your problem is beyond the capabilities of playerPrefs. you need to save a bool and the object its attached to.
    maybe if the number of enemies never increases you can use the index of the enemy list.
    create a list of the bools of the enemies. you will have an equal count of bools to enemies then when you load you can cross reference the bool indexes to the enemy indexes. if the bool is true then the enemy is alive else they are dead.
     
  11. danilo12

    danilo12

    Joined:
    Jul 21, 2015
    Posts:
    64
    So if I understood correctly what I need to do is make a list of strings for each enemy gameobject.. Now what i don't understand is how to assign a bool to each string i do understand that i need to make a list of bools for every string but for example if enemydeadbool1 is true when enemy 1 dies but how do.i translate it into code?
     
  12. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,738
    hmm what i would do is make a Dictionary<string, bool> store the enemy states in that than use a json or xml serializer to save that to file.
     
    danilo12 likes this.
  13. Crayz

    Crayz

    Joined:
    Mar 17, 2014
    Posts:
    192
    Serialization may be the best route for saving/loading game states. You're saving a floating point value as your key in PlayerPrefs and afaik PlayerPrefs should be used strictly because it stores values in the user's registry. Ideally each enemy should have a unique identifier given to them by some sort of manager which spawns (or recognizes) every enemy and adds them to a collection, their unique identifier being an integer that increments for each enemy that it spawns (or recognizes). If you continue to use PlayerPrefs you can then use that integer i.e. (Enemy + ID) resulting in Enemy1.. rather then Enemy9.0091817. I'm not sure if a registry key value will even support decimal points, so that may also be your issue
     
  14. danilo12

    danilo12

    Joined:
    Jul 21, 2015
    Posts:
    64
    Well the decimals aren't a problem I just mate the position.z to be a whole number on each and every one of my enemies but the saving only works for Enemy, but for Enemy1,2,3... it doesn't so I dont need another way to recgonize enemies because every enemy has it's unique ID I just want to know why does it only work on "Enemy" and not the others.
     
  15. danilo12

    danilo12

    Joined:
    Jul 21, 2015
    Posts:
    64
    So I made an EnemyManger class and added some simple code, and yet again it only works for the first enemy which is pissing me off.
    <code>
    using UnityEngine;
    using System.Collections;

    public class EnemyManager : MonoBehaviour {
    public GameObject Enemy1;
    public GameObject Enemy2;

    public int EnemyDead_1;
    public int EnemyDead_2;

    public int CheckIfDead_1;
    public int CheckIfDead_2;
    void Start () {

    }


    void Update () {
    if(EnemyDead_1 == 1){
    Destroy(Enemy1);
    }
    if(EnemyDead_2 == 1){
    Destroy(Enemy2);
    }
    if(Enemy1.GetComponent <Enemy>().isDead == true){
    CheckIfDead_1 = 1;
    }else{
    CheckIfDead_1 = 0;
    }
    if(Enemy2.GetComponent <Enemy>().isDead == true){
    CheckIfDead_2 = 1;
    }else{
    CheckIfDead_2 = 0;
    }
    }
    public void SaveEnemy(){
    PlayerPrefs.SetInt("Enemy_1_Dead",CheckIfDead_1);
    PlayerPrefs.SetInt("Enemy_2_Dead",CheckIfDead_2);
    }
    public void LoadEnemy(){
    EnemyDead_1 = PlayerPrefs.GetInt("Enemy_1_Dead");
    EnemyDead_2 = PlayerPrefs.GetInt("Enemy_2_Dead");
    }
    }
    </code>
     
  16. danilo12

    danilo12

    Joined:
    Jul 21, 2015
    Posts:
    64
    However, if i kill Enemy1 first it works for both...
     
  17. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,738
    the code tags are bbcode style so [ instead of <
     
  18. danilo12

    danilo12

    Joined:
    Jul 21, 2015
    Posts:
    64
    Bump, really need to fix this.since it's the last feature for my game.