I have tried many for few hours and am scratching my head on how to get this done.
I need to get a variable from a script and change it by +3
using UnityEngine;
using System.Collections;
public class SwordKillScript : MonoBehaviour {
public GameObject moneyAmount;
private Component MoneyText;
void Awake () {
moneyAmount = GameObject.FindGameObjectWithTag ("Money");
MoneyText = moneyAmount.GetComponent<moneyText> ();
}
void OnCollisionEnter2D (Collision2D collisonInfo){
Debug.Log ("Killed");
if (collisonInfo.collider.tag != "Player") {
MoneyText.money += 3;
Destroy (collisonInfo.collider.gameObject);
}
transform.position = transform.position;
}
}
That is the code for a sword, when it hits an object it destroys it then is supposed to add +3 to this script:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class moneyText : MonoBehaviour {
Text txt;
public int money = 20;
void Start () {
txt = gameObject.GetComponent<Text>();
txt.text= "$: " + money;
}
}
any help is great, I hope that this question is easy to read and answer.
Please answer as simply as possible and give the reason why, I will end up doing this sort of thing many times over and would love to know.
Thankyou!
BTW: Expect errors, I need to know what I can do to make this work - Thanks again.
EDIT: Here is the code I am having more trouble with, i've fiddled with assigning everything from strings to getcomponent, HALP!
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class MoneyText : MonoBehaviour {
public GUIText txt;
public int money = 20;
public void ModifyMoney () {
money += 3;
txt.text = "$: " + money;
}
}
There's nothing wrong in your script. You're getting the component correctly, and also incrementing the value correctly. The reason you're probably not seeing the updated value is because you set the value of the text only once in the Start() function.
i.e. txt.text= "$: " + money;
There's many ways of updating the text. You could do any of the following
A) Make the txt variable in moneyText public. Then in your SwordKillScript, you can add the following line
MoneyText.money += 3; //You have this already
moneyAmount.txt.text = "$: "+MoneyText.money; //Add this line
B) Write a method in the moneyText class which modifies the value of money.
public void ModifyMoney (int howMuch) {
money += howMuch;
txt.text = "$: "+money;
}
Call this method from SwordKillScript
C) You can make money a property.
private int money = 20;
public int Money {
get { return money; }
set {
money = value;
txt.text = "$ : "+money;
}
}
Then, in SwordKillScript, you just need to increment Money
P.S. Your naming conventions are a little off. Might I suggest that you take a look at it? Class names, for example, begin with an uppercase (MoneyText instead of moneyText)
Related
StripeNum is on a button and the colour function is set to the same colour button and using Debug.Log it shows stripe1 = 20. But in the second script Debug.Log stripe1.stripe1 = 0. Im just referencing the game object the script is on (the same gameobject is used as the object for the button) Image of The Console Showing Debug.Logs
using UnityEngine;
public class StripeNum : MonoBehaviour
{
public void black()
{
stripe1 = 0;
}
public void brown()
{
stripe1 = 10;
}
public void red()
{
stripe1 = 20;
Debug.Log(stripe1);
}
public void orange()
{
stripe1 = 30;
}
public void yellow()
{
stripe1 = 40;
}
public void green()
{
stripe1 = 50;
}
public void blue()
{
stripe1 = 60;
}
public void purple()
{
stripe1 = 70;
}
public void grey()
{
stripe1 = 80;
}
public void white()
{
stripe1 = 90;
}
public float stripe1;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class FinalCalc : MonoBehaviour
{
Scene c_scene;
float TwoStripesAdded;
float FinalR;
public Text FinalNum;
void Start(){
c_scene = SceneManager.GetActiveScene();
GameObject gameobject = GameObject.Find("GameObject");
StripeNum stripe1 = gameobject.GetComponent<StripeNum>();
Stripe2Num stripe2 = gameobject.GetComponent<Stripe2Num>();
Stripe3Num stripe3 = gameobject.GetComponent<Stripe3Num>();
Stripe4Num stripe4 = gameobject.GetComponent<Stripe4Num>();
if (c_scene.buildIndex == 6){
TwoStripesAdded = stripe1.stripe1 + stripe2.stripe1;
Debug.Log($"Added {stripe1.stripe1} and {stripe2.stripe1} and got {TwoStripesAdded}");
FinalR = TwoStripesAdded * stripe3.stripe1;
FinalNum.text = FinalR.ToString() + "Ω " + "±" + stripe4.stripe1 + "%";
}
}
}
Why not just name the class Stripe and have multiple instances of it? You can have empty child GameObjects and you can plop each stripe MonoBehaviour on the empty child. Then you can name the GameObject Stripe1, Stripe2, etc.
In Start() you can find those GameObjects, get the component attached to each, and cache those references so you don't have to keep re-getting them.
Aaaand actually in looking at your code I was assuming you were running this in Update, but you're running the check in Start. I don't know when or how you're setting colors, but if you're doing it in Play mode it's already too late, because this script won't check the colors.
You can't activate the methods until play mode (which is why I was asking you how you set it), so the only way to get a reading is if you set the value in Editor mode, but again that's not going to call a method.
Maybe what you're doing is setting the value in Editor mode that corresponds to a color?
Whatever the case, I think your data is not initialized when you check it, which is only once, before the first frame is drawn. If you're getting other debug messages then I need to know how you're getting. The Sum should be printed before anyone gets to set a value in Play mode.
Also a thought - you're checking the scene for some reason? If you set values and change scenes, all your objects are destroyed. The resistor calculator in one scene is a different instance than the one in scene 6 and will not have any values set on any stripes.
I've been trying to get a function to return a number to change the text in a button. However, I can not use the functions I wrote with OnClick(). I won't show up.
Here is the script I've been working with.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class DiceRollerBehavior : MonoBehaviour
{
public int setRandom;
// Start is called before the first frame update
void Start()
{
setRandom = 0;
}
// Update is called once per frame
void Update()
{
}
public int roll()
{
setRandom = Random.Range(1, 10);
Debug.Log("Your new number is:" + setRandom.ToString());
return setRandom;
}
}
The OnClick() should put the roll function in this list but doesn't.
I just need to be able to trigger a function in this script using the OnClick() feature for unity.
To be able to set a callback here it must be public void, not public int.
Also, your code will not change any text. To be able to do this, you need to assign the text label you want to change to a class field. So, it will look like this:
public class DiceRollerBehavior : MonoBehaviour
{
[SerializeField]
private Text _text; // assign this field in the inspector
public int setRandom;
void Start()
{
setRandom = 0;
}
public void OnBtnClick()
{
int rollValue = roll();
_text.text = #"{rollValue}";
}
int roll()
{
setRandom = Random.Range(1, 10);
Debug.Log("Your new number is:" + setRandom.ToString());
return setRandom;
}
}
I'm trying to create a shop in another scene. You can access it anytime while playing by pressing H. My problem is that the coins that the player has collected doesn't get saved. I've been trying to search for answers but nothing seems to help.
The Codes:
My Global Code that I use to save varibles:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Global : MonoBehaviour
{
public static Global Instance;
public int sumCoins;
void Awake(){
if (Instance == null){
DontDestroyOnLoad(gameObject);
Instance = this;
} else if (Instance != this){
Destroy(gameObject);
}
}
}
The code I use to buy items:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Shop : MonoBehaviour
{
public Button milk;
void Start()
{
Debug.Log("you have " + Global.Instance.sumCoins);
milk.onClick.AddListener(AddMilk);
}
void AddMilk(){
Debug.Log("You bought milk");
//if player has more than 5 coins.
//add milk
//else if player has less than 5 coins
//display "You cant buy this"
//else if player doesnt have a slot available
//display "You cant buy this"
}
}
The code that's used for counting and adding coins:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Coinsystem : MonoBehaviour
{
public int sumCoins = 0;
private int addedCoins;
int coins;
Text txt;
public GameObject count;
public void Start(){
Debug.Log("coin system working");
txt = count.GetComponent<Text>();
txt.text = "" + sumCoins;
sumCoins = Global.Instance.sumCoins;
}
public void Update(){
txt.text = "" + sumCoins;
}
public void AddCoins(int addedCoins){
sumCoins += addedCoins;
Debug.Log("Coins Added!");
}
public void SaveMoney(){
Global.Instance.sumCoins = sumCoins;
}
}
Thank you for taking your time to read this!
A quick way of solving this problem would be to use a static class. I have sometimes used this method to persist data throughout the application life span.
public static class GameData {
private static int coins = 0;
public static void SetCoins(int coinsIn)
{
coins = coinsIn;
}
public static void AddCoins(int coinsIn)
{
coins += coinsIn;
}
public static int GetCoins()
{
return coins;
}
}
Then you can just call the methods like this:
GameData.SetCoins(...);
GameData.AddCoins(...);
var coins = GameData.GetCoins();
The other way people solve this problem is as follows:
Save/Load to and from local storage (This can be used in conjunction with the class
above or used on it's own).
PlayerPrefs, similar to using a static class. Find out more about that
here.
Creating an object with a script attached that uses DontDestroyOnLoad. Find
out more about that here.
I wouldn't normally recommend the use of static classes because it is generally bad programming practice but sometimes it is required to get around limitations like this.
Generally, as a rule of thumb, if you are going to use a static class there is usually a better way of doing it.
I would probably say the most preferred way would be to Save/Load the data to and from local storage as and when needed but this approach is a bit too much for what you want to do.
Currently, I'm trying to add / subtract value from one script to another. I wanted script one to add +125 health to script two but don't know how. There is no gameobject involved in this scenarios.
Script one is
using UnityEngine;
using System.Collections;
public class AddHealth : MonoBehaviour {
int health = 10;
public void ChokeAdd()
{
AddHealthNow();
}
public void AddHealthNow()
{
health += 125;
Debug.Log("Added +125 Health");
}
}
Script two is
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
namespace CompleteProject
{
public class DataManager : MonoBehaviour
{
public static int depth;
public Text BOPPressureText;
int health = 20;
void Awake ()
{
depth = 0 ;
}
void Update ()
{
BOPPressureText.text = depth + 7 * (health) + " psi ";
}
}
}
If you're trying to add health to your second script, declare your health field as public. So that you can access its value in your first script.
public int health;
But I wouldn't do stuff like that. Expose this field by a property like:
public int Health
{
get
{
return this.health;
}
set
{
this.health = value;
}
}
by default the health will be declared as
private int health;
Other scripts can't access private fields.
Also you need a reference to your second script. You can access this via:
public DataManager data;
You've to assign your second object into this field in your Unity Editor. Then
This way, you can access the field healthby calling data.health += 125 in your first script.
I don't know the specific thing in Unity, but I think you can also call your script by:
DataManager data = GetComponent<DataManager>();
data.health += 125;
Other method to get your other script is call it like that in your first script:
var secondScript = GameObject.FindObjectOfType(typeof(DataManager)) as DataManager;
secondScript.health += 125;
I'm very new to the programming / scripting scene and I'm following a tutorial for making a basic controller and combat system (Birds view RPG). Thing is the tutorial will be making a "click to attack" (targeting) when me myself want to make a "attack closest enemy" type of combat.
What I have managed to do so far is having 3 opponents but I'm only able to attack 1 of them, thats where the instructor starts to add a targeting script which I wanna avoid. I tried finding someone else with a somewhat similar problem on answers.unity3d.com and tried to incorporate the code into my own project. The result seems to be slightly lacking and need help figuring out what it might be!
I did see many similar problems and tried to copy/paste code but there always seem to be minor issues I'm not familiar solving. (For example getting Tags to work?)
///Player code:
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
public string name;
public int health;
public int damage;
public float range;
public Transform opponent;
void Start ()
{
}
void Update ()
{
Player. ();
}
void Player.Attack()
{
if(Input.GetKeyUp (KeyCode.Space))
{
if(Vector3.Distance(opponent.transform.position, transform.position);
{
if(opponent != null && Vector3.Distance (opponent.position, Transform.position) < Range)
{
opponent.GetComponent<Enemy>().GetHit(damage);
}
}
///Enemy code:
using UnityEngine;
using System.Collections;
public class Enemy : MonoBehaviour
{
public string name = "Monster";
public int health;
public int damage;
void Start ()
{
}
void Update ()
{
}
public void GetHit(int playerDamage)
{
health = health - playerDamage;
}
void OnMouseOver()
{
Player.opponent = Transform;
}
}