Pass Value to One Script to Another in Unity3d - c#

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;

Related

How to make object appear when a certain torso is called using C# in Unity

This is the code I used for a tutorial
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Trial_Changer : MonoBehaviour
{
[Header("Sprite To Change")]
public SpriteRenderer bodyPart;
[Header("Sprites to Cycle Through")]
public List<Sprite> options = new List<Sprite>();
public static int currentTorsoOption = 0;
public void NextOption ()
{
currentTorsoOption++;
if (currentTorsoOption >= options.Count)
{ currentTorsoOption = 0; }
bodyPart.sprite = options[currentTorsoOption];
}
public void PreviousOption()
{
currentTorsoOption--;
if (currentTorsoOption <= 0)
{ currentTorsoOption = options.Count - 1; }
bodyPart.sprite = options[currentTorsoOption];
}
}
**This is the code I am using to try to say "if torso 2 is called, create object"
**
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpeechAppears : MonoBehaviour
{
public GameObject speechBubbleTOSpawn;
private int Torso = Trial_Changer.currentTorsoOption;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Torso == 2)
{
Instantiate(speechBubbleTOSpawn);
}
}
}
Except the torso just appears always.
What do I do to fix this?
I want an object to appear when torso 2 is on the screen but instead the object is just always present. What do I do ?
The culprit is this line :
private int Torso = Trial_Changer.currentTorsoOption;
Since you assign value Torso only once at the start of the game, its value always be the same.
Try this :
private int Torso => Trial_Changer.currentTorsoOption;
This change Torso from a field to a property, and when Torso is used, it will read the current value of Trial_Changer.currentTorsoOption.

.GetComponent Function Makes my Variable = 0

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.

Function not showing up in OnClick() for unity

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;
}
}

Initialize a variable and print its value on every frame

I'm trying to implement a "health" property for an object. I want health to equal 100 at the start of the game, and print the health every frame so I can debug.
Here's my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class healthScript : MonoBehaviour {
// Use this for initialization
void Start () {
public int health = 0;
}
// Update is called once per frame
void Update () {
}
}
How can I do this?
If you want to debug value each frame this will work:
public class healthScript : MonoBehaviour
{
//Variable declaration
private int _health;
// Use this for initialization
void Start()
{
_health = 100;
}
// Update is called once per frame
void Update () {
Debug.Log(_health);
}
}
Your error was that you have defined your variable inside a Start method, so it's only visible inside this method. But when you define a variable inside the class but outside any method it's visible inside all the class. But as for variables visible inside and outside the class, where they are declared see manual about access modifiers.
But I can suggest you a more convenient way:
public class healthScript : MonoBehaviour
{
//Property
public int Health
{
get { return _health; }
set
{
_health = value;
Debug.Log("Health changed to value: " + _health);
}
}
//Variable declaration
private int _health = 100;
}
In this case the you use properties to debug the value of your health. So every time you will change a value of health like that Health = someIntValue you'll get a console message about your current health level.

how to declare/use a getcomponent variable in Unity3D c#

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)

Categories