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?
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'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 would like my player to collide with an invisible collider and restart the scene right away but it seems like my script isn't working for some reason.
Added the tag 'Fall' on the invisible collider.
Added the script on the Invisible Collider Game Object.
Invisible collider object has Box Collider 2D Attached and is set ti: is Trigger
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class sceneRestart : MonoBehaviour
{
private void OnCollisionEnter2D(Collision2D platform)
{
if (platform.gameObject.tag == "Fall")
{
SceneManager.LoadScene("Main");
Debug.Log("Scene Restarted");
}
}
}
The script is attached to the invisible collider, so it needs to check if the colliding object is the player:
public class sceneRestart : MonoBehaviour
{
private void OnTriggerEnter2D(Collider2D Col)
{
if (Col.gameObject.tag == "Player")
{
SceneManager.LoadScene("Main");
Debug.Log("Scene Restarted");
}
}
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.
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.