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

[C#] Problem with not equal to the right variables in for loop

Discussion in 'Scripting' started by jolo309, Apr 7, 2014.

  1. jolo309

    jolo309

    Joined:
    Mar 4, 2012
    Posts:
    94
    Hi, so i have a little problem, with not equal to the right variable properties.

    This is the MobAI script

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [RequireComponent(typeof(NavMeshAgent))]
    5. public class MobAI : MonoBehaviour {
    6.    
    7.     MobCreator mc;
    8.     public float health = 57f;
    9.     public float minDamage = 5f;
    10.     public float maxDamage = 10f;
    11.     public float scale = 1f;
    12.     public float attackSpeed = 1500f;
    13.     public string runAnim;
    14.     public string walkAnim;
    15.     public string idleAnim;
    16.     public bool attackable;
    17.  
    18.     float distance;
    19.     int i = 0;
    20.     NavMeshAgent nma;
    21.  
    22.     void Awake()
    23.     {
    24.         mc = GameObject.Find("_CREATORSCRIPTS").GetComponent<MobCreator>();
    25.         nma = GetComponent<NavMeshAgent>();
    26.     }
    27.  
    28.     void Start()
    29.     {
    30.  
    31.     }
    32.  
    33.     // Update is called once per frame
    34.     void Update () {
    35.         distance = Vector3.Distance(GameObject.FindWithTag("Player").transform.position, transform.position);
    36.         if(distance <= 15  distance > 2f)
    37.         {
    38.             nma.SetDestination(GameObject.FindWithTag("Player").transform.position);
    39.         }
    40.  
    41.         for(int i = 0; i < mc.mobCreator.Count; i++)
    42.         {
    43.             Debug.Log("For start");
    44.             health = mc.mobCreator[i].health;
    45.             minDamage = mc.mobCreator[i].minDamage;
    46.             maxDamage = mc.mobCreator[i].maxDamage;
    47.             scale = mc.mobCreator[i].scale;
    48.             nma.speed = mc.mobCreator[i].runSpeed;
    49.             attackSpeed = mc.mobCreator[i].attackSpeed;
    50.             runAnim = mc.mobCreator[i].runAnim;
    51.             walkAnim = mc.mobCreator[i].walkAnim;
    52.             idleAnim = mc.mobCreator[i].idleAnim;
    53.             attackable = mc.mobCreator[i].attackable;
    54.             Debug.Log("For end");
    55.         }
    56.     }
    57. }
    58.  
    Then the mobcreator script(A script for easy making new mobs):

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class MobCreator : MonoBehaviour {
    6.  
    7.     [System.Serializable]
    8.     public class Mob
    9.     {
    10.         public enum MobType
    11.         {
    12.             Normal,
    13.             Elite,
    14.             Boss
    15.         }
    16.         public enum MobTypeState
    17.         {
    18.             Hostile,
    19.             Aggressive,
    20.             Friendly
    21.         }
    22.         public enum MobDamageType
    23.         {
    24.             Physical,
    25.             Ranged,
    26.             PhysicalAndRanged,
    27.             Fire,
    28.             Arcane,
    29.             Earth,
    30.             Frost
    31.         }
    32.  
    33.         public string name = "Unnamed";
    34.         public float health = 57f;
    35.         public float minDamage = 5f;
    36.         public float maxDamage = 10f;
    37.         public float scale = 1f;
    38.         public float runSpeed = 4f;
    39.         public float attackSpeed = 1500f;
    40.         public GameObject mob;
    41.         public string runAnim;
    42.         public string walkAnim;
    43.         public string idleAnim;
    44.         public MobType mobType;
    45.         public MobTypeState mobTypeState;
    46.         public MobDamageType mobDamageType;
    47.         public bool attackable;
    48.     }
    49.  
    50.     public List<Mob> mobCreator = new List<Mob>();
    51.  
    52.     // Use this for initialization
    53.     void Start () {
    54.         GameObject mobTest = (GameObject)Instantiate(mobCreator[0].mob, GameObject.Find("MobSpawn").transform.position, Quaternion.identity);
    55.     }
    56.    
    57.     // Update is called once per frame
    58.     void Update () {
    59.    
    60.     }
    61. }
    62.  

    Example to what i want:

    I have 3 mobs in the mobcreator list, Thug, thief and rat
    so i instantiate Thug, and the instantiated thug should have the variable properties from the thug in the list, but instead it does so the thug variable properties is equals to the last in the list which is the rat, so the thug has the rat properties which i don't want, what i want is the thug has the thug properties and thief has the thief properties and rat has the rat properties, because it doesn't really make sense if i have a thug with rat properties or a thief with rat properties :p

    So i appreciate any help i can get, and i appreciate tips on how i could make things better.

    Also a screenshot below shows the list i have of the mobs

    $Settings.png
     
  2. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    925
    as far as i understand the code, you constantly re-set the values in the for loop, and if i get that right, you set it to the values of mobCreator[0] up to mobCreator[2] each frame, it ends on mobCreator[2] and renders that.
     
    Last edited: Apr 7, 2014
  3. jolo309

    jolo309

    Joined:
    Mar 4, 2012
    Posts:
    94
    Yeah, but i'm not sure how i would do it so it does not do that
     
  4. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    Something to try:

    Make Mob a stand alone class.

    Add this to it's method list:
    Code (csharp):
    1.  
    2.         public string ToString(){
    3.             string s = "";
    4.             s+="MobHealth: " + health.ToString() + "\n";
    5.             s+="MobMinDamage: " + minDamage.ToString() + "\n";
    6.             s+="MobMaxDamage: " + maxDamage.ToString() + "\n";
    7.             s+="MobRunSpeed: " + runSpeed.ToString() + "\n";
    8.             s+="MobAttackSpeed: " + attackSpeed.ToString() + "\n";
    9.             s+="MobAttackable: " + attackable.ToString() + "\n";
    10.            
    11.             return s;
    12.         }
    13.  
    Change the MobAI Update for part to something like this:
    Code (csharp):
    1.  
    2.         for(Mob mob in mc.MobCreator){
    3.             Debug.Log("For start");
    4.            
    5.             health = mob.health;
    6.             minDamage = mob.minDamage;
    7.             maxDamage = mob.maxDamage;
    8.             scale = mob.scale;
    9.             nma.speed = mob.runSpeed;
    10.             attackSpeed = mob.attackSpeed;
    11.             runAnim = mob.runAnim;
    12.             walkAnim = mob.walkAnim;
    13.             idleAnim = mob.idleAnim;
    14.             attackable = mob.attackable;
    15.            
    16.             Debug.Log(mob.ToString());
    17.             Debug.Log("For end");
    18.         }
    19.  
     
  5. jolo309

    jolo309

    Joined:
    Mar 4, 2012
    Posts:
    94
    Hi, i did something a little bit easier

    Code (csharp):
    1. for(int i = 0; i < mc.mobCreator.Count; i++)
    2. {
    3.     Debug.Log("For start");
    4.     if(this.gameObject.name == mc.mobCreator[i].name)
    5.     {
    6.         health = mc.mobCreator[i].health;
    7.         minDamage = mc.mobCreator[i].minDamage;
    8.         maxDamage = mc.mobCreator[i].maxDamage;
    9.         scale = mc.mobCreator[i].scale;
    10.         nma.speed = mc.mobCreator[i].runSpeed;
    11.         attackSpeed = mc.mobCreator[i].attackSpeed;
    12.         runAnim = mc.mobCreator[i].runAnim;
    13.         walkAnim = mc.mobCreator[i].walkAnim;
    14.         idleAnim = mc.mobCreator[i].idleAnim;
    15.         attackable = mc.mobCreator[i].attackable;
    16.         break;
    17.     }
    18.     Debug.Log("For end");
    19. }
    Just adding a if statement and a break, now it does what i want.
    Thanks anyway :)
     
  6. TournyMasterBot

    TournyMasterBot

    Joined:
    Sep 8, 2013
    Posts:
    13
    @jolo309
    Code (csharp):
    1.  
    2. for(int i = 0; i < mc.mobCreator.Count; i++)
    3. {
    4.     Debug.Log("For start");
    5.  
    6.     if(this.gameObject.name == mc.mobCreator[i].name)
    7.     {
    8.         health = mc.mobCreator[i].health;
    9.         minDamage = mc.mobCreator[i].minDamage;
    10.         maxDamage = mc.mobCreator[i].maxDamage;
    11.         scale = mc.mobCreator[i].scale;
    12.         nma.speed = mc.mobCreator[i].runSpeed;
    13.         attackSpeed = mc.mobCreator[i].attackSpeed;
    14.         runAnim = mc.mobCreator[i].runAnim;
    15.         walkAnim = mc.mobCreator[i].walkAnim;
    16.         idleAnim = mc.mobCreator[i].idleAnim;
    17.         attackable = mc.mobCreator[i].attackable;
    18.         break;
    19.     }
    20.  
    21.     Debug.Log("For end");
    22.  
    23. }
    24.  
    You can also do
    Code (csharp):
    1.  
    2. debug.log("for start")
    3. for(...)
    4. {
    5.     if(!this.gameObject.name.equals(mc.mobCreator[i].name)) {continue;}
    6.     health = ... (your block of assignments)...
    7. }
    8. debug.log("for end")
    9.  
    This will reduce nesting and accomplish the same end.

    That being said, you might look into LINQ select queries to find your information, as it will save you a lot of loop control for this type of item.
    (LINQ overview: http://msdn.microsoft.com/en-us/library/bb397897.aspx)
    (LINQ samples: http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b)

    @bigmisterb

    Please never use string concatenation like this:
    Code (csharp):
    1.  
    2. public string ToString(){
    3.  
    4.             string s = "";
    5.             s+="MobHealth: " + health.ToString() + "\n";
    6.             s+="MobMinDamage: " + minDamage.ToString() + "\n";
    7.             s+="MobMaxDamage: " + maxDamage.ToString() + "\n";
    8.             s+="MobRunSpeed: " + runSpeed.ToString() + "\n";
    9.             s+="MobAttackSpeed: " + attackSpeed.ToString() + "\n";
    10.             s+="MobAttackable: " + attackable.ToString() + "\n";
    11.  
    12.             return s;
    13.  
    14.         }
    Performance is horrid, especially in an update loop. If you actually need string data, do something like

    Code (csharp):
    1.  
    2. var data = new StringBuilder();
    3. data.Append("MobHealth ");
    4. data.AppendLine(health.ToString());
    5. (... the rest of your items following the same pattern)
    6.  
    Strings are immutable, so you're creating multiple objects when you say stringvalue += "Some data" + some_other_data + "newline"

    Also of note, when you do use a stringbuilder, don't do concatination within the stringbuilder either, for the same reason as above.

    (WRONG)
    data.AppendLine("Some String" + Envronment.Newline +"Some Other String");

    (Correct)
    data.AppendLine("Some String");
    data.AppendLine("Some Other String);
     
  7. jolo309

    jolo309

    Joined:
    Mar 4, 2012
    Posts:
    94
    Thanks it works fine and does the exact same :)
    I'm going to look into LINQ too, thank you very much