Search Unity

Prefab doesn't destroy on get MouseKeyDown S?

Discussion in 'Scripting' started by Ninjix3, Mar 22, 2018.

  1. Ninjix3

    Ninjix3

    Joined:
    Mar 4, 2018
    Posts:
    13
    I'm making a script for a bird that will hover over the player and will result in two events. One is for destroying the bird (killing) the other is for resetting the game if the player doesn't shield itself for a certain time. However, whenever I press the "S" key (for shielding) nothing happens. Also, my fading transition starts right at the beginning instead of having a delay using the Ienumerator Fade In function. My debug.Log response "You Challenged the Bird" doesn't show up in the council either any reason why?

    Code (csharp):
    1.  
    2.  
    3. public class OwlAI : MonoBehaviour {
    4.     public float xSpread;
    5.     public float zSpread;
    6.     public float yOffset;
    7.  
    8.     public float waitTime= 1f;
    9.     public float fadeTime= 10f;
    10.  
    11.     public Transform centerPoint;
    12.  
    13.     public float rotSpeed;
    14.     public bool rotateClockwise;
    15.  
    16.     public GameObject owl;
    17.  
    18.     float timer = 0;
    19.  
    20.     // Use this for initialization
    21.     void Update()
    22.     {
    23.         timer += Time.deltaTime * rotSpeed;
    24.         Rotate ();
    25.         transform.LookAt (centerPoint);
    26.  
    27.  
    28.     }
    29.  
    30.     void Start (){
    31.  
    32.         StartCoroutine (OwlFadeIn(fadeTime));
    33.  
    34.         if  (Input.GetKeyDown(KeyCode.S)) {
    35.             // Fade in
    36.             //iTween.FadeTo(owl, 1, 1);
    37.             //Invoke("SetMaterialOpaque", 1.0f);
    38.  
    39.             Debug.Log ("You Challenged the Bird");
    40.             StartCoroutine (OwlDeath(waitTime));
    41.        
    42.             //} else {
    43.  
    44.             //StartCoroutine (ResetOwl(waitTime));
    45.  
    46.         }
    47.     }
    48.  
    49.     void Rotate()
    50.     {
    51.         if (rotateClockwise) {
    52.             float x = -Mathf.Cos (timer) * xSpread;
    53.             float z = Mathf.Sin (timer) * zSpread;
    54.             Vector3 pos = new Vector3 (x, yOffset, z);
    55.             transform.position = pos + centerPoint.position;
    56.         }else{
    57.             float x = Mathf.Cos (timer) * xSpread;
    58.             float z = Mathf.Sin (timer) * zSpread;
    59.             Vector3 pos = new Vector3 (x, yOffset, z);
    60.             transform.position = pos + centerPoint.position;
    61.  
    62.  
    63.         }
    64.  
    65.     }
    66.  
    67.     IEnumerator OwlDeath (float waitTime){
    68.  
    69.         Debug.Log ("Death Owl Started");
    70.         yield return new WaitForSeconds (waitTime);
    71.         //Destroy (this.gameObject);
    72.  
    73.         //Fade out
    74.         SetMaterialTransparent();
    75.         iTween.FadeTo (owl, 0, 1);
    76.  
    77.         Destroy (GameObject.FindWithTag ("Owl"));
    78.     }
    79.  
    80.     //IEnumerator ResetOwl (float waitTime){
    81.  
    82.         //Debug.Log ("Reset Game");
    83.         //yield return new WaitForSeconds (waitTime);
    84.     //}
    85.  
    86.     private void SetMaterialTransparent ()
    87.     {
    88.  
    89.         foreach (Material m in owl.GetComponent<Renderer>().materials)
    90.         {
    91.             m.SetFloat ("_Mode", 2);
    92.             m.SetInt ("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
    93.             m.SetInt ("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
    94.             m.SetInt ("_ZWrite", 0);
    95.             m.DisableKeyword ("_ALPHATEST_ON");
    96.             m.EnableKeyword ("_ALPHABLEND_ON");
    97.             m.DisableKeyword ("_ALPHAPREMULTIPLY_ON");
    98.             m.renderQueue = 3000;
    99.         }
    100.     }
    101.  
    102.     private void SetMaterialOpaque()
    103.     {
    104.         foreach(Material m in owl.GetComponent<Renderer>().materials)
    105.         {
    106.             m.SetInt ("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
    107.             m.SetInt ("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
    108.             m.SetInt ("_ZWrite", 1);
    109.             m.DisableKeyword ("_ALPHATEST_ON");
    110.             m.DisableKeyword ("_ALPHABLEND_ON");
    111.             m.DisableKeyword ("_ALPHAPREMULTIPLY_ON");
    112.             m.renderQueue = -1;
    113.         }
    114.  
    115.     }
    116.  
    117.     IEnumerator OwlFadeIn (float fadeTime){
    118.  
    119.         Debug.Log ("Owl Has Entered");
    120.         yield return new WaitForSeconds (fadeTime);
    121.         //Destroy (this.gameObject);
    122.         // Fade in
    123.         iTween.FadeTo(owl, 1, 1);
    124.         Invoke("SetMaterialOpaque", 1.0f);
    125.  
    126.     }
    127.  
    128.  
    129. }
    130.  
    131. [CODE/]
     
  2. Rotary-Heart

    Rotary-Heart

    Joined:
    Dec 18, 2012
    Posts:
    813
    You are checking for the Input on start, you should be checking for the Input on update. Start only gets called the frame the script gets enabled: Reference
     
    Ninjix3 likes this.
  3. Mokzen

    Mokzen

    Joined:
    Oct 10, 2016
    Posts:
    102
    Also, be aware that you pass a value of 1f to your Ienumerator, which means the delay will be kinda short.
     
    Ninjix3 likes this.
  4. Ninjix3

    Ninjix3

    Joined:
    Mar 4, 2018
    Posts:
    13
    Thank you so much guys!! I did that earlier but so much organizing and I get confused!
     
  5. Ninjix3

    Ninjix3

    Joined:
    Mar 4, 2018
    Posts:
    13
    On and one more thing. Because I'm confused with the value of 1f to the Ienumerator. I want to know why does my Debug.Log ("Reset Game"); post over and over in my council. I would like it to see if S was pressed and if not pass to the coroutine ResetOwl under else and wait 30 seconds before posting Debug.Log ("Reset Game"); once.


    Code (csharp):
    1.  
    2. public class OwlAI : MonoBehaviour {
    3.     public float xSpread;
    4.     public float zSpread;
    5.     public float yOffset;
    6.  
    7.     public int waitTime= 1;
    8.     public int fadeTime= 3;
    9.  
    10.     public Transform centerPoint;
    11.  
    12.     public float rotSpeed;
    13.     public bool rotateClockwise;
    14.  
    15.     public GameObject owl;
    16.  
    17.     float timer = 0;
    18.  
    19.     // Use this for initialization
    20.     void Update()
    21.     {
    22.         timer += Time.deltaTime * rotSpeed;
    23.         Rotate ();
    24.         transform.LookAt (centerPoint);
    25.  
    26.         if  (Input.GetKeyDown(KeyCode.S)) {
    27.  
    28.             Debug.Log ("You Challenged the Bird");
    29.             StartCoroutine (OwlDeath(waitTime));
    30.  
    31.         } else {
    32.  
    33.             StartCoroutine (ResetOwl());
    34.  
    35.         }
    36.  
    37.     }
    38.  
    39.     void Start (){
    40.  
    41.         StartCoroutine (OwlFadeIn());
    42.  
    43.  
    44.     }
    45.  
    46.     void Rotate()
    47.     {
    48.         if (rotateClockwise) {
    49.             float x = -Mathf.Cos (timer) * xSpread;
    50.             float z = Mathf.Sin (timer) * zSpread;
    51.             Vector3 pos = new Vector3 (x, yOffset, z);
    52.             transform.position = pos + centerPoint.position;
    53.         }else{
    54.             float x = Mathf.Cos (timer) * xSpread;
    55.             float z = Mathf.Sin (timer) * zSpread;
    56.             Vector3 pos = new Vector3 (x, yOffset, z);
    57.             transform.position = pos + centerPoint.position;
    58.  
    59.  
    60.         }
    61.  
    62.     }
    63.  
    64.     IEnumerator OwlDeath (int waitTime){
    65.  
    66.         Debug.Log ("Death Owl Started");
    67.         yield return new WaitForSeconds (waitTime);
    68.         //Destroy (this.gameObject);
    69.  
    70.         //Fade out
    71.         SetMaterialTransparent();
    72.         iTween.FadeTo (owl, 0, 1);
    73.  
    74.         Destroy (GameObject.FindWithTag ("Owl"));
    75.     }
    76.  
    77.     IEnumerator ResetOwl (){
    78.  
    79.         Debug.Log ("Reset Game");
    80.         yield return new WaitForSeconds(30);
    81.         //Fade out
    82.         SetMaterialTransparent();
    83.         iTween.FadeTo (owl, 0, 1);
    84.  
    85.         Destroy (GameObject.FindWithTag ("Owl"));
    86.     }
    87.  
    88.     private void SetMaterialTransparent ()
    89.     {
    90.  
    91.         foreach (Material m in owl.GetComponent<Renderer>().materials)
    92.         {
    93.             m.SetFloat ("_Mode", 2);
    94.             m.SetInt ("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
    95.             m.SetInt ("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
    96.             m.SetInt ("_ZWrite", 0);
    97.             m.DisableKeyword ("_ALPHATEST_ON");
    98.             m.EnableKeyword ("_ALPHABLEND_ON");
    99.             m.DisableKeyword ("_ALPHAPREMULTIPLY_ON");
    100.             m.renderQueue = 3000;
    101.         }
    102.     }
    103.  
    104.     private void SetMaterialOpaque()
    105.     {
    106.         foreach(Material m in owl.GetComponent<Renderer>().materials)
    107.         {
    108.             m.SetInt ("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
    109.             m.SetInt ("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
    110.             m.SetInt ("_ZWrite", 1);
    111.             m.DisableKeyword ("_ALPHATEST_ON");
    112.             m.DisableKeyword ("_ALPHABLEND_ON");
    113.             m.DisableKeyword ("_ALPHAPREMULTIPLY_ON");
    114.             m.renderQueue = -1;
    115.         }
    116.  
    117.     }
    118.  
    119.     IEnumerator OwlFadeIn (){
    120.  
    121.         Debug.Log ("Owl Has Entered");
    122.         yield return new WaitForSeconds(5);
    123.    
    124.         // Fade in
    125.         iTween.FadeTo(owl, 1, 1);
    126.         Invoke("SetMaterialOpaque", 1f);
    127.  
    128.     }
    129.  
    130.  
    131. }
    132.  
    133. [CODE/]
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Under what circumstances do you want the 'ResetOwl' to occur?

    Right now, your code is running many coroutines (beginning 1 each frame, so long as that key isn't down).

    Do you want it to reset the owl if they don't press 'S' on the first frame this script runs?
    I can't imagine that's correct, either..

    If you write what you're looking for a bit clearer, it might be easier to help you find a solution :)
     
  7. Mokzen

    Mokzen

    Joined:
    Oct 10, 2016
    Posts:
    102
    Code (CSharp):
    1. Debug.Log ("Reset Game");
    comes from your ResetOwl method, which is called in Update every frame as long as Unity doesn't receive an Input.GetKeyDown(KeyCode.S) input.

    that is probably why you see that message all the time.

    In case you don't know, the Update method is called once every frame. This means that any code you put in there, unless it is contained within some sort of condition check or similar, will be executed once every frame.

    In case of the if/else-statement you have in your Update method, you specify that if the the S-key is NOT pressed, the game should start a Coroutine with the Ienumerator ResetOwl as a parameter.

    Hope that clears things up a bit.
     
    Last edited: Mar 23, 2018
  8. Ninjix3

    Ninjix3

    Joined:
    Mar 4, 2018
    Posts:
    13
    Okay, so I tried to write it clean this time using a bool @methos5k @Mozken. What I want is that if a key is not pressed within a certain amount of seconds the game will have a reset screen. If the key is pressed then the bird dies.


    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using UnityEngine.UI;
    5.  
    6. public class OwlEx : MonoBehaviour {
    7.  
    8.     public GameObject gameOverPanel;
    9.  
    10.     public float TimeLimit = 10f;
    11.     private bool pressS;
    12.  
    13.     // Update is called once per frame
    14.     void Update () {
    15.         if (Input.GetKeyDown("S"))
    16.         {
    17.             pressS = true;
    18.             //Kills Owl
    19.  
    20.         }
    21.         //Test
    22.         if (!Input.GetKeyDown("S")) //If key is not pressed within certian time
    23.         {
    24.             pressS = false;
    25.             //Reset screen Appears
    26.             StopCoroutine(Reset());
    27.             StartCoroutine(Reset());
    28.         }
    29.     }
    30.  
    31.         IEnumerator Reset()
    32.     {
    33.         Debug.Log("Reset Taking place")
    34.         yield return new WaitForSeconds (TimeLimit);
    35.  
    36.         //GameOverScreen Appears
    37.         gameOverPanel.SetActive (true);
    38.     }
    39. }
    40.  
    41. [CODE/]
     
  9. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Is this 30 second timer that you mentioned supposed to begin as soon as this script is activated or is there some other trigger/event that should start the countdown/check for key press?

    Your code right now is sort of like before, except there is only 1 coroutine.. However, the coroutine is stopped and restarted every frame for which you've not pressed the 's' key.

    If you add some logic as to when you'd start the timer, you could run it for 30 seconds.
    You could set a bool when the key is pressed. Now, inside the coroutine when the 30 seconds has elapsed, you can check that bool, and if it's true, exit, otherwise show the Reset screen.
     
  10. Mokzen

    Mokzen

    Joined:
    Oct 10, 2016
    Posts:
    102
    I would make another IEnumerator called CheckForReset, in which I waited for 30 seconds, then set a bool called "supposedToReset" to true.
    Then, in Update, I would check for when that bool becomes true, and when it does, I would call my ResetOwl method.

    I would start the CheckForReset Coroutine when I get an input of the type Input.GetKeyUp(KeyCode.S).
    Whenever the player presses the S-button, you would then kill the CheckForReset coroutine.

    In that way, when the player releases the S-button (in other words, the player is guaranteed to no longer be pressing the S-button), a timer is started to check whether the game should reset after 30 seconds.

    Does that make sense? I admit, I'm at work right now, and I tried to put some code down on NotePad, but I really can't do that, unless I want my head to explode, so I hope this helps a bit.

    @methos5k might be able to check if this solution is even going to work.
     
    Last edited: Mar 26, 2018