Putting money.text in my shop scene - c#

I want my money.text to be in my shop scene to buy some shield.
For some reason my money.text is only on the other scene and it's not going in the shop scene.
This is my shop script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class ShopController : MonoBehaviour {
int MoneyAmount;
int isPowerup1Sold,isPowerup2Sold,isPowerup3Sold;
public Text MoneyAmountText;
public Button Buynow1,Buynow2,Buynow3;
// Use this for initialization
void Start () {
MoneyAmount = PlayerPrefs.GetInt ("moneyAmount");
}
// Update is called once per frame
void Update () {
MoneyAmountText.text = "Money : " + MoneyAmount.ToString ();
isPowerup1Sold = PlayerPrefs.GetInt ("isPowerup1Sold");
isPowerup2Sold = PlayerPrefs.GetInt ("isPowerup2Sold");
isPowerup3Sold = PlayerPrefs.GetInt ("isPowerup3Sold");
if (MoneyAmount >= 50 && isPowerup1Sold == 0)
Buynow1.interactable = true;
else
Buynow1.interactable = false;
if (MoneyAmount >= 70 && isPowerup2Sold == 0)
Buynow2.interactable = true;
else
Buynow2.interactable = false;
if (MoneyAmount >= 120 && isPowerup3Sold == 0)
Buynow3.interactable = true;
else
Buynow3.interactable = false;
}
public void buyPowerup1()
{
MoneyAmount -= 50;
PlayerPrefs.SetInt ("isPowerup1Sold", 1);
}
public void buyPowerup2()
{
MoneyAmount -= 70;
PlayerPrefs.SetInt ("isPowerup2Sold", 1);
}
public void buyPowerup3()
{
MoneyAmount -= 120;
PlayerPrefs.SetInt ("isPowerup3Sold", 1);
}
public void exitshop()
{
PlayerPrefs.SetInt ("moneyAmount", MoneyAmount);
Application.LoadLevel ("levelselect");
}
}
this is my money script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Money : MonoBehaviour {
public Text MoneyText;
public static int MoneyAmount = 0;
// Use this for initialization
void Start () {
MoneyAmount = PlayerPrefs.GetInt ("moneyAmount",0);
}
// Update is called once per frame
void Update () {
MoneyText.text = "Money" + MoneyAmount.ToString();
}
}
this is my shield.power script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Money : MonoBehaviour {
public Text MoneyText;
public static int MoneyAmount = 0;
// Use this for initialization
void Start () {
MoneyAmount = PlayerPrefs.GetInt ("moneyAmount",0);
}
// Update is called once per frame
void Update () {
MoneyText.text = "Money" + MoneyAmount.ToString();
}
}
This is where i put my money.text to show in the canvas scene.(the highlight blue color).

Text is an UI component for rendering strings on UI. Each scene need to have its own Text-component.
Then you need to keep the amount of money in one place so that every script dealing with money does not have its own MoneyAmount variable.
Money script could look like this:
public class Money : MonoBehaviour {
static int? cachedAmount = null;
const string playerPrefsKeyName = "moneyAmount";
const int startMoney = 0;
public static int Amount {
get {
if (cachedAmount == null) {
cachedAmount = PlayerPrefs.GetInt (playerPrefsKeyName, startMoney);
}
return cachedAmount.Value;
}
set {
if (cachedAmount == null || value != cachedAmount.Value) {
PlayerPrefs.SetInt (playerPrefsKeyName, value);
cachedAmount = value;
}
}
}
}
...and whenever you use money, you could use
if (Money.Amount >= 70) {
Money.Amount -= 70;
MoneyAmountText.text = "Money : " + Money.Amount.ToString ();
}

Related

How to make the Spheres able to deal damage to eachother?

Want to make my Spheres able to damage each other
Have tried to get the component of the other object
Health script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Hitpoints
{
private int health;
public int healthMax;
public Hitpoints(int health)
{
this.health = health;
}
public int GetHealth()
{
return health;
}
public float GetHealthPercent()
{
return (float)health / healthMax;
}
public void Damage(int damageAmount)
{
health -= damageAmount;
if (health < 0)
{
health = 0;
}
}
public void Heal(int healAmount)
{
health += healAmount;
if (health > healthMax)
{
health = healthMax;
}
}
}
Damage script
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class Detect_Blue : MonoBehaviour
{
Hitpoints hitpoints = new Hitpoints(100);
bool onetime = false;
public float radius;
public Vector3 direction = new Vector3(2, 2, 2);
private void Start()
{
Debug.Log("Health: " + hitpoints.GetHealth());
InvokeRepeating("DetectEnemy", 4f, 2f);
}
private void DetectEnemy()
{
var hitColliders = Physics.OverlapSphere(direction, radius);
for (var i = 0; i < hitColliders.Length; i++)
{
if (hitColliders[i].CompareTag("Player"))
{
if (!onetime)
{
onetime = true;
print(hitColliders[i].tag);
InvokeRepeating("Hello", 1, 1);
}
}
// collect information on the hits here
}
}
private void Hello()
{
var hitColliders = Physics.OverlapSphere(direction, radius);
for (var i = 0; i < hitColliders.Length; i++)
{
if (hitColliders[i].CompareTag("Player"))
{
hitColliders[i].GetComponent<Hitpoints>().Damage(10);
}
Debug.Log("Damaged: " + hitColliders[i].GetComponent<Hitpoints>().GetHealth());
if (hitpoints.GetHealth() == 0)
{
Destroy(gameObject);
}
}
}
}
ArgumentException: GetComponent requires that the requested component 'Hitpoints' derives from MonoBehaviour or Component or is an interface.
UnityEngine.Component.GetComponent[Hitpoints] () (at C:/buildslave/unity/build/Runtime/Export/Component.bindings.cs:42)
Detect_Blue.Hello () (at Assets/Detect_Blue.cs:57)
When you do GetComponent<T> on a game object, the type of T should inherit from monobehaviour.(Since Monobehavior are components for game-object, and you are trying to get a component)
To fix this, just simply use the hitpoints you have already created in Detect_Blue.
Debug.Log("Damaged: " + hitColliders[i].GetComponent<Hitpoints>().GetHealth());
will become
Debug.Log("Damaged: " + hitColliders[i].GetComponent<Detect_Blue>().hitpoints.GetHealth());
likewise for hitColliders[i].GetComponent<Hitpoints>().Damage(10);, it should be:
hitColliders[i].GetComponent<Detect_Blue>().hitpoints.Damage(10);
Alternatively,
you can just simply make Hitpoints inherit from Monobehavior and attach the script to the respective gameObject.
Though in your case, the first solution will be more feasible.
Also, you can use OnCollisionEnter to detect when the balls enter collision with another object.

How can I use name of a conversation as a trigger to start a conversation instead using index?

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.

SquidCoin.cs My Currency Script is not working after adding [PlayerPrefs]

I have a currency script for my game that is not displaying how much money the user has.
It was working before I added the PlayerPrefs class.
But after the addition, it will not display anything.
FYI, the PlayerPrefs class allows me to display numbers across multiple scenes in Unity.
I have posted my code below
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class squidCoin : MonoBehaviour {
public Text coinDisplay;
public int addMoneyAmmount;
public int squidCoins;
public float saveInterval;
public float paycheckTime;
// Use this for initialization
void Start () {
squidCoins = 50;
PlayerPrefs.SetInt("SquidCoins", squidCoins);
StartCoroutine(moneyADD());
StartCoroutine("SaveMoney");
}
public void squidCoinPayCheck(int squidCoinsToAdd){
squidCoins += squidCoinsToAdd;
}
public void Awake(){
PlayerPrefs.GetInt("SquidCoinsSaves");
}
public void minusSquidCoin(int squidCoinsToSubtract){
if(squidCoins - squidCoinsToSubtract < 0){
Debug.Log ("Oops Hes Broke");
squidCoins += addMoneyAmmount;
}
else{
squidCoins -= squidCoinsToSubtract;
}
}
IEnumerator moneyADD(){
yield return new WaitForSeconds(paycheckTime);
squidCoins += addMoneyAmmount;
}
IEnumerator SaveMoney (){
while (true)
{
yield return new WaitForSeconds(saveInterval);
PlayerPrefs.SetInt("SquidCoinSaves", squidCoins);
}
}
// Update is called once per frame
void Update () {
coinDisplay.text = "You Have: " + PlayerPrefs.GetInt("SquidCoinsSaves");
}
}
i looked at all of your code and it seems there is have many wrong details. I just fixed it and noted your wrongs with comment in front of the wrong parts
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class squidCoin : MonoBehaviour {
public Text coinDisplay;
public int addMoneyAmmount;
public int squidCoins;
public float saveInterval;
public float paycheckTime;
// Use this for initialization
void Start () {
squidCoins = 50;
PlayerPrefs.SetInt("SquidCoinsSaves", squidCoins); //your string name was wrong
StartCoroutine(moneyADD());
StartCoroutine("SaveMoney");
}
public void squidCoinPayCheck(int squidCoinsToAdd){
squidCoins += squidCoinsToAdd;
}
public void Awake(){
//PlayerPrefs.GetInt("SquidCoinsSaves"); //you can not get it like this, first you must equal this ti intiger type varible
}
public void minusSquidCoin(int squidCoinsToSubtract){
if(squidCoins - squidCoinsToSubtract < 0){
Debug.Log ("Oops Hes Broke");
squidCoins += addMoneyAmmount;
}
else{
squidCoins -= squidCoinsToSubtract;
}
}
IEnumerator moneyADD(){
yield return new WaitForSeconds(paycheckTime);
squidCoins += addMoneyAmmount;
}
IEnumerator SaveMoney (){
while (true)
{
yield return new WaitForSeconds(saveInterval);
PlayerPrefs.SetInt("SquidCoinsSaves", squidCoins); //string name was wrong
}
}
// Update is called once per frame
void Update () {
coinDisplay.text = "You Have: " + PlayerPrefs.GetInt("SquidCoinsSaves");
}
}

Countdown starting at random negative number

My countdown timer in ShowRestartDialog() is acting funky. Instead of starting at the defined countdownLength (which is set to 5) it is starting at a random negative number and going down from there. Why would that be happening? Thanks!
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class CountdownTimer : MonoBehaviour
{
public static CountdownTimer countdownTimerInstance = null; // Create Singleton
public Object startingScene;
public GameObject timeOutWarningDialog;
private GameObject timerDialogBoxInstance;
private GameObject canvas;
private IEnumerator counter;
private Button stopCountButton;
private Text timerTextField;
public float countdownLength;
public float countdownDelay;
private float countdownInterval = 1.0f;
void Awake()
{
if (countdownTimerInstance == null)
countdownTimerInstance = this;
else if (countdownTimerInstance != null)
Destroy(gameObject);
DontDestroyOnLoad(gameObject);
}
public void StartPreCountTimer()
{
GameManager.preCountActive = true;
Debug.Log("StartPreCountTimer Timer has Started!");
if (GameManager.restartWarningActive == false)
Invoke("ShowRestartDialog", countdownDelay);
}
public void RestartPreCountTimer()
{
GameManager.preCountActive = false;
Debug.Log("StartPreCountTimer Timer has Restarted!");
CancelInvoke("ShowRestartDialog");
}
void ShowRestartDialog()
{
GameManager.preCountActive = false;
canvas = GameObject.FindGameObjectWithTag("Canvas");
timerDialogBoxInstance = Instantiate(timeOutWarningDialog); // instantiate timeout warning dialog
timerDialogBoxInstance.transform.SetParent(canvas.transform, false);
timerDialogBoxInstance.SetActive(true);
Text[] textFields = timerDialogBoxInstance.GetComponentsInChildren<Text>(true); // get reference to timer textfields
timerTextField = textFields[2]; // access and assign countdown textfield
stopCountButton = timerDialogBoxInstance.GetComponentInChildren<Button>(); // get reference to keep playing button
stopCountButton.onClick.AddListener(StopDialogTimer); // add button listener
if (timerDialogBoxInstance.activeInHierarchy == true)
InvokeRepeating("StartDialogTimer", 0, countdownInterval);
}
void StartDialogTimer()
{
float s = countdownLength--;
Debug.Log(s);
if (timerTextField != null)
timerTextField.text = s.ToString();
if (s == -1)
{
RestartGame();
}
}
void StopDialogTimer()
{
Debug.Log("Restart Cancelled");
CancelInvoke("StartDialogTimer");
Destroy(timerDialogBoxInstance);
}
void RestartGame()
{
SceneManager.LoadScene(startingScene.name);
}
}
You initialize bad your s variable.
float s = countdownLength--;
On declaration s = 0.0f - 5 ===> -5 first value
You never reach the -1 value to restart your game.
A way to reach is changing this:
if (s <= -1)
{
RestartGame();
}

C# unity convert iterated number to a ranged number based on number of clicks

I'm trying to get a number between 0 and 3. I am trying to iterate through a counter and every 5 clicks on a button, it calls a method, but I can't seem to figure it out. I have tried various ways to do it. If I could get some hints on how to complete this then please let me know. If you need any other info then also let me know. Thanks!
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Threading;
public class ButtonClick : MonoBehaviour {
private Vector3 starPos;
private int starCounter;
private int[] starTypes;
private int totalStarTypes = 4;
public Button button;
public UnityEngine.UI.Text starCounterText;
private Image starImage;
// Use this for initialization
void Start () {
starTypes = new int[totalStarTypes];
}
void Update(){
if (Input.GetMouseButtonDown (0)) {
starCounter++;
}
for (int i = 0; i < starCounter; i++) {
int j = i;
int type = (j % 5);
if (type == 0) {
//SpawnStar (j%5);
}
}
}
// Update is called once per frame
public void UpdateStar () {
starCounterText.text = "Star Counter: " + starCounter;
}
public void SpawnStar(int type){
if (type == 0) {
Debug.Log ("White Star Spawned!");
}
if (type == 1) {
Debug.Log ("Red Star Spawned!");
}
if (type == 2) {
Debug.Log ("Yellow Star Spawned!");
}
if (type == 3) {
Debug.Log ("Blue Star Spawned!");
}
}
}
Random r = new Random();
void Update()
{
if (Input.GetMouseButtonDown(0))
{
starCounter = (starCounter + 1) % 5;
if (starCounter == 0) SpawnStar(r.Next(0, 4));
}
}
Your code will spawn the all stars every frame after the 5'th click.
Try this, it will spawn a single star when you click, and only the one you wanted to spawn.
The int starCounter will handle which star to spawn
The bool executeSpawn will handle when to spawn a star
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Threading;
public class ButtonClick : MonoBehaviour {
private Vector3 starPos;
private int starCounter;
private bool executeSpawn;
private int[] starTypes;
private int totalStarTypes = 4;
public Button button;
public UnityEngine.UI.Text starCounterText;
private Image starImage;
// Use this for initialization
void Start () {
starTypes = new int[totalStarTypes];
}
void Update(){
if (Input.GetMouseButtonDown (0)) {
starCounter++;
executeSpawn = true;
}
if(executeSpawn) {
SpawnStar (i % 5);
executeSpawn = false;
}
}
// Update is called once per frame
public void UpdateStar () {
starCounterText.text = "Star Counter: " + starCounter;
}
public void SpawnStar(int type){
if (type == 0) {
Debug.Log ("White Star Spawned!");
}
if (type == 1) {
Debug.Log ("Red Star Spawned!");
}
if (type == 2) {
Debug.Log ("Yellow Star Spawned!");
}
if (type == 3) {
Debug.Log ("Blue Star Spawned!");
}
}
}

Categories

Resources