Can anyone help me script a light to turn on and off by pressing E when player is in range? I searched every where. Or could you point me to where I can learn it myself?
If you have not gone through Create with Code - Unity Learn then I would go through that first. It will teach you most basic scripting concepts, including activating things using triggers + input which is one way to tackle this.
Okay thank you, I will follow your link and go from there.
Anyone know where I can learn to script a light to come on/off when the player collider enters a trigger and hits E? Ive been doing the classes mentioned above since I made this post but no luck on learning about a light switch.
You’re not going to find your exact specific requirement in any tutorial or video. You need to learn the concepts and combine them.
- Figure out how to turn a light on/off in a script.
- Figure out how to get code running that responds to triggers
- Figure out how to get code running that responds to input
- Combine all of the above to get your desired effect.
The way to approach this also depends on the type of game you want to make. You would want to go a different route for a first person game where your crosshair would have to be on the button exactly, than for a 2d platformer or 3rd person game.
It’s a 3rd person I made some houses in blender and made the doors and windows work. My light is working when my player enters the trigger and I press E the light will turn on and off but not every time. I’m using a script with a bool. I’ll post the script below to see if anyone can tell what’s wrong.
Does it matter that the light is on in the scene when I hit play? Thanks for your help guys.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LightSwitch : MonoBehaviour {
public GameObject light;
private bool on = false;
// Use this for initialization
void OnTriggerStay(Collider plyr) {
if (plyr.tag == "Player" && Input.GetKeyDown(KeyCode.E) && !on)
{
light.SetActive(true);
on = true;
}
else if (plyr.tag == "Player" && Input.GetKeyDown(KeyCode.E) && on)
{
light.SetActive(false);
on = false;
}
}
}
Thanks for posting your code! Your script is ALMOST there. The only problem is that OnTriggerStay is part of the physics update. The physics update doesn’t run every frame (by default, it runs 50 times per second). On the other hand, Input.GetKeyDown will only return true duriong the EXACT frame when the button is pressed. So if your framerate is faster than 50 FPS, occasionally you will press the button and it will unfortunately happen during one of the frames when OnTriggerStay does not run.
To fix this, you should capture your input in Update, and consume it in OnTriggerStay. Update runs every frame so it will never miss Input like physics functions can. Something like this:
public class LightSwitch : MonoBehaviour {
public GameObject light;
private bool on = false;
bool pressedButtonThisFrame = false;
private void Update() {
pressedButtonThisFrame = Input.GetKeyDown(KeyCode.E);
}
// Use this for initialization
void OnTriggerStay(Collider plyr) {
if (plyr.tag == "Player" && pressedButtonThisFrame && !on) {
// consume the button press
pressedButtonThisFrame = false;
light.SetActive(true);
on = true;
}
else if (plyr.tag == "Player" && pressedButtonThisFrame && on) {
// consume the button press
pressedButtonThisFrame = false;
light.SetActive(false);
on = false;
}
}
}
Some more details about how and when different Unity callback functions like Update are called can be found here: https://docs.unity3d.com/Manual/ExecutionOrder.html
Finally, here’s an alternative way to write your script that I think is a little cleaner:
public class LightSwitch : MonoBehaviour {
public GameObject light;
private bool playerInside = false;
private void Update() {
if (playerInside && Input.GetKeyDown(KeyCode.E)) {
light.SetActive(!light.activeSelf);
}
}
private void OnTriggerEnter(Collider other) {
if (other.CompareTag("Player")) {
playerInside = true;
}
}
private void OnTriggerExit(Collider other) {
if (other.CompareTag("Player")) {
playerInside = false;
}
}
}
Thanks for your help and showing me an example of how you would do it. I got It working a different script I can post it later for you to see. I see there’s a lot of ways to type code and get same result. I had ended up using OnTriggerEnter and Exit. Now that I got this working I’m stuck trying to play an amin to open door from pressing F while on trigger and then be able to press F again to play the close anim. I may post a thread about it to, if you could maybe check it out when I do. Thanks again.
Sorry but this has the same issue as the original code ^^. Because you set state of “pressedButtonThisFrame” every frame. So if there is no physics update the frame it’s set to true, it would be set to false the next frame and won’t be detected. You probably wanted to do:
private void Update() {
if (Input.GetKeyDown(KeyCode.E))
pressedButtonThisFrame = true;
}
Ah you’re right. But then you have the problem where you can press the button and then 5 seconds later walk into the trigger and it will activate the light.
In any case my second example script is a lot better anyway.
Can you tell what I’m doing wrong here? I’m trying to get my door working kind of like I did the light. I think I 'm messing up the bool. The door will open and close with F or G but it will run G when the doors closed not only when open.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class doorFunction4 : MonoBehaviour
{
public bool onTrigger;
public bool doorOpen;
public Animator anim;
public GameObject theDoor;
void Start()
{
anim = GetComponent<Animator>();
}
void OnTriggerEnter(Collider other)
{
onTrigger = true;
}
void OnTriggerExit(Collider other)
{
onTrigger = false;
}
void Update()
{
if (theDoor.active == true)
{
doorOpen = true;
}
else
{
doorOpen = false;
}
if (onTrigger)
{
if (doorOpen)
{
if (Input.GetKeyDown(KeyCode.F))
{
anim.Play("DoorScreenFrontOpen");
}
else if (Input.GetKeyDown(KeyCode.G))
{
anim.Play("DoorScreenFrontClose");
}
}
}
}
void OnGUI()
{
if (onTrigger)
{
if (doorOpen)
{
GUI.Box(new Rect(0, 0, 200, 20), "Press F to open door");
}
else
{
GUI.Box(new Rect(0, 0, 200, 20), "Press G to close door");
}
}
}
}
Here is what I did to make my light work and am trying do the same above but with animation.
using UnityEngine;
using System.Collections;
public class LightSwitchNew : MonoBehaviour {
public bool onSwitch;
public bool lightStatus;
public GameObject theLight;
void OnTriggerEnter(Collider other)
{
onSwitch = true;
}
void OnTriggerExit(Collider other)
{
onSwitch = false;
}
void Update()
{
if(theLight.active == true)
{
lightStatus = true;
}
else
{
lightStatus = false;
}
if (onSwitch)
{
if (lightStatus)
{
if (Input.GetKeyDown(KeyCode.E))
{
theLight.active = false;
}
}
else
{
if (Input.GetKeyDown(KeyCode.E))
{
theLight.active = true;
}
}
}
}
void OnGUI()
{
if (onSwitch)
{
if (lightStatus)
{
GUI.Box(new Rect(0, 0, 200, 20), "Press E to turn off the light");
}
else
{
GUI.Box(new Rect(0, 0, 200, 20), "Press E to turn on the light");
}
}
}
}
i try to make street light on when in game Time is a 06.00pm to 06.00am and same as 06.00 am to 06.00pm off.all are make with sun(directional light) is this posible to make i use simple sun roation script with Procedural sky…Thanks in advance
Please don’t necro old threads to hijack for your question; just create your own thread.