I'm making a 2D game and want to jump from a dialogue scene that is a tutorial for the beginning of the game to a scene where the game starts but I don't know how to achieve that after the dialogue ends. here is the entire script for the scene ( dialogue manager, Dialogue, and Dialogue trigger).
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class DialogueManager : MonoBehaviour
{
public TextMeshProUGUI nameText;
public TextMeshProUGUI dialogueText;
private Queue<string> sentences;
void Start()
{
sentences = new Queue<string>();
}
public void StartDialogue(Dialogue dialogue)
{
nameText.text = dialogue.name;
sentences.Clear();
foreach (string sentence in dialogue.sentences)
{
sentences.Enqueue(sentence);
}
DisplayNextSentence();
}
public void DisplayNextSentence()
{
if (sentences.Count == 0)
{
EndDialogue();
return;
}
string sentence = sentences.Dequeue();
dialogueText.text = sentence;
}
void EndDialogue()
{
Debug.Log("End of conversation.");
}
}
And this is the Dialogue Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Dialogue
{
public string name;
[TextArea(3, 10)]
public string[] sentences;
}
And this is the Dialogue Trigger:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DialogueTrigger : MonoBehaviour
{
public Dialogue dialogue;
public void TriggerDialogue()
{
FindObjectOfType<DialogueManager>().StartDialogue(dialogue);
}
}
Use SceneManager.LoadScene in your EndDialogue() method
void EndDialogue()
{
// load new scene here
Debug.Log("End of conversation.");
}
Related
I am making a game where, if the catcher gets destroyed by the object, the game over screen is triggered. All that seems to occur is that there is a giant game over the screen at the beginning of when I play, while the game is running in the background. For some reason, the game does not seem to call in the game over screen only on collision.
This is the script I am using for my catcher, where it collides, disappears, and then the game over screen is set up to be triggered.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CatcherDestroy : MonoBehaviour
{
public GameOverScreen GameOverScreen;
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Catcher"))
{
Destroy(collision.gameObject);
GameOverScreen;
}
}
}
and this is the code for my GameOverScreen.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameOverScreen : MonoBehaviour
{
public Text pointsText;
public void Setup(int score)
{
gameObject.SetActive(true);
pointsText.text = "Score:" + score.ToString();
}
}
You are not calling anything when an object collides, you're just listing the reference of the object. You'll need to call the function that you have exposed. Without calling a method from the script reference, no code will be run. Edit your first snippet as follows:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CatcherDestroy : MonoBehaviour
{
public GameOverScreen GameOverScreen;
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Catcher"))
{
Destroy(collision.gameObject);
GameOverScreen.Setup();
}
}
}
The other option would be to move the code in Setup to Awake or Start or OnEnable, then instead of calling the function in the collision, you just need to set it as active.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CatcherDestroy : MonoBehaviour
{
public GameOverScreen GameOverScreen;
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Catcher"))
{
Destroy(collision.gameObject);
GameOverScreen.score = theScore;
GameOverScreen.gameObject.SetActive(true);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameOverScreen : MonoBehaviour
{
public Text pointsText;
public int score;
private void OnEnable()
{
pointsText.text = "Score:" + score.ToString();
}
}
The one issue is you'll need to pass in the score parameter which I do not see in your script CatcherDestroy.
We are trying to add the ability to lose three child slimes at the same time when attacked by a specific weapon.
Children's slime is managed by List.
List script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChildSlimeList : MonoBehaviour
{
[SerializeField]
private List<GameObject> SlimeChild=new List<GameObject>();
public void ChildSlimeRandomOff()
{
for (int i = 0; i < 2; i++)
{
var SlimeNum = Random.Range(0, SlimeChild.Count);
GameObject SlimeChildList = SlimeChild[SlimeNum];
SlimeChildList.SetActive(false);
SlimeChild.RemoveAt(SlimeNum);
}
}
}
Child slime script
using System;
using System.Collections.Generic;
using _SlimeCatch.Stage;
using UnityEngine;
using Random = System.Random;
public class ChildrenSlimeWeaponCollider : MonoBehaviour
{
[SerializeField] private GameObject MolotovCocktail;
public GameObject GameManager;
ChildSlimeList _childSlimeList;
void Start()
{
//_childSlimeList = GetComponent<ChildSlimeList>().SlimeChild();
}
public void OnCollisionEnter2D(Collision2D other)
{
//if (!other.gameObject.CompareTag("Weapon")) return;
//_childSlimeList.SlimeChild.RemoveAt(this.gameObject);
if (other.gameObject.CompareTag("MolotovCocktail"))
{
GameManager.GetComponent<ChildSlimeList>().ChildSlimeRandomOff();
}
Destroy(gameObject);//or SetActive(false)
Destroy(other.gameObject);//or SetActive(false)
}
}
At this rate, the elements of the slime list of the child attacked by a specific weapon will not be deleted directly. Help me.
State of the gameenter image description here
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChildSlimeList : MonoBehaviour
{
[SerializeField]
private List<GameObject> SlimeChild=new List<GameObject>();
public void ChildSlimeRandomOff()
{
for (int i = 0; i < 2; i++)
{
var SlimeNum = Random.Range(0, SlimeChild.Count);
GameObject SlimeChildList = SlimeChild[SlimeNum];
SlimeChildList.SetActive(false);
SlimeChild.RemoveAt(SlimeNum);
}
}
public void SlimeColliderDecision(GameObject gameObject)
{
SlimeChild.Remove(gameObject);
}
}
using System;
using System.Collections.Generic;
using _SlimeCatch.Stage;
using UnityEngine;
using Random = System.Random;
public class ChildrenSlimeWeaponCollider : MonoBehaviour
{
[SerializeField] private GameObject MolotovCocktail;
public GameObject GameManager;
ChildSlimeList _childSlimeList;
void Start()
{
//_childSlimeList = GetComponent<ChildSlimeList>().SlimeChild();
}
public void OnCollisionEnter2D(Collision2D other)
{
//if (!other.gameObject.CompareTag("Weapon")) return;
if (other.gameObject.CompareTag("MolotovCocktail"))
{
GameManager.GetComponent<ChildSlimeList>().SlimeColliderDecision(this.gameObject);
GameManager.GetComponent<ChildSlimeList>().ChildSlimeRandomOff();
}
gameObject.SetActive(false);
other.gameObject.SetActive(false);
}
}
By making this change, we were able to hide three objects and at the same time reduce the number of elements in the list that contain them.
Many thanks to those who gave me tips.
I have been following a tutorial for saving player names with playerprefs.
I got it working normal text, but not with TextMeshPro. Is there a way to edit the code so that I can use TextMeshPro with the scripts?
First Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SaveName : MonoBehaviour
{
public InputField textBox;
public void ClickSaveButton()
{
PlayerPrefs.SetString("name", textBox.text);
Debug.Log("Your name is " + PlayerPrefs.GetString("name"));
}
}
Second Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class NameScene : MonoBehaviour
{
public Text NameBox;
void Start()
{
NameBox.text = PlayerPrefs.GetString("name");
}
// Update is called once per frame
void Update()
{
}
}
Import TextMeshPro to your script and instead of public Text NameBox; use public TMP_Text NameBox;
Basically, I have this Text (scoreText) which is in my "Menu" scene so hence I have initiated it in GameControlMenu.cs, however, I'm trying to change its text from my other script GameControl.cs whilst I'm currently on my "Main" scene.
GameControlMenu.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class GameControlMenu : MonoBehaviour
{
public static GameControlMenu instanceMenu;
public Text scoreText;
void Start()
{
//does stuff but not important to question
}
}
GameControl.cs:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
public class GameControl : MonoBehaviour
{
public static GameControl instance;
public int score = 5;
void Start()
{
GameControlMenu.instanceMenu.scoreText.text = "PREVIOUS SCORE: " + score;
}
}
This setup works for a couple of my other variables which I'm accessing from another file but for whatever reason this just keeps throwing me the error: NullReferenceException: Object reference not set to an instance of an object
Any help is appreciated :)
You can't do GameControlMenu.instanceMenu... since GameControlMenu is in another scene as you described, and the instance isn't in the current scene.
But what you can do is to store the value somewhere first, and let the GameControlMenu use it when the other scene loads like so:
GameControlMenu.cs
public class GameControlMenu : MonoBehaviour
{
public static GameControlMenu instanceMenu;
public static string StuffToShowOnScoreText { get; set; }
public Text scoreText;
void Awake()
{
// So that it loads the text on start
scoreText.text = StuffToShowOnScoreText;
// ...
}
}
GameControl.cs
public class GameControl : MonoBehaviour
{
public static GameControl instance;
public int score = 5;
void Start()
{
// Store the value
GameControlMenu.StuffToShowOnScoreText = "PREVIOUS SCORE: " + score;
}
}
Im getting this error in unity, my problem is highscore, it doesnt work. I tried all kinds of videos on youtube but i think im doing something wrong in all of them. Also tried with Text highscore and also doesnt work. It says to me " Are you missing an assembly reference?"
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScoreScript : MonoBehaviour {
public static int scoreValue = 0;
public Text score;
public static int highscore;
void Start () {
highscore.Text = PlayerPrefs.GetInt("HighScore", 0);
score = GetComponent<Text>();
scoreValue = 0;
}
void Update () {
score.text = "" + scoreValue;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class hazardCollisionFunctions : MonoBehaviour {
private void OnCollisionEnter(Collision col){
if(col.gameObject.tag == "Platform"){
this.gameObject.SetActive(false);
ScoreScript.scoreValue += 1;
}
if(col.gameObject.tag == "Player"){
if(ScoreScript.highscore < ScoreScript.scoreValue){
PlayerPrefs.SetInt("HighScore", ScoreScript.scoreValue);
}
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
}
Add a public Text highScoreText; field to your ScoreScript so ScoreScript can work with it.
Set highScoreText.Text to "" + highScore in Start so the text gets set appropriately.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScoreScript : MonoBehaviour {
public static int scoreValue = 0;
public Text score;
public Text highScoreText;
public static int highscore;
void Start () {
highscore = PlayerPrefs.GetInt("HighScore", 0);
highScoreText.Text = "" + highScore;
score = GetComponent<Text>();
scoreValue = 0;
}
void Update () {
score.text = "" + scoreValue;
}
}
Drag the high score text object into the highScoreText field of the ScoreScript script in the inspector