Search Unity

Why is the Code Working Only For / On One Instance?

Discussion in 'Scripting' started by FGPArthurVII, Mar 27, 2018.

  1. FGPArthurVII

    FGPArthurVII

    Joined:
    Jan 5, 2015
    Posts:
    106
    Greetings Everyone;

    I've got a prefab, which is a Printer, This prefab is set with a tag called "Flamable".

    The objective here is that I can get near to it and by pressing "E" once it starts incinerating, by instancing the particle system. With the next "E" inputs I can put out the fire or light it on fire again.

    Once the object tagged "Flamable" is hit by the Raycast, by hitting "E" it becames "Burning", and the code now detects that the only job I have to do now is to put out / burn it.

    But the thing is: There is only one printer working with this feature (printer (0) in case (Also, the names follow this pattern: printer (0), printer (1), printer(2)... printer(n)) ) When I get to some other printer (say printer (1)), when I hit E it changes to "Burning" tag... the printer (0)... not printer (1) as should be... also, when I look at this very same printer instance , the code is detecting "Burning Printer", which means I am looking to an object marked with the tag "burning", even though by going to the scene view It is clearly marked "Flamable". Moreover, by pressing "E" to ignite / extinguish... it indeed happens... on the other printer, of course...

    I have no clue about what is going on here in order to this bug happen.

    Can someone help me with the issue?

    Thanks;
    Arthur.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class IncendiaryTendencies : MonoBehaviour
    6. {
    7.     RaycastHit hit;
    8.     ParticleSystem currentParticle;
    9.  
    10.     private int index, currPartSys; //currPartSys Acts as an index for the particle Systems Array;
    11.     private static int leng; //Length Variable;
    12.     private bool canInstance, canSet;
    13.     //--------------------//
    14.     private Vector3 fwd;  
    15.     private Transform currentObject;
    16.     private GameObject instance;
    17.     public GameObject ptSys;
    18.     //--------------------//
    19.     private ParticleSystem[] fires;
    20.  
    21.     void Start()
    22.     {
    23.         currPartSys = 0;
    24.         index = 0;
    25.         leng = index + 1;
    26.         instance = null;
    27.         fires = new ParticleSystem[leng];
    28.         fwd = transform.TransformDirection(Vector3.forward);
    29.         canInstance = false;
    30.         canSet = false;
    31.     }
    32.  
    33.     void FixedUpdate()
    34.     {
    35.         if (Physics.Raycast (transform.position, fwd, out hit, 3f))
    36.         {
    37.             currentObject = hit.transform;
    38.             if (currentObject.tag == "Flamable")
    39.             {
    40.                 print ("Flamable " + currentObject.name);
    41.                 canInstance = true;
    42.             }
    43.             else if (currentObject.tag == "Burning")
    44.             {
    45.                 print ("Burning " + currentObject.name);
    46.                 SearchParticles ();
    47.                 canSet = true;
    48.             }
    49.         }  
    50.     }
    51.  
    52.     private void SummonInstance ()
    53.     {
    54.         if (Input.GetKeyDown (KeyCode.E) && canInstance)
    55.         {
    56.             instance = Instantiate (ptSys, currentObject);
    57.             instance.transform.localPosition = new Vector3 (0, 0, 0);
    58.             instance.transform.localEulerAngles = new Vector3 (0, 0, 0);
    59.             fires[index] = currentObject.GetChild(4).GetComponent<ParticleSystem>();
    60.             fires[index].name = currentObject.name;
    61.  
    62.             currentObject.tag = "Burning";
    63.             index += 1;
    64.             canInstance = false;
    65.         }
    66.     }
    67.  
    68.     //---------------------------------------------------------------------------------//
    69.  
    70.     private void SetState ()
    71.     {
    72.         if (Input.GetKeyDown (KeyCode.E) && canSet && fires[currPartSys].isPlaying)
    73.         {
    74.             fires[currPartSys].Stop ();
    75.             print ("Stopped");
    76.         }
    77.         else if (Input.GetKeyDown (KeyCode.E) && canSet && fires[currPartSys].isStopped)
    78.         {
    79.             fires[currPartSys].Play ();
    80.             print ("Playing");
    81.         }
    82.     }
    83.  
    84.     void SearchParticles()
    85.     {
    86.         for (int i = 0; i < fires.Length; i++)
    87.         {
    88.             if (fires[i].name == currentObject.name)
    89.                 currPartSys = i;
    90.         }
    91.     }
    92.  
    93.     //================================================================================//
    94.  
    95.     void Update()
    96.     {
    97.         SummonInstance ();
    98.         SetState();
    99.     }
    100. }
     
    Last edited: Mar 27, 2018
  2. gegebel

    gegebel

    Joined:
    Jan 29, 2014
    Posts:
    469
    sounds like your currentObject is not selected correctly.
    Added to this, you never change the tags back when the fire is stopped.

    In my opinion, you make it too complicated and confusing.
    Try to simplify, especially your conditions.

    Let's say you go to a printer, set it on fire. the printer is never set to canSet, unless you go back to that printer and hit E again, since it's happening in FixedUpdate and SetState is on Update, this might cause problems.

    I'm not saying this is the main problem, but things like that get confusing very fast and doing a raycast on every FixedUpdate is not really effective to be honest.
    Do the raycast only when you did hit E and not before.
    Added to this, you do a raycast against everything, so if the raycast hits something else than your printer, it will still get a currentObject, and you do the assignment every FixedUpdate.

    Since I don't know your scene or your game, I won't say it's an issue to do it like you did, but it's clear, there is a much better solution to this.
    I wouldn't bother trying to fix this code if I were you, just start from scratch.
     
  3. FGPArthurVII

    FGPArthurVII

    Joined:
    Jan 5, 2015
    Posts:
    106
    Well, The reason I've never set it back to flamable, is to avoid instancing all the time; Since I work with objects that doesn't have the particle system on it originally (to keep less things on scene), so I instance once and the next jobs just Start or Stop it at will.
    CanSet is like a version of CanInstance, but since we're not working with Instancing anymore, CanSet will give me permition to activate or disengage the fire, or not.
     
  4. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
    Thought I had an idea but it didn't make sense after further thought. Does it give the correct object name? I'm not clear on that.
     
  5. FGPArthurVII

    FGPArthurVII

    Joined:
    Jan 5, 2015
    Posts:
    106
    After both your comments I've made some changes to the code based on it, and Reached this, but the problem between the two printers is still happening:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class IncendiaryTendencies : MonoBehaviour
    6. {
    7.     private int index, currPartSys; //currPartSys Acts as an index for the particle Systems Array;
    8.     private static int leng; //Length Variable;
    9.     //--------------------//
    10.     private Vector3 fwd;  
    11.     private Transform currentObject;
    12.     private GameObject instance;
    13.     public GameObject ptSys;
    14.     private ParticleSystem currentParticle;
    15.     //--------------------//
    16.     private ParticleSystem[] fires;
    17.  
    18.     void Start()
    19.     {
    20.         currPartSys = 0;
    21.         index = 0;
    22.         leng = index + 1;
    23.         instance = null;
    24.         fires = new ParticleSystem[leng];
    25.         fwd = transform.TransformDirection(Vector3.forward);
    26.     }
    27.  
    28.     private void CheckCommand ()
    29.     {
    30.         if (Input.GetKeyDown (KeyCode.E))
    31.         {
    32.             RaycastHit hit;
    33.             if (Physics.Raycast (transform.position, fwd, out hit, 3f))
    34.             {
    35.                 currentObject = hit.transform;
    36.                 if (currentObject.tag == "Flamable")
    37.                 {
    38.                     SummonInstance ();
    39.                 }
    40.                 else if (currentObject.tag == "Burning")
    41.                 {
    42.                     SetState();
    43.                 }
    44.             }
    45.         }
    46.     }
    47.  
    48.     private void SummonInstance ()
    49.     {
    50.         print ("Flamable " + currentObject.name + " Now Burning");
    51.  
    52.         instance = Instantiate (ptSys, currentObject);
    53.         instance.transform.localPosition = new Vector3 (0, 0, 0);
    54.         instance.transform.localEulerAngles = new Vector3 (0, 0, 0);
    55.         fires[index] = currentObject.GetChild(4).GetComponent<ParticleSystem>();
    56.         fires[index].name = currentObject.name;
    57.  
    58.         currentObject.tag = "Burning";
    59.         index += 1;
    60.     }
    61.  
    62.     private void SetState ()
    63.     {
    64.         //----------------------------------------//
    65.         for (int i = 0; i < fires.Length; i++)
    66.         {
    67.             if (fires[i].name == currentObject.name)
    68.                 currPartSys = i;
    69.         }
    70.         //---------------------------------------//
    71.  
    72.  
    73.         if (Input.GetKeyDown (KeyCode.E) && fires[currPartSys].isPlaying)
    74.         {
    75.             fires[currPartSys].Stop ();
    76.             print ("Stopped");
    77.         }
    78.         else if (Input.GetKeyDown (KeyCode.E) && fires[currPartSys].isStopped)
    79.         {
    80.             fires[currPartSys].Play ();
    81.             print ("Playing");
    82.         }
    83.     }
    84.  
    85.     //================================================================================//
    86.  
    87.     void Update()
    88.     {
    89.         CheckCommand ();
    90.     }
    91. }
    What do you mean?
     
    Last edited: Mar 28, 2018
  6. gegebel

    gegebel

    Joined:
    Jan 29, 2014
    Posts:
    469
    I suppose you put this script on the player. ever thought to have a script on the printers ?
    Might use a trigger to detect the player and wait for a command instead of searching through different objects and particle systems. Just an idea.
    You would move the execution on the object, maybe go through an interface so you could use the script on other objects too and trigger the objects as useable when the player is close.
    Well that's how I would do it to get around the problem anyway.
     
  7. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
    Does this line give the correct object name:
    Code (csharp):
    1.  
    2.  print ("Flamable " + currentObject.name);
    3.  
    Also, are these prefabs? Did you drag them into the project folder and then drag the reference onto the script or whatever?
     
  8. FGPArthurVII

    FGPArthurVII

    Joined:
    Jan 5, 2015
    Posts:
    106
    Tried that now, now I can Instance the Fire on both Printers at the same time, but one printer still interfers with the other's fire

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class CatchingFire : MonoBehaviour
    6. {
    7.     private GameObject instance;
    8.     private bool isInstanced;
    9.     public GameObject ptSys;
    10.     private ParticleSystem fire;
    11.     private Transform myself;
    12.  
    13.     void Start()
    14.     {
    15.         isInstanced = false;
    16.         myself = this.GetComponent<Transform> ();
    17.     }
    18.  
    19.     void OnTriggerStay(Collider col)
    20.     {
    21.         if (col.tag == "Player")
    22.         {
    23.             print ("Hello World");
    24.             if (Input.GetKeyDown(KeyCode.E) && !isInstanced)
    25.             {
    26.                 SummonInstance ();
    27.                 isInstanced = true;
    28.             }
    29.         }
    30.     }
    31.  
    32.     private void SummonInstance ()
    33.     {
    34.         print ("Flamable " + this.name + " Now Burning");
    35.  
    36.         instance = Instantiate (ptSys, this.transform);
    37.         instance.transform.localPosition = new Vector3 (0, 0, 0);
    38.         instance.transform.localEulerAngles = new Vector3 (0, 0, 0);
    39.         fire = myself.GetChild (4).GetComponent<ParticleSystem> ();
    40.     }
    41.  
    42.     private void SetState ()
    43.     {
    44.         if (Input.GetKeyDown(KeyCode.E) && fire.isPlaying)
    45.         {
    46.             fire.Stop ();
    47.             print (this + " has been Put Out");
    48.         }
    49.         else if (Input.GetKeyDown(KeyCode.E) && fire.isStopped)
    50.         {
    51.             fire.Play ();
    52.             print (this + " has been Ignited");
    53.         }
    54.     }
    55.  
    56.     void Update()
    57.     {
    58.         if (isInstanced)
    59.         {
    60.             SetState ();
    61.         }
    62.     }
    63. }
    64.  
     
  9. FGPArthurVII

    FGPArthurVII

    Joined:
    Jan 5, 2015
    Posts:
    106
    Yes, currently printing all right.
     
  10. gegebel

    gegebel

    Joined:
    Jan 29, 2014
    Posts:
    469
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class CatchingFire : MonoBehaviour
    6. {
    7.     private GameObject instance;
    8.     private bool isInstanced;
    9.     public GameObject ptSys;
    10.     private ParticleSystem fire;
    11.     private Transform myself;
    12.  
    13.     void Start()
    14.     {
    15.         isInstanced = false;
    16.         myself = this.GetComponent<Transform>();
    17.     }
    18.  
    19.     void OnTriggerStay(Collider col)
    20.     {
    21.         if (col.tag == "Player")
    22.         {
    23.             print("Hello World");
    24.             if (Input.GetKeyDown(KeyCode.E))
    25.             {
    26.                 if (!isInstanced)
    27.                 {
    28.                     SummonInstance();
    29.                     isInstanced = true;
    30.                 } else
    31.                 {
    32.                     SetState();
    33.                 }              
    34.             }
    35.         }
    36.     }
    37.  
    38.     private void SummonInstance()
    39.     {
    40.         print("Flamable " + this.name + " Now Burning");
    41.  
    42.         instance = Instantiate(ptSys, this.transform);
    43.         instance.transform.localPosition = new Vector3(0, 0, 0);
    44.         instance.transform.localEulerAngles = new Vector3(0, 0, 0);
    45.         fire = myself.GetChild(4).GetComponent<ParticleSystem>();
    46.     }
    47.  
    48.     private void SetState()
    49.     {
    50.             if (fire.isPlaying)
    51.             {
    52.                 fire.Stop();
    53.                 print(this + " has been Put Out");
    54.             } else
    55.             {
    56.                 fire.Play();
    57.                 print(this + " has been Ignited");
    58.             }
    59.     }
    60. }
    61.  
    I tried to rewrite a bit of it, but I don't get why you reference the fire by searching through childs instead of using the created instance. After all you want to control the instance and nothing else. So why not use instance.GetComponent<ParticleSystem>() ?
    To me, it looks like instance and fire are 2 very different things.
    You should also put some conditions for null reference exceptions, once it works like you want.
     
  11. FGPArthurVII

    FGPArthurVII

    Joined:
    Jan 5, 2015
    Posts:
    106