Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by NAiLz · Jul 20, 2016 at 02:39 PM · nullreferenceexceptionrandom.rangeeffectsarray of gameobjects

Need help with lightning randomization

Greetings smart people! I've searched for answers on this for 2 days and haven't found anything yet so I apologize if this has already been covered. I've modified a script that turns a directional light on and off randomly to simulate lightning. It also enables and disables lightning sprites as well. It's very easy to get one sprite to work over and over again since it really just requires plugging in a line of code in the flashOn() and flashOff() methods. One sprite just won't due though and so I've created an array and an index to capture a random sprite from the array. My logic is off somewhere though. The code "works" in that it will grab a random item from the array and enable it but the problem is that I think it moves on to another item in the array sometimes before the flashOff() method has a chance to turn off the last one enabled. I know this because now and then a lightning sprite will remain on the screen until the code cycles back to its index reference and shuts it off and I get NullReferenceExeption errors. If anyone can take a look and spot my flawed logic I'd really appreciate it. Here is the script:

 using UnityEngine;
 using System.Collections;
 
 public class LightningFlash : MonoBehaviour {
 
     public float minTime = 0.5f;                    // The minimum time between flashes
     public float threshhold = 0.5f;                // Value to check random value 
     public Light light;                            // Light creating lightning effect
     public GameObject[] lightningList;                // Lightning graphics list
 
     private int _index;                                // Index for lightningList
     private GameObject _currentLightning;            // Captures index value
     private GameObject _lastLightning;                // The last lightning object to be disabled
     private float _lastTime = 0;                        // Value for the last time lightning flashed
 
 
     void Update () 
     {
         _index = Random.Range (0, lightningList.Length);
 
         if((Time.time - _lastTime) > minTime)
         {
             if(Random.value > threshhold)
             {
                 _currentLightning = lightningList[_index];
 
                 flashOn();
             }
 
             else
             {
                 flashOff();
             }
 
             _lastTime = Time.time;
 
         }
 
     }
 
     void flashOn ()
     {
             light.enabled = true;
             _currentLightning.SetActive(true);
     }
 
     void flashOff ()
     {
         light.enabled = false;
         _currentLightning.SetActive(false);
     }
 }
 

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by hoogemast · Jul 21, 2016 at 02:34 PM

I guess there are 2 errors in your code at the moment. The first one is the nullpointerexception. You have a list of lightnings and a random range between 0 and lightning.lenght. This means that the an array of {lightning1,lightning2,lightning3,lightning4} is of length 4. Which means your Random.Range can be of value 4. When accessing the array you can have LightningList[4] which gives a nullpointerexception because it doesn't exist. The array indexes are running from zero, so the 4th element has index 3 and not index 4. An easy solution to fix this is by replacing this line:

   _index = Random.Range (0, lightningList.Length);

With this:

  _index = Random.Range (0, lightningList.Length-1); // NOTE THE -1

The second problem is the lightning not going off. I think this happens because you have a threshold of 0.5f to compare with a Random.value. Random.Value returns a random value between 0 and 1. If this value is lower than 0.5 it is smaller than threshold and the else condition will happen (lightning going off). If it is higher the if statement is true and there will be a new lightning in the list, but the else statement wont be executed. After some loops it will set its index back again and the lightning will go off. To quick fix your code you can add a variable to check if there is a current lightning like this, but there are many other options:

  void Update () 
  {
      _index = Random.Range (0, lightningList.Length);
 
      if((Time.time - _lastTime) > minTime)
      {
          if(flashIsOff) //set this as a boolean in your class
          {
              _currentLightning = lightningList[_index];
 
              flashOn();

              flashIsOff = false;
          }
 
          else
          {
              flashOff();

              flashIsOff=true;
          }
 
          _lastTime = Time.time;
 
      }
 
  }

In this case you won't need to create a threshold variable, but maybe you would like to prevent the lightning to happen once in a while.

Next time make sure that you know what the random function does since both of your errors are coming from this function. Here is the link to the documentation. I hope this answer will help. Have fun coding.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image NAiLz · Jul 21, 2016 at 02:41 PM 0
Share

@hoogemast

Thanks so much! The index problem was causing all the problems even with my case switch solution. Noob mistake. Thanks alot for the reply.

avatar image
0

Answer by NAiLz · Jul 21, 2016 at 04:29 PM

I managed to find a fix using a switch statement and even added some randomization for the duration of the lightning flashes as follows:

 using UnityEngine;
 using System.Collections;
 
 public class LightningFlash : MonoBehaviour {
 
     public float minTime = 0.5f;                // The minimum time between flashes
     public float threshhold = 0.5f;                // Value to check random value 
     public Light light;                            // Light creating lightning effect
     public GameObject[] lightningList;            // Lightning graphics list
 
     public FlashState flashState;                // Enum for case switch storage
     public float flashTimer;                    // Timer allowing for longer flashes
     public float maxFlash;                        // Longest flash allowed
 
     private int index;                                // Index for _lightningList
     private GameObject _currentLightning;            // Captures index value
     private GameObject _lastLightning;                // The last lightning object to be disabled
     private float _lastTime = 0;                    // Value for the last time lightning flashed
 
 
     void Update () 
     {
         index = Random.Range (0, lightningList.Length - 1);
         maxFlash = Random.Range (0.5f, maxFlash);
 
         switch (flashState)
         {
         case FlashState.Ready:
 
             _currentLightning = lightningList[index];
 
             if((Time.time - _lastTime) > minTime)
             {
                 if(Random.value > threshhold)
                 {
                     //_currentLightning = lightningList[index];
 
                     flashOn();
                 }
 
                 flashState = FlashState.Flashing;
             }
             break;
 
         case FlashState.Flashing:
             flashTimer += Time.deltaTime * 3;
             if(flashTimer >= maxFlash)
             {
                 flashTimer = maxFlash;
                 flashOff();
                 _lastTime = Time.time;
                 flashState = FlashState.Cooldown;
             }
             break;
 
         case FlashState.Cooldown:
             flashTimer -= Time.deltaTime *3;
             if(flashTimer <= 0)
             {
                 flashTimer = 0;
                 flashState = FlashState.Ready;
             }
             break;
         }
 
     }
 
     void flashOn ()
     {
             light.enabled = true;
             _currentLightning.SetActive(true);
     }
 
     void flashOff ()
     {
         light.enabled = false;
         _currentLightning.SetActive(false);
     }
 }
 
 public enum FlashState
 {
     Ready,
     Flashing,
     Cooldown
 }
 







Thanks to @hoogemast for the index fix.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Generate random no and active that GO using array 1 Answer

How can I define a box using Camera.ScreenToWorldPoint? 2 Answers

NullException Error With Array of GameObjects 2 Answers

onclick on random objects in gamemode and update score 1 Answer

Randomizing a selection from an array 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges