I have a problem that I can't solve by my self.
I have a Pause Button which need to activate pause panel on scene, but nothing work.
1. I have a public GO "Panel" attached in the inspector.
2.Inspector writes that: "There is no 'GameObject' attached to the "Panel" game object, but a script is trying to access it."
3.Script on always active GO.
4.At start Panel is Active.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class ButtonController : MonoBehaviour {
private Scene ActiveScene;
private GameController gm;
public GameObject panel;
// Use this for initialization
void Start ()
{
gm = GetComponent<GameController>();
ActiveScene = SceneManager.GetActiveScene();
panel.SetActive(false);
}
public void Pause()
{
Debug.Log("Pause");
panel.SetActive(true);
Time.timeScale = 0;
}
public void Menu()
{
SceneManager.LoadScene(0);
}
public void Restart()
{
SceneManager.LoadScene(ActiveScene.buildIndex);
}
public void Play()
{
Time.timeScale = 1;
panel.SetActive(false);
}
Glad if u can help!
I solved the problem: I attached the script twice.
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 have been trying to make an OnTriggerEnter Score system and it has not been updating and is showing no errors so am I doing something wrong that I dont know about here is my Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class ScoreManger : MonoBehaviour
{
public TextMeshProUGUI MyscoreText;
private int ScoreNum;
// Start is called before the first frame update
void Start()
{
ScoreNum = 0;
MyscoreText.text = ScoreNum.ToString();
}
void update() {
MyscoreText.text = ScoreNum.ToString();
}
public void OnTriggerEnte2D(Collider2D col){
if(col.tag == "Score"){
ScoreNum += 1;
Debug.Log("It Worked");
MyscoreText.text = ScoreNum.ToString();
Destory(col.gameObject);
}
}
}
You spelled OnTriggerEnter2D wrong.
Or you haven't marked at least one of the colliders you are interacting with as a trigger.
Or you haven't attached the script to a gameobject.
I'm trying to do a 2D platformer with a deaths counter, but I'm facing a problem.
Here is the script I attached to a 3D Text:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DeathCounter : Respawn
{
public Text DeathCount;
public void SetText(int text)
{
string deathsS = deaths.ToString();
DeathCount.text = deathsS;
}
}
And it does nothing.
I'm asking for help please.
What do I do ?
Here is the "Respawn" script, if needed:
using System.Collections;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
using UnityEngine;
public class Respawn : MonoBehaviour
{
public int deaths;
private Scene scene;
void Start()
{
scene = SceneManager.GetActiveScene();
}
void OnCollisionEnter2D(Collision2D col)
{
if(col.transform.CompareTag("Player"))
{
deaths = deaths + 1;
Debug.Log("You are dead");
System.Threading.Thread.Sleep(500);
SceneManager.LoadScene(0);
}
}
}
Thanks a lot for your help !
Have a nice day.
First thing I would do is remove the inheriting of Respawn from your DeathCounter class since it's not extending the functionality of Respawn. I would then set the function to use the passed in parameter to set the text value instead.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DeathCounter : MonoBehaviour
{
public Text DeathCount;
public void SetText(String text)
{
DeathCount.text = "Death Count: " + text;
}
}
Then, in your other class when doing your collision check you can pass the death count value as what to set your DeathCount text to.
using System.Collections;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
using UnityEngine;
public class Respawn : MonoBehaviour
{
public int deaths;
//Reference to your DeathCounter script
public DeathCounter dCounter;
private Scene scene;
void Start()
{
scene = SceneManager.GetActiveScene();
}
void OnCollisionEnter2D(Collision2D col)
{
if(col.transform.CompareTag("Player"))
{
deaths = deaths + 1;
//New line here, with passed in script for updating as a reference
dCounter.SetText(deaths.ToString());
Debug.Log("You are dead");
System.Threading.Thread.Sleep(500);
SceneManager.LoadScene(0);
}
}
}
Edit: One script version...
using System.Collections;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Respawn : MonoBehaviour
{
public int deaths;
//Reference to your Text, dragged in via the inspector
public Text deathCount;
private Scene scene;
void Start()
{
scene = SceneManager.GetActiveScene();
}
void OnCollisionEnter2D(Collision2D col)
{
if(col.transform.CompareTag("Player"))
{
deaths = deaths + 1;
//Just update the referenced UI text
deathCount.text = "Death Count: " + deaths;
Debug.Log("You are dead");
System.Threading.Thread.Sleep(500);
SceneManager.LoadScene(0);
}
}
}
The problem
basically lies in the LoadScene:
You increase the deaths value BUT then you reload the scene → you also reload the Respawn instance and therefore deaths again will have its original value so probably 0.
You didn't even call the SetText method but even if you would when the scene is reloaded also the Text component is reloaded and will have the original text like of you hadn't called the SetText method at all.
Solution
I'm order to fix it in this case I would use
public class Respawn : MonoBehaviour
{
public static int deaths{ get; private set; }
...
if the value is static it is not bound to a certain instance of Respawn but "lives" directly in the type Respawn. Therefore it keeps its current value also when reloading the scene. The {get; private set;} turns it from a field into a property which can be read by every other class but written only by the Respawn class.
Further you never want to use something like
System.Threading.Thread.Sleep(500);
in the Unity main thread. This completely freezes the main thread and if you e.g. later add any animations etc the app will simply freeze completely. Instead use a Coroutine like
void OnCollisionEnter2D(Collision2D col)
{
if(!col.transform.CompareTag("Player")) return;
deaths += 1;
Debug.Log("You are dead");
StartCoroutine(Reload());
}
private IEnumerator Reload()
{
yield return new WaitForSeconds(0.5f);
SceneManager.LoadScene(0);
}
Finally you have to set the Text after loading the scene so it gets updated also in the reloaded scene.
public class DeathCounter : Respawn
{
public Text DeathCount;
// automatically called when scene is reloaded
private void OnEnable()
{
DeathCount.text = deaths.ToString();
}
}
Sidenote:
In Respawn you store a
scene = SceneManager.GetActiveScene();
but later never use it but instead anyway use
SceneManager.LoadScene(0);
so I would get rid of that Start method .. it only causes unnecessary overhead.
I have followed a tutorial on Youtube (https://www.youtube.com/watch?v=_nRzoTzeyxU) on how to create a dialogue system for a game. Since my game is a platformer/RPG, I am currently attempting to adapt this system to where the player can walk up to an NPC and press the "Submit" button to access their dialogue, instead of clicking a button on the canvas/UI.
So far I have created an Interactable script that allows the player to detect if they are in the range of the invisible sphere collider that is equipped to the NPC, which is working. If I try to access the dialogueTrigger script that is equipped to the NPC however, I get a NullReferenceException error. I would like some help on how to properly call the dialogueTrigger script from the NPC and trigger the dialogue event, as I am very new to code and I only have this so far. Any help would be appreciated.
EDIT:
NullReferenceException: Object reference not set to an instance of an object
Interactable.Update () (at Assets/Scripts/Interactable.cs:34)
Dialogue Trigger is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DialogueTrigger : MonoBehaviour
{
public Dialogue dialogue;
public void TriggerDialogue ()
{
FindObjectOfType<DialogueManager>().StartDialogue(dialogue);
}
}
Interactable is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Interactable : MonoBehaviour
{
private GameObject triggeringNpc;
private bool triggering;
public DialogueTrigger Diag;
void Start()
{
}
void Update()
{
if(triggering)
{
Debug.Log("Within Range");
if (Input.GetButtonDown("Submit"))
{
Debug.Log("Pressed the Interact Button");
Diag.TriggerDialogue();
}
}
}
void OnTriggerEnter(Collider other)
{
if(other.tag == "NPC")
{
triggering = true;
triggeringNpc = other.gameObject;
}
}
void OnTriggerExit(Collider other)
{
if(other.tag == "NPC")
{
triggering = false;
triggeringNpc = null;
}
}
}
The culprit would be your Diag reference. Have you correctly dragged a DialogueTrigger prefab from your Hierarchy window and into the public field on Interactable?
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.