Creating a 'flexible' police lightbar?

Hey everyone, I’m creating a script in which I can assign up to 4 lights and set their rotation. It’s for something like police lights. Right now you can assign lights to the script, set their rotation offset (so one light starts with a 30 degrees offset, another light with a 60 degrees offset, etc).

One thing I can’t figure out is how to continuesly rotate all assigned lights with one variable. I can place all lights in one function Update() but if one light isn’t assigned to lights after that one don’t rotate. So if for instance light 1 and 4 are assigned, only light 1 is spinning because lights 2 and 3 aren’t assigned. All assigned lights have to rotate no matter how many lights are assigned. Can anyone help me out here?

var RotatingLight01 : GameObject;
var Offset01 : float = 0;
{
RotatingLight01.transform.Rotate(Offset01,0,0);
}
var RotatingLight02 : GameObject;
var Offset02 : float = 0;
{
RotatingLight02.transform.Rotate(Offset02,0,0);
}
var RotatingLight03 : GameObject;
var Offset03 : float = 0;
{
RotatingLight03.transform.Rotate(Offset03,0,0);
}
var RotatingLight04 : GameObject;
var Offset04 : float = 0;
{
RotatingLight04.transform.Rotate(Offset04,0,0);
}

var rotationsPerMinute : float = 10.0;
function Update()
{
     RotatingLight01.transform.Rotate(6.0*rotationsPerMinute*Time.deltaTime,0,0);
     RotatingLight02.transform.Rotate(6.0*rotationsPerMinute*Time.deltaTime,0,0);
     RotatingLight03.transform.Rotate(6.0*rotationsPerMinute*Time.deltaTime,0,0);
     RotatingLight04.transform.Rotate(6.0*rotationsPerMinute*Time.deltaTime,0,0);
}

Something with the last part isn’t working but I can’t figure out what it is exactly (other than the function Update not going past a light that isn’t assigned.

this is a simple solution but it’s not good code

function Update()
{
    if(RotatingLight01 != null)
    {
        RotatingLight01.transform.Rotate(6.0*rotationsPerMinute*Time.deltaTime,0,0);
    }
    if(RotatingLight02 != null)
    {
        RotatingLight02.transform.Rotate(6.0*rotationsPerMinute*Time.deltaTime,0,0);
    }
    if(RotatingLight03 != null)
    {
        RotatingLight03.transform.Rotate(6.0*rotationsPerMinute*Time.deltaTime,0,0);
    }
    if(RotatingLight04 != null)
    {
        RotatingLight04.transform.Rotate(6.0*rotationsPerMinute*Time.deltaTime,0,0);
    }

}

It actually works like a charm. What makes this not good code? And what would I need to do to make it better?

when you repeat code, this is not good.
here is what i would do. Via C#, not that crazy JavaScript crap.
two scripts, a lightmanager script, think of this as the cop car. so all the lights are sub objects on the car.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class LightManager : MonoBehaviour {

    public CopLight[] LightList;
    public float rotationsPerMinute = 50.0f;
    // Use this for initialization
    void Start () {
        LightList = GetComponentsInChildren<CopLight>();
        Debug.Log(LightList.Length);
    }
  
    // Update is called once per frame
    void Update () {
  
        for(int i = 0; i < LightList.Length; i++)
        {
            if(LightList[i].isOn)
            {
                LightList[i].transform.Rotate(6.0f * rotationsPerMinute * Time.deltaTime, 0, 0);
            }
        }
    }
}

then the light script

using UnityEngine;
using System.Collections;

public class CopLight : MonoBehaviour {

    public float Offset;
    public bool isOn = true;

    void Start()
    {
        transform.Rotate(Offset, 0, 0);
    }
}

as you can see there is a lot less code. it does that same thing, and I added an isOn option. so you turn a single light on or off.

Screen shots of my test scene

Thanks! It’s working perfectly. I’ve now made it that the lights can be turned on or off, as well as a seperate siren. The code you provided me with hasn’t been altered. Instead I created a seperate script for the switching on and off, as well as asigning the siren-sound.

This is now my Siren.cs

using UnityEngine;
using System.Collections;

public class Siren : MonoBehaviour {
    private Light lights;
    public GameObject lightParent;
    private AudioSource Sound;
    public AudioClip Siren1;
    public AudioClip Siren2;

    void Awake()
    {
        Sound = GetComponent<AudioSource> ();
    }

    void Start()
    {
       
    }

    void Update ()
    {
        Light[] lights = lightParent.GetComponentsInChildren<Light>(true);   
        foreach (Light light in lights)
        {
            if (Input.GetKeyUp (KeyCode.F))
            {
                light.enabled = !light.enabled;
                Sound.loop = true;
                Sound.clip = Siren2;
                Sound.Play ();
            }
            if (light.enabled == false){
                if (Sound.isPlaying) {
                    Sound.Stop ();
                } else
                    Sound.Play ();

        }
    }
}
}

The ultimate goal is to be able to switch through different modes.
Mode 1 = off
Mode 2 = lights only
Mode 3 = lights and sound
And an alternative for both Mode 2 and 3 is when you hold F (in this case) that the other siren plays. When you release it should resume whatever mode it’s in. I’ve been trying for about 4 hours now to get that working but without succes. I got it to play the other siren but the sound was distorted and after I released the key everything stopped.

Any tips as to how to tackle this last problem? :slight_smile:

hope this helps. it’s not a direct answer, I can’t give away everything. This should point you in a direction.

using UnityEngine;
using System.Collections;
public class Siren : MonoBehaviour {
    private Light lights; // i don't see this being used
    public GameObject lightParent;
    private AudioSource Sound;
    public AudioClip Siren1;
    public AudioClip Siren2;
    void Awake()
    {
        Sound = GetComponent<AudioSource> ();
    }
    void Start()
    {
      
    }
    void Update ()
    {
        Light[] lights = lightParent.GetComponentsInChildren<Light>(true);  //this is bad.  doing a getComponent in update is very costly in proformance
        foreach (Light light in lights)
        {
            if (Input.GetKeyUp (KeyCode.F))  //if the f key was released
            {
                light.enabled = !light.enabled; //toggle the light.enabled bool, so if ON = off, and Off = On.
                //play siren2
                Sound.loop = true;
                Sound.clip = Siren2;
                Sound.Play ();
            }
            if (light.enabled == false) //check if light.enabled = no, If if the light is Off play siren1
            {
                if (Sound.isPlaying) //this will stop Siren1 and siren2 every frame.  you should check what clip is playing,  only stop if clip = siren2
                {
                    Sound.Stop ();
                }
                else
                {
                    //play siren1
                    Sound.loop = true;
                    Sound.clip = Siren1;
                    Sound.Play ();
                }
            }
        }
    }
}

I like this and at the same time it’s driving me nuts. So I went back to the script and ripped out pretty much everything. The sound, the lights, all gone. I placed some code to count how many time the F key is being pressed. So if it’s pressed once only the lights can come on, if it’s pressed twice it’s lights and siren and if it’s pressed a third time everything turns off. So I added this:

void Update ()
    {

        {
            if (Input.GetKeyDown (KeyCode.F))

            {
                lastPressed += 1;
            }

            if (lastPressed > 2)
           
            {
                lastPressed = 0;
            }

            if (lastPressed == 1) {
                Debug.Log ("You clicked Once!");
                    }
            if (lastPressed == 2)
        {
                    Debug.Log("You clicked Twice!");
                }
                   
                }
            }

Works like charm. After that I moved the GetComponentsinChildren code to void Start() and that’s where the trouble starts. Right now it’s narrowed down to one problem: light.enbled = !light.enabled; doesn’t work anymore. Here’s the full script as it is right now:

using UnityEngine;
using System.Collections;

public class Siren : MonoBehaviour {
    private int lastPressed = 0;
    private Light[] lights;
    public GameObject lightParent;
    private AudioSource Sound;
    public AudioClip Siren1;
    public AudioClip Siren2;

    void Awake()
    {
        Sound = GetComponent<AudioSource> ();


    }
    void Start()
    {
        lights = lightParent.GetComponentsInChildren<Light>(true);
        //this is bad.  doing a getComponent in update is very costly in proformance
        foreach (Light light in lights) {
           
        }
    }
    void Update ()
    {

        {
            if (Input.GetKeyDown (KeyCode.F))

            {
                lastPressed += 1;
            }

            if (lastPressed > 2)
           
            {
                lastPressed = 0;
            }

            if (lastPressed == 1) {
                Debug.Log ("Once");
                light.enabled = !light.enabled; //toggle the light.enabled bool, so if ON = off, and Off = On.
                    }
            if (lastPressed == 2)
        {
                    Debug.Log("You clicked Twice!");
                }
                   
                }
            }
}

Everything is pretty much exactly the same codewise as it was before except that one part has moved to void Start. So I’m drawing a blank here. Also can’t find much about this specific subject matter online.

By the way, since you’ve been so helpful I’m gonna release an asset for this when it’s done so that everyone can use it, because when it works it looks beautiful the way I’ve done it (spotlights and trancelucent materials).

I think I know where the problem is.
At the start of the game, when you press play, are the light object enabled or disabled? the transform has a check box on the top left side.
If it starts as disabled the GetComponentsInChildren will not find them.

updated code as well, you have a few brackets messed up and extra ones

using UnityEngine;
using System.Collections;

public class Siren : MonoBehaviour {
    private int lastPressed = 0;
    private Light[] lights;
    public GameObject lightParent;
    private AudioSource Sound;
    public AudioClip Siren1;
    public AudioClip Siren2;

    void Awake()
    {
        Sound = GetComponent<AudioSource> ();


    }
    void Start()
    {
        lights = lightParent.GetComponentsInChildren<Light>();
        foreach (Light light in lights) 
        {
           light.enabled = false; //turn off the light at start of game
        }
    }
   
    void Update ()
    {
            if (Input.GetKeyDown (KeyCode.F))
            {
                lastPressed += 1;
           
                if (lastPressed > 2)
                {
                    lastPressed = 0;
                }
               
                if(lastPressed == 0)
                {
                    Debug.Log ("All Off");
                    //turn Off the lights
                    foreach (Light light in lights) 
                    {
                    light.enabled = false; //turn off the light at start of game
                    }
                    //turn siren off
                }
                else if(lastPressed == 1) 
                {
                    Debug.Log ("Once");
                    //turn on the lights
                    foreach (Light light in lights) 
                    {
                    light.enabled = true; //turn on the light at start of game
                    }
                }
                else if (lastPressed == 2)
                {
                        Debug.Log("You clicked Twice!");
                        //do stuff for the sirens
                }
            }
    }
}

You are a light saver! Works like a charm! I’m gonna add something little tomorrow and than it’s done :slight_smile: I’ll release everything once it’s done with major credits to you. I think other people can appreciate this script as well. In Dutch I would call you an ‘eindbaas’ which roughly translates to kickass person. Thanks dude!

send me the link to it when you post it