Search Unity

Clones to not affect each other, having their own independent values?

Discussion in '2D' started by Ezwrath, Jul 26, 2014.

  1. Ezwrath

    Ezwrath

    Joined:
    May 17, 2014
    Posts:
    8
    Currently having a problem with my instantiated prefabs.

    0:09, the already released orb no longer collides due to a newly instantiated orb.
    (I do not own the background, it is a placeholder)

    If I hold the key S, i will instantiate a clone prefab that is a child to my player and all my clones will be able to ignore collision with all layers. On releasing the Key S, all my clones will no longer ignore collision, and that specific clone will no longer be a child. However, I only want the newly instantiated clone, while holding my key to ignore collision. Any other clone of that prefab that is not a child will not be affected.




    I attach this script to my player.

    in my update I call DarkOrbChannel();
    Line 52 of DarkOrbchannel, Get Key down, I call Spawn ();
    Line 63 of DarkOrbChannel(); I call Get Key up which calls Launch();,
    Line 84 of Spawn(); makes my ignore true
    Line 142 of Launch(); makes my ignore false
    I use ignore on my second Script on lines 28, and 38.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class DarkOrbPlayer : MonoBehaviour
    5. {
    6.     Animator anim;
    7.     public Rigidbody2D darkOrb;
    8.     public Transform channelStart;
    9.     public bool instantiated = true;                //to check if orb is created
    10.     public float cooldown = 0f;                        //individual cooldown on keydown
    11.     public float attackspeed = 3f;                    //attack speed is part of cooldown
    12.     public float checker = 0;                        //used to turn float to int, for Mathf
    13.     public float xsize = 15f;                        //x scale of orb
    14.     public float ysize = 15f;                        //y scale of orb
    15.     public float transition = 1f;                    //color of player, transition = 1 = white
    16.     public bool transitioning = false;                //if alpha of orb > 1
    17.     public float initialcost = 10f;
    18.     public AudioClip eerieend;
    19.     public AudioClip eeriesound;
    20.     public bool release = false;
    21.     public bool ignore;
    22.     public Rigidbody2D orb;
    23.  
    24.     void Start()
    25.     {
    26.         anim = gameObject.GetComponent<Animator> ();
    27.     }
    28.  
    29.     void Update()
    30.     {
    31.         DarkOrbChannel ();
    32.         foreach (SpriteRenderer sr in GetComponentsInChildren<SpriteRenderer>())
    33.         sr.color = new Color(transition, transition, transition);
    34.         if(!transitioning && transition != 1)
    35.         {
    36.             transition += 0.0015f;
    37.             if (transition > 1)
    38.             {
    39.                 transition = 1;
    40.             }
    41.         }
    42.     }//End Update
    43.  
    44.     void DarkOrbChannel()
    45.     {
    46.         if(Input.GetKeyDown(KeyCode.S))
    47.         {
    48.             WizardHealth wh = gameObject.GetComponent<WizardHealth>();
    49.             Playerscript ps = gameObject.GetComponent<Playerscript> ();
    50.             if( ps.isIdl && Time.time > cooldown && wh.mana > 10)
    51.             {
    52.                 Spawn();
    53.             }
    54.         }
    55.         if(Input.GetKey(KeyCode.S) && orb != null && instantiated)
    56.         {
    57.             Playerscript ps = gameObject.GetComponent<Playerscript> ();
    58.             Size ();
    59.             Alpha();
    60.             ps.moving = 2;
    61.  
    62.         }
    63.         if(Input.GetKeyUp(KeyCode.S))
    64.         {
    65.             Launch();
    66.         }
    67.     }//End DarkOrbChannel
    68.  
    69.     void Spawn()
    70.     {
    71.         WizardHealth wh = gameObject.GetComponent<WizardHealth>();
    72.         Playerscript ps = gameObject.GetComponent<Playerscript> ();
    73.         release = false;
    74.         anim.SetBool ("DarkOrbChannel", true);
    75.         ps.isChannel = true;
    76.         wh.mana -= 10;
    77.         orb = Instantiate(darkOrb , channelStart.position, Quaternion.identity) as Rigidbody2D;
    78.         orb.transform.parent = transform;
    79.         cooldown = Time.time + attackspeed;
    80.         //audio.PlayOneShot (eerieend);
    81.         audio.clip = eeriesound;
    82.         audio.Play ();
    83.         instantiated = true;
    84.         ignore = true;
    85.     }//End Spawn
    86.  
    87.     void Size()
    88.     {
    89.         orb.transform.localScale = new Vector3(xsize, ysize, 0);
    90.         xsize -= 0.01f;
    91.         ysize -= 0.01f;
    92.         if (ysize <= 2f || xsize <= 2f)
    93.         {
    94.             xsize = 2f;
    95.             ysize = 2f;
    96.         }
    97.     }//End Size
    98.  
    99.     void Alpha()
    100.     {
    101.         WizardHealth wh = gameObject.GetComponent<WizardHealth>();
    102.         DarkOrb dorb = transform.Find("Darkorb(Clone)").GetComponent<DarkOrb> ();
    103.         dorb.alpha += 0.00025f;
    104.         if(dorb.alpha > 1)
    105.         {
    106.             transitioning = true;
    107.             transition -= 0.002f;
    108.             foreach (SpriteRenderer sr in GetComponentsInChildren<SpriteRenderer>())
    109.                 sr.color = new Color(transition, transition, transition);
    110.             if(transition <= 0.5f)
    111.             {
    112.                 transition = 1f;
    113.             }
    114.         }
    115.  
    116.         if(dorb.alpha <= 1)
    117.         {
    118.             checker += 2 * Time.deltaTime;
    119.             wh.mana -= Mathf.FloorToInt(checker);
    120.             if(checker >=1)
    121.             {
    122.                 checker =0;
    123.             }
    124.         }
    125.         if(dorb.alpha >1.8f || wh.mana == 0)
    126.         {
    127.             Launch();
    128.         }
    129.     }//End Alpha
    130.  
    131.     void Launch()
    132.     {
    133.         release = true;
    134.         Playerscript ps = gameObject.GetComponent<Playerscript> ();
    135.         ps.moving = 4;
    136.         ps.isChannel = false;
    137.         anim.SetBool ("DarkOrbChannel", false);
    138.         transitioning = false;
    139.         xsize = 15f;
    140.         ysize = 15f;
    141.         orb.transform.parent = null;
    142.         ignore = false;
    143.         if(instantiated && orb != null)
    144.         {
    145.             audio.Stop();
    146.             audio.PlayOneShot (eerieend);
    147.             instantiated = false;
    148.             if(ps.facingRight)
    149.             {
    150.                 orb.rigidbody2D.AddForce(Vector3.right * 400);
    151.             }
    152.             else
    153.             {
    154.                 orb.rigidbody2D.AddForce(-Vector3.right * 400);
    155.             }
    156.         }
    157.     }//End Launch
    158.  
    159.     public int darkBallExp = 0;      
    160.     public int darkBallMaxExp = 500;
    161.     public int darkBallLevel =1;
    162. }
    this one I attach to my public Rigidbody2D darkOrb prefab on my first script
    Line 28, if ignore is true, I ignore these layers
    Line 38 else, I do not ignore these layers.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class DarkOrb : MonoBehaviour
    5. {
    6.     public float lifeTime =3f;
    7.     public float alpha = 0.3f;
    8.     private float alphadamage = 0f;
    9.     public static float damage = 2f;
    10.     public bool isEnemyDarkBall = false;
    11.  
    12.     void Start()
    13.     {
    14.         alpha = 0.3f;
    15.         Physics2D.IgnoreLayerCollision (11, 12);
    16.         Physics2D.IgnoreLayerCollision (13, 12);
    17.         Physics2D.IgnoreLayerCollision (9, 12);
    18.         Physics2D.IgnoreLayerCollision (10, 12);
    19.         Physics2D.IgnoreLayerCollision (14, 12);
    20.         Physics2D.IgnoreLayerCollision (15, 12);
    21.     }
    22.  
    23.     void Update ()
    24.     {
    25.         damage = Mathf.FloorToInt(alphadamage);
    26.  
    27.         DarkOrbPlayer dop = GameObject.Find ("Wizard").GetComponent<DarkOrbPlayer> ();
    28.         if(dop.ignore) //if child
    29.         {
    30.             Debug.Log ("iamchild");
    31.             Physics2D.IgnoreLayerCollision (11, 12);
    32.             Physics2D.IgnoreLayerCollision (13, 12);
    33.             Physics2D.IgnoreLayerCollision (9, 12);
    34.             Physics2D.IgnoreLayerCollision (10, 12);
    35.             Physics2D.IgnoreLayerCollision (14, 12);
    36.             Physics2D.IgnoreLayerCollision (15, 12);
    37.         }
    38.         else  //if not  a child
    39.         {
    40.             alphadamage = 12 * alpha;
    41.             if (alphadamage > 12)
    42.             {
    43.                 alphadamage = 12;
    44.             }
    45.             Physics2D.IgnoreLayerCollision (13, 12,false);
    46.             Physics2D.IgnoreLayerCollision (9, 12,false);
    47.             Physics2D.IgnoreLayerCollision (10, 12,false);
    48.             Physics2D.IgnoreLayerCollision (14, 12,false );
    49.             Physics2D.IgnoreLayerCollision (15, 12,false );
    50.         }
    51.  
    52.         SpriteRenderer spriterenderer = GetComponent<SpriteRenderer> ();
    53.         spriterenderer.color = new Color (1f, 1f, 1f, alpha);
    54.         transform.Rotate (0 , 0, 720 * Time.deltaTime);
    55.         Playerscript ps = GameObject.Find("Wizard").GetComponent<Playerscript>();
    56.  
    57.         if(dop.release)
    58.         {
    59.             Destroy(gameObject , lifeTime);
    60.         }
    61.     }
    62.  
    63.     void OnTriggerEnter2D(Collider2D OtherCollider)
    64.     {
    65.         HealthScript healthscript = OtherCollider.gameObject.GetComponent<HealthScript> ();
    66.  
    67.         if (healthscript != null)
    68.             if (isEnemyDarkBall = healthscript.isEnemy ())
    69.         {
    70.             if (isEnemyDarkBall == true)
    71.             {
    72.                 healthscript.redtime = Time.time + 1 * healthscript.redduration;
    73.                 healthscript.red = 8;
    74.                 healthscript.Damage (Playerscript.DO);
    75.             }
    76.         }
    77.     }
    78. }
    Update: The damage of my prefab depends on how long I've held down my Key. I decided to remove the ignore collision, and the damage scales off how long I held on my newly instantiated orb, rather than the previous.
     
    Last edited: Jul 28, 2014
  2. Punchbag

    Punchbag

    Joined:
    Oct 30, 2012
    Posts:
    48
    Changes to a prefab will affect all instances of the prefab.

    When a clone is spawned, check whether you want to attach the "ignore collisions component" and if you do, attach it to the clone, not the prefab.

    This way, you'll have individual clones floating around with the component and others without.

    Edit
    Additionally, your life will be much easier if you get used to making things like Orbs fire and forget. That is, after the player creates them, they manage themselves, instead of trying to manage them centrally in the player. This includes things like their sound effect being played by the orb instead of the player, so you can eventually cast whatever you want from the player without having to list like 80 sound effects in on method. Instead each of your 80 spells has their associated sound effect... and so on.
     
  3. Ezwrath

    Ezwrath

    Joined:
    May 17, 2014
    Posts:
    8
    Thank you for replying, I'm still very new to unity and am still stuck on this problem.

    How do I attach this to my clone, not my prefab? However this would still not change my damage value?

    I have tried making unique named clones, but still do not know how to execute the code properly. I have also stumbled upon something called structs, Is that possibly a solution?
     
    Last edited: Aug 24, 2014
  4. Punchbag

    Punchbag

    Joined:
    Oct 30, 2012
    Posts:
    48
    Ok, had a quick re-read of your code. I'm going to describe your key steps, then point out where you've gone wrong:
    • Create an Orb (or many orbs!)
    • In each Orb's update (which happens every "frame"), find the player (of which there is only one)
    • If that one player's one ignore property is true, behave differently
    Now, hopefully, this will already point you to your problem. You change the ignore value, all orbs find the one player, see the changed value and behave differently. Here's what you should be doing:
    • Create an orb (or many orbs!)
    • On the newly created orb, set the direction, the orb's ignore value, etc.
    • Forget about the orb in the player.
    • Forget about the player in the orb.
    • Have the orb check it's own ignore value when going about its business.
    Problem solved, because each orb is taking care of its own responsibilities.

    This is a key component of Object Oriented Programming. If you make everything responsible for itself and doing the minimum to control other objects or be controlled by other objects, you'll have a much easier time of keeping track of what is going on.

    Eventually, you'll probably want to take all the orb generation code out of the player and put it into some sort of factory class, so that any object can create orbs wherever they want, but this is an advanced concept so don't worry about it for now.

    Good luck!