I wanted to add a flashlight to my game. When I press the button to make it disappear, it disappears, but when I press the button to try to make it appear again it doesn't. I've been trying to find the solution for the past hour and a half and looked into the docs too but I didn't find anything.
using System.Collections.Generic;
using UnityEngine;
public class flashlight : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1))
{
gameObject.SetActive(true);
}
if (Input.GetKeyUp(KeyCode.Alpha2))
{
gameObject.SetActive(false);
}
}
}
The script is being deactivated along with the gameObject so it isn't listening for Input.GetKeyUp(KeyCode.Alpha2).
To get round this create an empty GameObject to hold the script and make the light a child of said GameObject, then when you deactivate the light the script is still active and listening for the Input.
Update the script like this to assign the light child
public class flashlight : MonoBehaviour
{
public GameObject light;//Assign this is the inspector
void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1))
{
light.SetActive(true);
}
if (Input.GetKeyUp(KeyCode.Alpha2))
{
light.SetActive(false);
}
}
}
Related
I am making a shooting game in Unity, and I am using particles as the laser/bullets. Even when I press left alt, the particles don't show up. It does print out firing weapon on the console, but the particles don't appear. I am using c#.
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fire : MonoBehaviour
{
[SerializeField] ParticleSystem weapon;
// Start is called before the first frame update
void Start()
{
weapon.Pause();
}
// Update is called once per frame
void Update()
{
WeaponProcessor();
}
void WeaponProcessor()
{
if (Input.GetButtonDown("Fire2"))
{
if (!weapon.isPlaying)
{
Debug.Log("Firing weapon");
weapon.Play();
}
}
else
{
weapon.Pause();
Debug.Log("Not firing weapon");
}
}
}
By the way, weapon.pause does not work either.
ParticleSystem.Pause freezes particles, this doesn't seem to be the correct behavior for weapon fire.
Pauses the system so no new particles are emitted and the existing particles are not updated.
You need to restart Particle system like this:
using UnityEngine;
public class Fire : MonoBehaviour
{
[SerializeField] private ParticleSystem fireParticles;
private void Start()
{
if (fireParticles.isPlaying)
{
fireParticles.Stop();
}
}
private void Update()
{
WeaponProcessor();
}
private void WeaponProcessor()
{
if (Input.GetButtonDown("Fire2"))
{
fireParticles.Play();
}
if (Input.GetButtonUp("Fire2"))
{
fireParticles.Stop();
}
}
}
Already fired bullets will not stop and new ones will be created on the next "Fire2" press
I don't know how to reload a scene so that the user can press a key and reset the game. Whenever I do it, the engine just crashes. The game is based on a cat chasing glasses around with a 120-second timer, and each of them has unique abilities. On collision, it should reload the scene. Is there any way that I can do this?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class gamemanager : MonoBehaviour
{
public GameObject catwin;
public GameObject glasseswin;
public timer timer;
public Transform catpos;
public Transform glassespos;
public Vector3 catspawn;
public Vector3 glassesspawn;
public bool gameover = false;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKey("r"))
{
GameReset();
}
}
public void CW()
{
catwin.SetActive(true);
gameover = true;
while (gameover)
{
if (Input.GetKey(KeyCode.R))
{
GameReset();
}
}
}
public void GW()
{
glasseswin.SetActive(true);
if (Input.GetKey("r"))
{
GameReset();
}
}
public void GameReset()
{
catwin.SetActive(false);
glasseswin.SetActive(false);
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
It crashes because the while loop inside the CW method is actually a while (true). When something calls this method it should wait until method is completed, but it'll never happen because of the loop. As a result, the program gets stuck while trying to execute infinitely many commands in one frame, so it has no other choice but to crash.
In order to fix it remove the loop from the method and check whether the key was pressed in Update. Something like this:
if (gameover && Input.GetKey("r"))
GameReset();
You can replace gameover with something else in order to include other conditions
I've just started teaching myself coding, and I've been watching Brackey's tutorial series. I'm trying to create a Pause menu, and I've followed along with the video, but for some reason I can't get the menu to activate when I hit escape. I've double checked the code and it should be working, when compared to what's on screen. Is there something I'm missing?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PauseMenu : MonoBehaviour
{
public static bool isGamePaused = false;
public GameObject pauseMenu;
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
if (isGamePaused)
{
ResumeGame();
}
else
{
PauseGame();
}
}
}
void ResumeGame()
{
pauseMenu.SetActive(false);
Time.timeScale = 1f;
isGamePaused = false;
}
void PauseGame()
{
pauseMenu.SetActive(true);
Time.timeScale = 0f;
isGamePaused = true;
}
}
Now that I can see the relevant code and hierarchy I believe I see the issue. In your script, you are checking for input in the Update() which is only called when the GameObject the script component is on is active in the hierarchy.
When you are toggling your pause, you are activating and deactivating the GameObject that you assign in the inspector. As the object you assigned in the GameObject that has the script, the Update() will never be called after it is disabled.
You have a few options, but the easiest one would be to drag in the reference of the panel pauseMenu as the reference object to toggle in your script instead of the Canvas object you currently have. That way the Canvas can act as a manager for the pauseMenu, toggling it when the input changes.
I tried both setting enabled to true and SetActive(true) to diplay a Gameover Image. However, none of them works. I have a public Image gameOverImage declared and set the gameOverImage.enabled in the Start() to false.
private void Start()
{
gameOverImage.enabled = false;
}
Then in one of my function, I put:
public void killAt(Vector2 loc)
{
foreach (GameObject obj in setup.GetActive())
{
if (obj.GetComponent<PieceInfo>().GetLocation() == loc)
{
if (obj.GetComponent<PieceInfo>().GetPieceType() == 'G')
{
gameOver = true;
gameOverImage.enabled = true;
Debug.Log("?????");
}
setup.deactivate(obj);
break;
}
}
}
The console does have ????? logged but no gameOverImage displayed in the game view. The game is over because I couldn't click my game any more. Any ideas? I also tried UI text. It doesn't work as well.
In Unity in order to activate an object you need to have it in the scene. If the GameObject does not exist in the scene, or in your case the UI Element that contains the Image, is not in your scene SetActive(true) or Enabled = true will not have any effect. You will need to instantiate the object. To make it exist in your world.
Prefabs, are useful to store a common configuration that can be used multiple times in your game but they do not exist in the scene, that is why you have to instantiate them.
For your GameOver Image you have a few options the simplest is this:
using UnityEngine;
using UnityEngine.UI;
public class EnableUI : MonoBehaviour {
public Image GameOverImage;
// Use this for initialization
void Start () {
GameOverImage.gameObject.SetActive(false);
}
// Update is called once per frame
void Update () {
if(Input.GetKeyDown(KeyCode.Space))
{
GameOverImage.gameObject.SetActive(true);
}
}
}
If you want to instantiate it:
using UnityEngine;
public class EnableUI : MonoBehaviour {
// This is a prefab that is canvas with your game over image nested as a child image UI under it
public GameObject GameOverObject;
// Use this for initialization
void Start () { }
// Update is called once per frame
void Update () {
if(Input.GetKeyDown(KeyCode.Space))
{
Instantiate(GameOverObject);
}
}
}
How do I set gameobject(myCanvas) to be false during the first play?
I've put this script into the cube, and when I click the cube it will show the Canvas.
I haven't been clicking on the cube but, the canvas has already come out.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class MouseDownText : MonoBehaviour {
public Canvas myCanvas;
void Start()
{
// first start game. gameobject will turn off
myCanvas.gameObject.SetActive(false);
}
void OnMouseDown()
{
// for switch on/off
myCanvas.gameObject.SetActive(!myCanvas.gameObject.activeSelf);
}
}
From what I understand you have a canvas component attached to a game object (a cube) and you want to use mouse clicks to toggle whether or not the canvas is active.
Have you tried:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class MouseDownText : MonoBehaviour {
public Canvas myCanvas;
// Use this for initialization
void Start () {
myCanvas = GetComponent<Canvas> ();
myCanvas.enabled = false;
}
// Update is called once per frame
void Update () {
}
void OnMouseDown()
{
// for switch on/off
if (myCanvas.enabled)
myCanvas.enabled = false;
else
myCanvas.enabled = true;
}
}
Also make sure you haven't accidentally enabled it in some other code somewhere.