Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Automated lights with a list

Discussion in 'Scripting' started by cruising, Apr 5, 2020.

  1. cruising

    cruising

    Joined:
    Nov 22, 2013
    Posts:
    329
    Hello!

    How do i make this list code to work with the "intensity" of the lights?
    Or is there some other way you add lights in a list?
    Code (CSharp):
    1. error CS1061: Type `System.Collections.Generic.List<UnityEngine.Light>' does not contain a definition for `intensity' and no extension method `intensity' of type `System.Collections.Generic.List<UnityEngine.Light>' could be found. Are you missing an assembly reference?
    Full Code

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class AutomatedLights : MonoBehaviour
    6. {
    7.     public List <Light> lights = new List<Light>();
    8.     public float IntensityOn = 1;
    9.     public float IntensityOff = 0;
    10.  
    11.     void OnTriggerEnter(Collider other)
    12.     {
    13.         if (other.tag == "Player")
    14.         {
    15.             lights.intensity = IntensityOn;
    16.             }
    17.         }
    18.  
    19.     void OnTriggerExit(Collider other)
    20.     {
    21.         if (other.tag == "Player")
    22.         {
    23.             lights.intensity = IntensityOff;
    24.         }
    25.     }
    26. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,517
    I see what you're trying to do but I'm afraid this is C#, not ADA. :) Alas, C# does not support such set distributive operations.

    Instead of trying to set .intensity on the List object, you have to iterate the elements in the list and set each one:

    Code (csharp):
    1. foreach( var L in lights) L.intensity = IntensityOn;
     
    SolarFalcon likes this.
  3. cruising

    cruising

    Joined:
    Nov 22, 2013
    Posts:
    329
    Ah! Thank you very much! :D:D
    Trying now to dim the lights so they dont instantly light up and down, but cant find any on google for that, or any tutorials.
    If you know any tutorial please link :)
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,517
    You can either make a coroutine to dim/brighten it over a period of frames, but then that runs into the issue of what to do with that coroutine if you quickly run in and out... it can be done with StopCoroutine but it gets messy AF really fast and you will have to figure out how bright the lights were at the moment you changed, etc.

    Instead, I like to have two variables for the intensity:

    One variable is the
    DesiredIntensity
    and one variable is the
    CurrentIntensity
    .

    Every Update() you would see if
    CurrentIntensity
    is below
    DesiredIntensity
    and if so, move it up. Same goes if it is above.

    The key is when you "cross" over DesiredIntensity (detect it going up separately from detect it going down), you want to be sure to assign DesiredIntensity directly into CurrentIntensity, because with floating point values they will NEVER otherwise be identical. Setting them identical and testing them for equality is reliable in this case and you can use that to NOT be driving the intensities every frame, which is computationally wasteful.

    roughly,

    Code (csharp):
    1. bool needUpdate = false;
    2.  
    3. if (current < desired)
    4. {
    5.  needUpdate = true;
    6.  current += adjustRate * Time.deltaTime;
    7.  if (current > desired) current = desired;
    8. }
    9.  
    10. if (current > desired)
    11. {
    12.  needUpdate = true;
    13.  current -= adjustRate * Time.deltaTime;
    14.  if (current < desired) current = desired;
    15. }
    16.  
    17. // now only update your lights if needUpdate is true!
    18. if (needUpdate)
    19. {
    20.   // put light update code here, updating it to current
    21. }
    22.  
    This way if you run in and back out of the trigger, wherever the lights were at that moment, they'll just reverse and start going the other way smoothly, no jerk or blink.
     
    SolarFalcon likes this.
  5. cruising

    cruising

    Joined:
    Nov 22, 2013
    Posts:
    329
    Im not the brightest coder in this world, so i hope i did anything right with your code.
    But i have done something wrong, because if i set the "adjust rate" to "1" the light only goes up to 0.14 and goes down to 0.04, and with "adjust rate" 9 it works fine but the lights is nearly instantly on and off and "current" goes up to 1

    Take a look and tell me what i have done wrong please:oops:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class AutomatedLights : MonoBehaviour
    6.    {
    7.     public List<Light> lights = new List<Light>();
    8.     //public float IntensityOn = 1;
    9.     //public float IntensityOff = 0;
    10.     public bool needUpdate = false;
    11.     public float current = 0f;
    12.     public float desired = 1f;
    13.     public float adjustRate = 1f;
    14.  
    15.  
    16.     void OnTriggerEnter(Collider other)
    17.     {
    18.         if (other.tag == "Player")
    19.         {
    20.             if (current < desired)
    21.             {
    22.                 needUpdate = true;
    23.                 current += adjustRate * Time.deltaTime;
    24.                 if (current > desired) current = desired;
    25.             }
    26.             // now only update your lights if needUpdate is true!
    27.             if (needUpdate)
    28.             {
    29.                 foreach (var L in lights) L.intensity = current;
    30.                 desired = 1f;
    31.             }
    32.  
    33.             //foreach (var L in lights) L.intensity = IntensityOn;
    34.         }
    35.     }
    36.  
    37.     void OnTriggerExit(Collider other)
    38.     {
    39.         if (other.tag == "Player")
    40.         {
    41.             if (current > desired)
    42.             {
    43.                 needUpdate = true;
    44.                 current -= adjustRate * Time.deltaTime;
    45.                 if (current < desired) current = desired;
    46.             }
    47.  
    48.             // now only update your lights if needUpdate is true!
    49.             if (needUpdate)
    50.             {
    51.                 foreach (var L in lights) L.intensity = current;
    52.                 desired = 0f;
    53.             }
    54.  
    55.             //foreach (var L in lights) L.intensity = IntensityOn;
    56.         }
    57.     }
    58. }
     
    Last edited: Apr 5, 2020
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,517
    ALL of the code I wrote in my post above needs to go in Update(). Be sure to also include only one instance of the foreach light loop inside the if (needUpdate), but it has to all go in Update().

    Inside the OnTrigger-ish calls, after checking the tag, ONLY put in the assignment to desired. Don't do anything else in there.
     
  7. cruising

    cruising

    Joined:
    Nov 22, 2013
    Posts:
    329
    Seams like i cant get the triggers to cooperate with the update(). what ever i do, Update() keep rise the intensity when you not enter or exit the trigger or start the game.
    How i want it to work is if you set the "desired" to 1, and when you enter the trigger, "current" will equal the "desired" and when exit "current" will go down to 0 and "desired" is still 1. "desired" should be some sort of a reference of max intensity.
    I dont know if that is how this should work? but some how i need to prevent the update() to update when your not enter or exit the trigger. :)

    EDIT:

    I had to add 1 more float to fix this, so now it works and i can manually set how much intensity i want for each room
    Here is the full code:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class AutomatedLights : MonoBehaviour
    6.    {
    7.     public List<Light> lights = new List<Light>();
    8.     public bool needUpdate = false;
    9.     public float current = 0f;
    10.     float desired = 0f;
    11.     public float wanted = 1f;
    12.     public float adjustRate = 9f;
    13.  
    14.  
    15.     private void Update()
    16.     {
    17.         bool needUpdate = false;
    18.         if (current < desired)
    19.         {
    20.             needUpdate = true;
    21.             current += adjustRate * Time.deltaTime;
    22.             if (current > desired) current = desired;
    23.         }
    24.  
    25.         if (current > desired)
    26.         {
    27.             needUpdate = true;
    28.             current -= adjustRate * Time.deltaTime;
    29.             if (current < desired) current = desired;
    30.         }
    31.  
    32.         // now only update your lights if needUpdate is true!
    33.         if (needUpdate)
    34.         {
    35.             foreach (var L in lights) L.intensity = current;
    36.         }
    37.     }
    38.  
    39.     void OnTriggerEnter(Collider other)
    40.     {
    41.         if (other.tag == "Player")
    42.         {
    43.             desired = wanted;
    44.         }
    45.     }
    46.  
    47.     void OnTriggerExit(Collider other)
    48.     {
    49.         if (other.tag == "Player")
    50.         {
    51.             desired = 0f;
    52.         }
    53.     }
    54. }
     
    Last edited: Apr 6, 2020