So apparently, i was working on my games dialogue and of course, i have to put the text in the text slot for my code. I tried putting it in the slot but it didnt work. I tried changing the "Text" to "TextMesh" but still, didnt work.
this is my code that i tried for the game.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Goose : MonoBehaviour
{
public GameObject dialoguePanel;
public TextMesh dialogueText;
public string[] dialogue;
private int index;
public float wordSpeed;
public bool playerIsClose;
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.E) && playerIsClose)
{
if(dialoguePanel.activeInHierarchy)
{
zeroText();
}
else
{
dialoguePanel.SetActive(true);
StartCoroutine(Typing());
}
}
}
public void zeroText()
{
dialogueText.text = "";
index = 0;
dialoguePanel.SetActive(false);
}
IEnumerator Typing()
{
foreach(char letter in dialogue[index].ToCharArray())
{
dialogueText.text += letter;
yield return new WaitForSeconds(wordSpeed);
}
}
public void NextLine()
{
if(index < dialogue.Length - 1)
{
index++;
dialogueText.text = "";
StartCoroutine(Typing());
}
else
{
zeroText();
}
}
private void OnTriggerEnter2D(Collider2D other)
{
if(other.CompareTag("Player"))
{
playerIsClose = true;
}
}
private void OnTriggerExit2D(Collider2D other)
{
if(other.CompareTag("Player"))
{
playerIsClose = false;
zeroText();
}
}
}
I think what you need is public TMP_Text dialogueText
Related
I had a script that controlled my main menu that was on a GameObject and moved it to another gameobject and reconnected all the loose ends. now for some reason none of my buttons work, even with highlighting.
just had two gameobjects and moved the script between them using the editor
the script itself doesnt do much, just this:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class MainMenu : MonoBehaviour
{
public GameObject mainMenu;
public GameObject optionsMenu;
public GameObject modeMenu;
public Dropdown resolutionDropdown;
private Resolution[] resolutions;
public Toggle fullscreenToggle;
public void StartGameLocal()
{
SceneManager.LoadScene("Local2P");
}
public void StartGameAI()
{
SceneManager.LoadScene("AI2P");
}
public void MenuToOptions()
{
mainMenu.SetActive(false);
optionsMenu.SetActive(true);
}
public void OptionsToMenu()
{
mainMenu.SetActive(true);
optionsMenu.SetActive(false);
}
public void MenuToMode()
{
mainMenu.SetActive(false);
modeMenu.SetActive(true);
}
public void ModeToMenu()
{
mainMenu.SetActive(true);
modeMenu.SetActive(false);
}
public void ExitGame()
{
Application.Quit();
}
void Start()
{
resolutions = Screen.resolutions;
resolutionDropdown.ClearOptions();
List<string> options = new List<string>();
int currentResolutionIndex = 0;
for (int i = 0; i < resolutions.Length; i++)
{
string option = resolutions[i].width + " x " + resolutions[i].height;
options.Add(option);
if (resolutions[i].width == Screen.width && resolutions[i].height == Screen.height)
currentResolutionIndex = i;
}
resolutionDropdown.AddOptions(options);
resolutionDropdown.value = currentResolutionIndex;
resolutionDropdown.RefreshShownValue();
if (Screen.fullScreen == true)
{
fullscreenToggle.isOn = true;
}
}
public void SetResolution(int resolutionIndex)
{
Resolution resolution = resolutions[resolutionIndex];
Screen.SetResolution(resolution.width,
resolution.height, Screen.fullScreen);
PlayerPrefs.SetInt("ResolutionPreference", resolutionDropdown.value);
}
public void SetFullscreen(bool isFullscreen)
{
Screen.fullScreen = isFullscreen;
if (isFullscreen)
{
PlayerPrefs.SetInt("FullscreenPreference", 1);
}
else
{
PlayerPrefs.SetInt("FullscreenPreference", 0);
}
}
void Update()
{
if (Input.GetKey(KeyCode.Escape))
{
if (optionsMenu.activeSelf)
{
OptionsToMenu();
}
else if (optionsMenu.activeSelf)
{
ModeToMenu();
}
else
{
Application.Quit();
}
}
}
}
i dont know how to fix this and why my buttons just stopped working, even after reconnecting everything, but please help!
p.s. havent checked the update code to see if it worked, if yall have suggestions let me know
Your buttons likely pointed to the functions in this script in their OnClick handlers. If you moved the location of the script, you need to go to each of the buttons and hook those handlers back up.
Inside the manager script I have a method that start a dialogue name : StartDialogue:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DialogueManager : MonoBehaviour
{
public Text dialogueText;
public Text nameText;
public float sentencesSwitchDuration;
public bool animateSentenceChars = false;
public GameObject canvas;
public static bool dialogueEnded = false;
public DialogueTrigger trigger;
private Queue<string> sentence;
// Use this for initialization
void Start()
{
sentence = new Queue<string>();
}
public void StartDialogue(Dialogue dialogue)
{
canvas.SetActive(true);
nameText.text = dialogue.name;
sentence.Clear();
foreach (string sentence in dialogue.sentences)
{
this.sentence.Enqueue(sentence);
}
DisplayNextSentence();
}
public void DisplayNextSentence()
{
if (this.sentence.Count == 0)
{
EndDialogue();
return;
}
string sentence = this.sentence.Dequeue();
dialogueText.text = sentence;
StopAllCoroutines();
StartCoroutine(DisplayNextSentenceWithDelay(sentence));
}
public IEnumerator DisplayNextSentenceWithDelay(string sentence)
{
if (animateSentenceChars)
{
dialogueText.text = "";
foreach (char letter in sentence.ToCharArray())
{
dialogueText.text += letter;
yield return null;
}
}
yield return new WaitForSeconds(sentencesSwitchDuration);
DisplayNextSentence();
}
private void EndDialogue()
{
dialogueEnded = true;
if (trigger.dialogueNum == trigger.conversations[trigger.dialogueIndex].Dialogues.Count)
canvas.SetActive(false);
Debug.Log("End of conversation.");
}
}
Then in the trigger script I have a method name TriggerDialogue that get index number. For example index 0 it will start the dialoue/s of the first conversation. But in fact it's just starting the first dialogue from the dialogues List.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
[ExecuteInEditMode]
public class DialogueTrigger : MonoBehaviour
{
public List<Conversation> conversations = new List<Conversation>();
//public List<Dialogue> dialogue = new List<Dialogue>();
[HideInInspector]
public int dialogueNum = 0;
[HideInInspector]
public int dialogueIndex = 0;
private bool triggered = false;
private List<Dialogue> oldDialogue;
private bool activateButton = false;
public void TriggerDialogue(int dialogueIndex)
{
this.dialogueIndex = dialogueIndex;
if (conversations.Count > 0 &&
conversations[dialogueIndex].Dialogues.Count > 0)
{
if (triggered == false)
{
if (FindObjectOfType<DialogueManager>() != null)
{
FindObjectOfType<DialogueManager>().StartDialogue(conversations[dialogueIndex].Dialogues[dialogueNum]);
dialogueNum += 1;
}
triggered = true;
}
}
}
private void Update()
{
ButtonActivation();
if (DialogueManager.dialogueEnded == true)
{
if (dialogueNum == conversations[dialogueIndex].Dialogues.Count)
{
return;
}
else
{
FindObjectOfType<DialogueManager>().StartDialogue(conversations[dialogueIndex].Dialogues[dialogueNum]);
DialogueManager.dialogueEnded = false;
dialogueNum += 1;
}
}
}
public bool ActivateButton()
{
return activateButton;
}
private void ButtonActivation()
{
if (ConversationsChecks() == true)
{
foreach (string sentence in conversations[dialogueIndex].Dialogues[dialogueNum].sentences)
{
if (sentence != "")
{
activateButton = true;
}
else
{
activateButton = false;
}
}
}
else
{
activateButton = false;
}
}
public void SaveConversations()
{
string jsonTransform = JsonHelper.ToJson(conversations.ToArray(), true);
File.WriteAllText(#"d:\json.txt", jsonTransform);
}
public void LoadConversations()
{
string jsonTransform = File.ReadAllText(#"d:\json.txt");
conversations.Clear();
conversations.AddRange(JsonHelper.FromJson<Conversation>(jsonTransform));
}
private bool ConversationsChecks()
{
bool IsConversationsReady = false;
if (conversations.Count > 0 &&
conversations[dialogueIndex].Dialogues.Count > 0 &&
conversations[dialogueIndex].Dialogues[dialogueNum].sentences.Count > 0 &&
conversations[dialogueIndex].Dialogues[dialogueNum].name != "" &&
conversations[dialogueIndex].name != "")
{
IsConversationsReady = true;
}
else
{
IsConversationsReady = false;
}
return IsConversationsReady;
}
}
Then I have more two small classes :
Dialogue:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Dialogue
{
[Tooltip("Dialogue Name")]
public string name;
[TextArea(1, 10)]
public List<string> sentences = new List<string>();
}
And Conversation :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Conversation
{
[Tooltip("Conversation Name")]
public string name;
public List<Dialogue> Dialogues = new List<Dialogue>();
}
So now when I want to start a dialogue I'm calling the TriggerDialogue method like this example :
dialogueTrigger.TriggerDialogue(0);
Instead I want to do something like that :
dialogueTrigger.StartConversation("Opening Scene");
Or
dialogueTrigger.StartConversation("The last conversation");
And this is example screenshot of how the Inspector of the conversations and dialogues looks like :
Conversations
So if for example I want to start the first conversation somewhere in my game I will do :
dialogueTrigger.StartConversation("The Opening");
And it will start the dialogue/s inside the "The Opening" conversation.
Using the index is working fine but I want to use to start a conversation by the conversation name it will be easier.
Given that you are using a List<T>, if you move away from using the index to get the item you want, you will need to enumerate the collection each time to find that same item. The best you can do here, is change the data structure to a Dictionary, so you can search for it by the Key and avoid the performance hit. In order to also avoid having to remember what names you put to the conversations, perhaps it would be best to use an Enum.
So, create the enum:
public enum SceneConversations
{
OpeningScene = 1,
// ...
}
and start using
public class DialogueTrigger : MonoBehaviour
{
public Dictionary<SceneConversations, Conversation> conversations = new Dictionary<SceneConversations, Conversation>();
you can then use
public void StartConversation(SceneConversations conversationWanted) {}
and call it with
dialogueTrigger.StartConversation(SceneConversations.OpeningScene);
If I remember correctly, this has the added advantage that Unity will show you a drop-down for the possible values of SceneConversations, so that's also easier to handle.
I have four buttons using the same prefab and holding 4 text elements from an array out of which only one is assigned bool value to true. I am trying to access that true element when any of false element is clicked. i want to highlight true element when the false element is clicked. can anyone please help me to achieve this functionality?
using simpleobjectpool
taking reference from unity quiz game tutorial
Thanks
Answer Button Script
public class AnswerButton : MonoBehaviour
{
public Text answerText;
private AnswerData answerData;
private GameController gameController;
private bool isCorrect;
void Start()
{
gameController = FindObjectOfType<GameController>();
}
public void Setup(AnswerData data)
{
answerData = data;
answerText.text = answerData.answerText;
}
public void HandleClick()
{
gameController.AnswerButtonClicked(answerData.isCorrect);
{
if (answerData.isCorrect)
{
}
if (!answerData.isCorrect)
{
}
}
Answer Data Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class AnswerData
{
public string answerText;
public bool isCorrect;
}
QuestionData Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class QuestionData
{
public string questionText;
public AnswerData[] answers;
}
Game Controller Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System;
public class GameController : MonoBehaviour
{
public Text questionText;
public Text scoreDisplayText;
public SimpleObjectPool answerButtonObjectPool;
public Transform answerButtonParent;
public GameObject questionPanel;
public GameObject roundOverPanel;
public GameObject levelsPanel;
private DataController dataController;
private RoundData currentRoundData;
private bool isRoundActive;
private float timeBeetweenQuestions = 3.0f;
private List<GameObject> answerButtonGameObjects = new List<GameObject>();
private QuestionData[] questionPool;
private int questionIndex;
private int qNumber = 0;
private List<int> questionIndexesChosen = new List<int>();
public int playerScore = 0;
public int totalQuestions;
private static int pointAddedForCorrectAnswer;
public AudioSource answerButtonClicked;
public AudioSource wrongAnswerClicked;
void Start ()
{
dataController = FindObjectOfType<DataController>();
currentRoundData = dataController.GetCurrentRoundData();
questionPool = currentRoundData.questions;
playerScore = 0;
questionIndex = 0;
scoreDisplayText.text = "Score: " + playerScore.ToString();
isRoundActive = true;
ShowQuestion();
}
private void ShowQuestion()
{
RemoveAnswerButtons();
QuestionData questionData = questionPool[questionIndex];
questionText.text = questionData.questionText;
for (int i = 0; i < questionData.answers.Length; i++)
{
GameObject answerButtonGameObject =
answerButtonObjectPool.GetObject();
answerButtonGameObjects.Add(answerButtonGameObject);
answerButtonGameObject.transform.SetParent(answerButtonParent);
AnswerButton answerButton =
answerButtonGameObject.GetComponent<AnswerButton>();
AnswerButton.Setup(questionData.answers[i]);
}
}
private void RemoveAnswerButtons()
{
while (answerButtonGameObjects.Count > 0)
{
answerButtonObjectPool.ReturnObject(answerButtonGameObjects[0]);
answerButtonGameObjects.RemoveAt(0);
}
}
IEnumerator TransitionToNextQuestion()
{
yield return new WaitForSeconds(timeBeetweenQuestions);
ShowQuestion();
}
IEnumerator WaitForFewSeconds()
{
yield return new WaitForSeconds(timeBeetweenQuestions);
EndRound();
}
IEnumerator ReturnCorrectButtonColor()
{
Debug.Log("im correct");
GetComponent<Button>().image.color = Color.green;
yield return new WaitForSeconds(seconds: 2.9f);
GetComponent<Button>().image.color = Color.white;
}
IEnumerator ReturnWrongButtonColor()
{
Debug.Log("im wrong");
GetComponent<Button>().image.color = Color.red;
yield return new WaitForSeconds(seconds: 2.9f);
GetComponent<Button>().image.color = Color.white;
}
public void AnswerButtonClicked (bool isCorrect)
{
if (isCorrect)
{
playerScore += currentRoundData.pointAddedForCorrectAnswer;
scoreDisplayText.text = "Score: " + playerScore.ToString();
//play coorect answer sound
answerButtonClicked.Play();
StartCoroutine(ReturnCorrectButtonColor());
}
if (!isCorrect)
{
//play wrong answer sound
answerButtonClicked = wrongAnswerClicked;
answerButtonClicked.Play();
StartCoroutine(ReturnWrongButtonColor());
// buttons = GameObject.FindGameObjectsWithTag("Answer");
// {
// foreach (GameObject button in buttons)
// {
// if (button.GetComponent<AnswerButton>
//().answerData.isCorrect)
// {
// button.GetComponent<AnswerButton>
// ().StartCoroutine(ReturnCorrectButtonColor());
// }
// }
//}
}
if (qNumber < questionPool.Length - 1) /
{
qNumber++;
StartCoroutine(TransitionToNextQuestion());
}
else
{
StartCoroutine(WaitForFewSeconds());
}
}
public void EndRound()
{
isRoundActive = false;
questionPanel.SetActive(false);
roundOverPanel.SetActive(true);
}
//on button click return to main menu
public void ReturnToMenu ()
{
SceneManager.LoadScene("MenuScreen");
}
}
In order to highlight both Wrong (the clicked one) and the Right buttons you need to have access to both buttons. This means that you can't do highlighting from HandleClick method of your Answer Button Script, as it only has access to itself, e.g. to the Wrong button.
The good thing is that this method notifies GameController that the button has been clicked. GameController knows about all the buttons, so it can easily highlight both buttons.
So, instead of launching your highlight subroutines from Answer Button's HandleClick, you should do this from GameController's AnswerButtonClicked: identify both the Right button and the clicked button there and launch appropriate subroutines for them.
Update:
For instance, your ReturnCorrectButtonColor would look like:
IEnumerator ReturnCorrectButtonColor( GameObject button )
{
Debug.Log("im correct");
button.GetComponent<Button>().image.color = Color.green;
yield return new WaitForSeconds(seconds: 2.9f);
button.GetComponent<Button>().image.color = Color.white;
}
so in AnswerButtonClicked you identify which button to highlight as a correct answer button and pass it as a paramter to this method:
StartCoroutine(ReturnCorrectButtonColor(correctButton));
I cannot figure out the issue, I deleted then remade the PlayTab object, but it no longer works... It is telling me it has not been assigned, but it has to my knowledge. Relatively new to Unity programming, any help would be great, the script below.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.Audio;
public class MainMenu : MonoBehaviour {
public GameObject Buttons;
public GameObject CreditsPanel;
public GameObject QuitPanel;
public GameObject Options;
public GameObject PlayTab;
public Slider audiosl;
public Slider graphicsl;
public Toggle fullscreen;
public string SceneName;
void Start (){
QualitySettings.SetQualityLevel (100);
//(int)PlayerPrefs.GetFloat("Quality")
AudioListener.volume = 100;
//PlayerPrefs.GetFloat("Volume");
int qualityLevel = QualitySettings.GetQualityLevel();
audiosl.value = AudioListener.volume;
graphicsl.value = qualityLevel;
}
void Update (){
Debug.Log ("Update");
AudioListener.volume = audiosl.value;
QualitySettings.SetQualityLevel ((int)graphicsl.value);
}
public void InGame(bool a){
if (a == true) {
Application.LoadLevel (SceneName);
} else {
//continue
}
}
public void Play(bool a){
Debug.Log ("Inside Play Function");
if (a == true) {
Debug.Log ("Inside If Statment");
PlayTab.SetActive(a);
Buttons.SetActive(!a);
Animation pl = PlayTab.GetComponent<Animation>();
pl.Play("EnterPlayMenu");
}else {
Debug.Log ("Else'd");
PlayTab.SetActive(a);
}
}
public void ShowMenu(bool a){
}
public void Option(bool a){
if (a == true) {
Options.SetActive(a);
Buttons.SetActive(!a);
Animation Opt = Options.GetComponent<Animation>();
Opt.Play("OptionEnter");
}if (a == false) {
Animation d = Buttons.GetComponent<Animation> ();
d.Play ("mainbuttonenter");
Options.SetActive (false);
}
}
public void Credits(bool a){
if (a == true) {
CreditsPanel.SetActive(a);
Buttons.SetActive(!a);
Animation cr = CreditsPanel.GetComponent<Animation>();
cr.Play("EnterCredits");
}else {
CreditsPanel.SetActive(a);
}
}
public void Quit(bool a){
if (a == true) {
QuitPanel.SetActive(a);
Buttons.SetActive(!a);
Animation q = QuitPanel.GetComponent<Animation>();
q.Play("EnterQuit");
}else {
QuitPanel.SetActive(a);
}
}
public void Exit(bool a){
if (a == false) {
Option(false);
Buttons.SetActive(true);
CreditsPanel.SetActive(false);
QuitPanel.SetActive(false);
Options.SetActive(false);
PlayTab.SetActive(false);
saveSettings();
}
if (a == true) {
Application.Quit();
}
}
public void saveSettings(){
PlayerPrefs.SetFloat ("Quality", QualitySettings.GetQualityLevel ());
PlayerPrefs.SetFloat ("Volume", AudioListener.volume);
}
public void FullScreen(bool a){
if (Screen.fullScreen == a) {
Screen.fullScreen = !a;
} else {
Screen.fullScreen = a;
}
}
}
As far as I see, you have only defined the playTab variable, but not assigned it.
EDIT:
Try displaying it at start, then automatically hiding it via code. Probably Unity don't initialize objects that are not visible on scene from the start.
I have three characters and each of them has a camera attached to them.By default they are disabled but one.I made a character selector which is supposed to change them.I have a problem where I can move the selected one but the camera stays at the last one.
Here is the script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityStandardAssets.Utility;
public class GameManageer : MonoBehaviour {
public Camera[] cams = new Camera[3];
public Character CurrentCharacter;
public List<Character> Characters = new List<Character>();
public List<Item> AllItems;
bool ShowCharWheel;
public int SelectedCharacter;
public int lastCharacter;
public static GameManageer Instance;
void Awake(){
Instance = this;
foreach (Character c in Characters){
c.Instance = Instantiate(c.PlayerPrefab, c.HomeSpawn.position, c.HomeSpawn.rotation) as GameObject;
c.Instance.GetComponent<PlayerController>().LocalCharacter = c;
}
ChangeCharacter(Characters[PlayerPrefs.GetInt("SelectedChar")]);
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input.GetKey (KeyCode.C)) {
ShowCharWheel = true;
} else {
ShowCharWheel = false;
}
}
void ChangeCharacter(Character c){
lastCharacter = SelectedCharacter;
SelectedCharacter = Characters.IndexOf (c);
cams [SelectedCharacter].gameObject.SetActive (true);
cams [lastCharacter].gameObject.SetActive (false);
CurrentCharacter = c;
Characters [lastCharacter].Instance.GetComponent<PlayerController> ().CanPlay = false;
Characters [SelectedCharacter].Instance.GetComponent<PlayerController> ().CanPlay = true;
PlayerPrefs.SetInt ("SelectedChar", SelectedCharacter);
}
void OnGUI(){
if (ShowCharWheel) {
GUILayout.BeginArea(new Rect(Screen.width - 64, Screen.height - 192,64,192));
foreach (Character c in Characters){
if (GUILayout.Button(c.Icon,GUILayout.Width(64),GUILayout.Height(64))){
ChangeCharacter(c);
}
}
GUILayout.EndArea();
}
}
}
[System.Serializable]
public class Character {
public string Name;
public Texture2D Icon;
public GameObject PlayerPrefab;
public GameObject Instance;
public Transform HomeSpawn;
}
[System.Serializable]
public class Item{
public string Name;
public Texture2D Icon;
public ItemInstance InstancePrefab;
}
This should do the job:
cams[SelectedCharacter].enabled = true;
cams[lastCharacter].enabled = false;
Use Depth:
foreach (Camera cam in cams)
{
cam.depth = cam == cams[SelectedCharacter] ? 10 : 0;
}
I think the real problem here though, is that you have more cameras in the scene which you have to manage as well, other then only the last and current selected character... in which case:
foreach (Camera cam in cams)
{
cam.SetActive(cam == cams[SelectedCharacter]);
}