Enabling/Disabling fire based on time of day

Hello,

I am still very very new to all this unity stuff. I have been doing google searches for most of everything I have today with a few asset purchases as well. Now that I have a test environment I am starting to play around with scripts and game objects. One of the current things I am working on is fires. I have a torch that is going to be set out and I want it to light when it’s dark and go out when its daylight. I am currently using Enviro for my day/night cycles. Is there somewhere someone can point me to a script to make this happen? I will continue searching around for it in the meantime, but since I am still new it would take me forever to attempt to do this myself.

Thanks in advance.

Hey there, welcome to Unity.

I have a few things that come to mind after reading your post.

I would say when you’re starting out, it would be better to start with smaller tutorials that show you some core/key concepts. Unity interface + essentials, scripting beginner stuff, and one or a few simple games (small ones).
I know that it seems a lot more fun to have better assets and everything, but right now you’re only able to add things you find online, by pasting (or using) and have not learned what to do.
Some assets are quite advanced, so there is no argument there that those can serve a great benefit, and using them compared to making your own can be helpful.
I still think learning a good portion yourself will help you so much.

However, more to your question: I have no knowledge of that asset. I recently read about it, so I know it exists, but that’s it. If you can find in its code a method that gets called when the day/night changes, you could use that to notify another script of the change.
Beyond that, it’s virtually impossible to give you a specific answer, because … well, I have no idea what the code for that looks like :wink:

One more “however”… if you know the time that a day/night cycle will last, you can get a very close approximation in your own script, and using a coroutine (or Invoke) with an appropriate time to wait, then change your torch on / off. It might be 99.7% accurate, but darn close.

I think you could do something like:

public ParticleSystem particles;

void Start(){
particles = gameObject.GetComponent<ParticleSystem>();
}

public void StartParticles(){
particles.Play();
}

public void StopParticles(){
particles.Stop();
}

put the script on the torch object

Now you just need a reference to the GameObject torch, or the script name, on some script that tells you when day starts and night starts in Enviro. I have no idea how to do that since I haven’t seen that asset.

Thank you fire7side. I will keep this in mind while I’m “dissecting” the enviro script. It’s pretty lengthy at 807 lines but it is a good way for me to learn what all is going on in this script. Once I figure out exactly what it is doing, I can then figure out how to reference it.

Thank you for your reply Methos5k. I have been taking a few different classes both on the unity training section as well as Udemy. I will be taking many more lessons from several sources but I am more of a hands-on person that likes to dive in and learn by doing. I do not put aside the value of the training courses though, as I get to “get my hands dirty” by building things. I have started with the roll a ball game and moved on to a 1 level with a boss fight 2D game so far. I have taken a few C# classes as well and just recently got access to Pluralsight’s training so will be starting that soon.

This torch script I’m looking to do is just me learning how to tie things in other assets together. I have learned how to make assets work on their own, but now need to explore how they work with other things. This is a pretty small feat to work on lights with a time of day I think, I am just not experienced enough to do it without some assistance.

In one of my tutorials, I made a little basic script to turn off a game object at start. Obviously this works just fine since its just a line.

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

public class ActiveObjects : MonoBehaviour {

    // Use this for initialization
    void Start () {
        gameObject.SetActive(false);
    }
  
    // Update is called once per frame
    void Update () {
      
    }
}

And I think I found the day/night cycle script here:

using UnityEngine;
using System.Collections;

public class EnviroDayNightSwitch : MonoBehaviour {

    private Light[] lightsArray;

    void Start () {

        lightsArray = GetComponentsInChildren<Light> ();

        EnviroSky.instance.OnDayTime += () =>
        {
            Deactivate () ;
        };

        EnviroSky.instance.OnNightTime += () =>
        {
            Activate () ;
        };

        if (EnviroSky.instance.isNight)
            Activate ();
        else
            Deactivate ();
    }
   

    void Activate ()
    {
        for (int i = 0; i < lightsArray.Length; i++) {
            lightsArray [i].enabled = true;
        }

    }

    void Deactivate ()
    {
        for (int i = 0; i < lightsArray.Length; i++) {
            lightsArray [i].enabled = false;
        }
    }

}

Now I need to figure out how to reference the cycle to determine if its day or night, then enable/disable the gameobject from there.

Cool… Looks like in that code that it’s daytime when ‘Deactivate’ is called. Is that what you meant?
Sounds like you’re having a good time, btw. And a good mix of learning & doing which also sounds good. =)

1 Like

This is the code that came with Enviro, Its not mine. That is correct that deactivated means daytime. However, this just activates the nighttime “scene” which is the different lighting i believe. I would like someone to add the torches to this code, or use a script attached to the firs on the torches that says something like “if (envirosky.instance.isNight) then turn on the fire. else turn off” obviously in code. not too sure which would be right. I tried to mess with both but had not much luck.

In your torch script, create 2 methods (1 for on , and 1 for off), if you haven’t already.
Then, copy the example they have there.
Inside a script on the torch:

void OnEnable() {
EnviroSky.instance.OnDayTime += DayTime;
EnviroSky.instance.OnNightTime += NightTime;
}
public void DayTime() {
  // turn off torch light.
}
public void NightTime(){
   // light torch
}
void OnDisable() {
EnviroSky.instance.OnDayTime -= DayTime;
EnviroSky.instance.OnNightTime -= NightTime;
}

Something like that?

Edit: fixed a typo and added the public modifier to the methods for the event.

Well, that worked out well. Nice job guys.

I have taken your code and implemented it but I still think I’m doing something wrong. I’m trying to watch some videos on how to fix this but can’t seem to put the right fields in there. This is what I have ended with tonight before bed. I will work again on it in the morning. Also, this is my current error:

NullReferenceException: Object reference not set to an instance of an object
ActiveComponentTorch.OnDisable () (at Assets/Torches/Script/ActiveComponentTorch.cs:54)

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

public class ActiveComponentTorch : MonoBehaviour {


    // Use this for initialization
    void Start () {

    }
   
    // Update is called once per frame
    void Update () {

    }
    void OnEnable()
    {
        EnviroSky.instance.OnDayTime += DayTime;
        EnviroSky.instance.OnNightTime += NightTime;
    }
    public void DayTime()
    {
        // turn off torch light.
        if (gameObject.tag == "Fire")
            PowerOff();
    }

    private void PowerOff()
    {
            gameObject.SetActive(false);
    }

    public void NightTime()
    {
        // light torch
        if (gameObject.tag == "Fire")
            PowerOn();
    }

    private void PowerOn()
    {
        gameObject.SetActive(true);
    }

    void OnDisable()
    {
        EnviroSky.instance.OnDayTime -= DayTime;
        EnviroSky.instance.OnNightTime -= NightTime;
    }
}

A couple of notes and a question! :slight_smile:

Question first: Does it work for them turning on/off ? :slight_smile:

Notes:

  1. I do not think you will need to check your own tag , as this script should only be on a game object that you want to use it, I would imagine.
  2. If the script is otherwise working, and you’re only getting that error when closing the game or something like that, it could be that the instance of EnviroSky has been destroyed before this script’s OnDisable is called.
    In other words, safely ignored; though you could write code to check if it’s null, if you really wanted to.

The script does not seem to be turning them on and off. I start the scene out and on play the error pops up.

I do have the script attached to the game object. If I put

    void Start () {
        gameObject.SetActive(false);
    }

in the script then it will start the frame as turned off. I almost feel like I’m missing something in update that would check this every frame.

3330160--259545--Script.PNG

Ack! It’s my bad. When I wrote those scripts, I had meant to ask if you were disabling just the flame or the whole game object.
Since I can’t see the EnviroSky script, could you check if it creates the 'Instance" variable (assignment) in Start() ? If that’s the case, you will have to delay your Event subscription for 1 frame, in a coroutine, maybe.
If it creates the instance variable in Awake, then just copy the code from OnEnable to Start and comment out the OnDisable code for now and see if that works.

Its on start. There are no awake fields in the scripts. (i posted the EnviroDayNightSwitch.cs above in my 3rd post if you want to verify.) I also found another script that is called EnviroSetSystemTime.cs and it doesn’t have much in there. I have been doing some learning on the variables it has in it to see if its something I can use and maybe just turn them on with the time that it uses:

using UnityEngine;
using System.Collections;

public class EnviroSetSystemTime : MonoBehaviour {

    void Start ()
    {
        if (EnviroSky.instance != null) {
            EnviroSky.instance.SetTime (System.DateTime.Now);
        }

    }

}

Okay, well try this, in your script.
(comment out the OnEnable/OnDisable to test) and add:

// changing your Start method

// this should wait 1 frame, ensuring that this method is called after the one from your
// previous post; what was happening before was the other script ran after this one,
// so our code couldn't find the variable being set there.
IEnumerator Start() {
  // your own code, not related to the event
  yield return null;
  EnviroSky.instance.OnDayTime += DayTime;
  EnviroSky.instance.OnNightTime += NightTime;
  }

I still dont see it doing anything. But thank you for giving me another thing to research into. I havnt seen IEnumerator so thats something to learn!

Here is what my torch script currently looks like. I have spent this morning in between working to test out some thing I have been seeing on the web, none working of course.

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

public class ActiveComponentTorch : MonoBehaviour {

    // Use this for initialization
    IEnumerator Start () {
        yield return null;
        EnviroSky.instance.OnDayTime += DayTime;
        EnviroSky.instance.OnNightTime += NightTime;
    }
   
    // Update is called once per frame
    void Update () {

    }
//   void OnEnable()
//   {
//       EnviroSky.instance.OnDayTime += DayTime;
//       EnviroSky.instance.OnNightTime += NightTime;
//   }
    public void DayTime()
    {
        // turn off torch light.
              if (gameObject.tag == "Fire")
                  PowerOff();
    }

    private void PowerOff()
    {
            gameObject.SetActive(false);
    }

    public void NightTime()
    {
        // light torch
        if (gameObject.tag == "Fire")
            PowerOn();
    }

    private void PowerOn()
    {
        gameObject.SetActive(true);
    }

//   void OnDisable()
  //  {
  //      EnviroSky.instance.OnDayTime -= DayTime;
//       EnviroSky.instance.OnNightTime -= NightTime;
  //  }
}

Okay, well you don’t have any errors, right?

One important question here is, did you leave the game object active in the hierarchy ? :slight_smile:
If it’s not active, Start will not be running :slight_smile:

I tried it both ways just to make sure. If it starts active, it stays active, and if it starts inactive, it stays inactive.

I do not see any errors in Unity.

Okay! hang on this is a step-by-step process. :slight_smile:
So, please keep it active at the start, and here is the modified code to deal with (if your game is night time when starting):

IEnumerator Start () {
        yield return null;
        EnviroSky.instance.OnDayTime += DayTime;
        EnviroSky.instance.OnNightTime += NightTime;
        if (!EnviroSky.instance.isNight) DayTime();  // since it's on by default, we turn it off if it's night.
    }

So whatever that is, it works. A little different then what I understand with your comments, but its exactly what I want. I set it to night and i didn’t notice anything but for the sake of it, I set it back to daytime and when I hit start it shut off the fire. I waited until night time and the fire turned on!!!