Unity Buttons Assignment [duplicate] - c#

This question already has answers here:
How to access a variable from another script in another gameobject through GetComponent?
(3 answers)
In Unity, how can I pass values from one script to another?
(4 answers)
Closed 3 years ago.
I'm pretty new to C# and Unity, so sorry if my question is too simple.
I'm trying to create an easy Upgrade System made from text and button for each stat.
I made the Text script to show my "Attack Damage" stat, which worked. Now, I want to create a script Button so once that I click it my stat will go from (ex. 10 to 11) or anything. So my question is: how can I access variables from another script so that i can use them to be incremented by clicking the button?
I'll attach both the scripts, please try to explain as simple as you can, so that a newbie can understand. Thanks!
Attack Damage Text Script ( Keep in mind that in Player class the heroDamage is set to 10f)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AttackDamage : MonoBehaviour
{
public static float attackDamage = Player.heroDamage;
public Text attackDamageText;
// Start is called before the first frame update
void Start()
{
attackDamageText.text = ADButton.attack.ToString(); //here it was attackDamage.ToString() at first but i wanted to see if it works like that.
}
// Update is called once per frame
void Update()
{
}
}
Attack Damage Button Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ADButton : MonoBehaviour
{
public Button attackDamageButton;
public static float attack;
// Start is called before the first frame update
void Start()
{
attackDamageButton.onClick.AddListener(Update);
}
// Update is called once per frame
void Update()
{
attack = AttackDamage.attackDamage;
if (Input.GetMouseButtonDown(0))
attack++;
}
}
I guess my second code is wrong, but I don't know how can I modify it.

https://answers.unity.com/questions/1336162/how-to-reference-a-class-in-another-script-properl.html
This shows various possible methods.
But the simpler is reference by object.
like
public class AttackDamage : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
public void Method1()
{
// Do Something like Attack++;
}
}
public class ADButton : MonoBehaviour
{
public AttackDamage obj;
// Start is called before the first frame update
void Start()
{
obj.Method1();
}
}
Also in this case you need to assign the class AttackDamage in inspector on GameObject having ADButton script.

Related

Unity Console says "type or namespace definition, or end of file expected unity"

I'm making a VR test and I've run into a problem and am not sure what to do. Unity keeps saying "type or namespace definition, or end of file expected unity" I am using someone else's code but I am following the tutorial. Here is my code
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class VrRig : MonoBehaviour { }
public Transform headConstraint;
public Vector3 headBodyOffset;
{
// Start is called before the first frame update
void Start()
{
headBodyOffset = transform.position - headConstraint.position;
}
// Update is called once per frame
void Update()
{
transform.position = headConstraint.position + headBodyOffset;
transform.forward = Vector3.ProjectOnPlane(headConstraint.up,Vector3.up).normalized;
}
}
you are creating an empty class by having the curly brackets open and closed right after the class declaration. after you declare a code block with class members but never assign it to anything. If you put an opening curly bracket right after the class declaration and close it after all your members, it should work.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class VrRig : MonoBehaviour
{
public Transform headConstraint;
public Vector3 headBodyOffset;
// Start is called before the first frame update
void Start()
{
headBodyOffset = transform.position - headConstraint.position;
}
// Update is called once per frame
void Update()
{
transform.position = headConstraint.position + headBodyOffset;
transform.forward = Vector3.ProjectOnPlane(headConstraint.up,Vector3.up).normalized;
}
}

How do i use a script in another script? [duplicate]

This question already has answers here:
How to access a variable from another script in another gameobject through GetComponent?
(3 answers)
Closed 2 years ago.
so, my code;
Script one;
using System.Collections.Generic;
using UnityEngine;
public class mousePosTracker : MonoBehaviour
{
public Vector2 mousePos;
public void Update()
{
mousePos = Input.mousePosition;
Debug.Log(mousePos);
}
}
and script two;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class player : MonoBehaviour
{
void Update()
{
transform.Translate(// mouse position);
}
}
the code currently is pretty bare-bones, but I will fix that. so what I want to do is; I want to access the vector2 mousePos variable in script2, so that I can move the player based on the mouse position.
Make a reference on your Player script to your MousePosTrackerScript and use it.
One recommendation, use CamelCase on your class names.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public MouseousePosTracker posTracker = null; //attach it from your Editor or via script
void Update()
{
transform.Translate(posTracker.mousePos);
}
}
One easy way is to use the Find method.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
private MousePosTracker mousePosTracker;
void Start(){
mousePosTracker = GameObject.Find("gameobject name which has the MousePosTrackerScript").GetComponent<MousePosTracker>()
}
void Update()
{
transform.Translate(mousePosTracker.mousePos);
}
}
If the gameobject has a tag you can use the FindWithTag method too.
Do like this in your 2nd script, always make sure your script has first letter in caps.
EDIT: if you do not want to give reference (drag&drop) in editor, use the below example. If you want it to be simpler without providing reference in the script, use Lotan's solution.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
private MousePosTracker mouse;
void Start()
{
mouse = (MousePosTracker) GameObject.FindObjectOfType(typeof(MousePosTracker));
}
void Update()
{
transform.Translate(mouse.mousePos);
}
}

Error: "NullReferenceException: Object reference not set to an instance of an object" for 2 scripts on one object in Unity

There is a chance this is a duplicate, but I have tried and tried to get this to work and it's probably something simple.
I'm trying to get two scripts to interact on one object. I would like a basic generic physics script that will handle all the interactions for all my objects.
Script 1:
// Simple Player1
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player1 : MonoBehaviour
{
Physics physics_script;
void Start(){
physics_script = gameObject.GetComponent<Physics>();
}
// Update is called once per frame
void Update() {
physics_script.helloWorldFromAnotherScript();
}
}
Script 2:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Physics : MonoBehaviour
{
void Start(){
}
void Update() {
}
public void helloWorldFromAnotherScript()
{
Debug.Log("Hello world from player");
}
}
Edit:
I'm pretty sure the problem is here:
But I can't change it to save my life.
It should work.
Are you sure you have BOTH scripts added to the gameObject? At the image I only see player1, and I doubt if Physics it's added.
Elsewhere you can make physics_scripts public or serialize them(with [SerializeField]) and you will be able to drag'n'drop at the editor the script to the formfield. Thats allows you to not use the GetComponent<> at start.
Remember to delete start and update methods if you dont use them.

Find the 'Number' of the Scene the Player is in to Save it in PlayerPref Unity

I'm working on a 2D Pixel Platformer RPG, I need to develop a save and load mechanism in it. There are several scenes in the game (and will have many more), the question is, how do I save the scene number the player is currently in, so that when he quits and reloads the game, he's in the same scene. How can I implement it in C# Unity. (please be clear as I'm somewhat a beginner).
Ok, so there are a few things you need to do in order to achive this:
First, in the first scene in your build - create an Empty GameObject, name it "SceneManager".
Then, create a new tag "SceneManager" and add it to the "SceneManager" GameObject
Finally, add the "SceneManager" script to the "SceneManager" GameObject:
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneManager : MonoBehaviour
{
void Awake()
{
DontDestroyOnLoad(gameObject);
}
public void SaveScene()
{
int activeScene = SceneManager.GetActiveScene().buildIndex;
PlayerPrefs.SetInt("ActiveScene", activeScene);
}
public void LoadScene()
{
int activeScene = PlayerPrefs.GetInt("ActiveScene");
SceneManager.LoadScene(activeScene);
}
}
Then, you can load/save scenes by using this script:
using UnityEngine;
public class UsageScript: MonoBehaviour {
private SceneManager SceneManager;
void Awake ()
{
sceneManager = GameObject.FindGameObjectWithTag("SceneManager").GetComponent<SceneManager>();
}
void UsageManager()
{
sceneManager.SaveScene();
sceneManager.LoadScene();
}
}

Set Time Selection in Unity

I am doing a Unity project.
I have two scenes in my project.
In the first scene. I set three buttons texted "1 min", "2 mins" and "3 mins".
And I want to have the corresponding game duration in my second scene (game scene).
I have countdown function in my script.
now I am using singleton pattern following the steps of this tutorial. https://www.youtube.com/watch?v=CPKAgyp8cno
Problem is when I run the game, three texts of time start simultaneously.
And my buttons in Scene one could control load scenes but not choose time.
The following are the codes. In the PersistentManager Script which attached to the PersistentManager game object:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PersistentManagerScript : MonoBehaviour
{public static PersistentManagerScript Instance { get; private set; }
public int Value;
// Start is called before the first frame update
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
}
In the SceneManager Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SceneManagerScript : MonoBehaviour
{
public GameObject CountDownIn1;
public GameObject CountDownIn2;
public GameObject CountDownIn3;
public Text ValueText;
public Text ValueText1;
public Text ValueText2;
private void Start()
{
switch (this.gameObject.name)
{
case "Button1min":
SetGameTimeEqualOne();
break;
case "Button2mins":
SetGameTimeEqualTwo();
break;
case "Button3mins":
SetGameTimeEqualThree();
break;
}
}
public void SetGameTimeEqualOne()
{
CountDownIn1.SetActive(true);
ValueText.text = PersistentManagerScript.Instance.Value.ToString();
Debug.Log("COUNTDOWN1 active");
//DontDestroyOnLoad(this.CountDownIn1);
}
public void SetGameTimeEqualTwo()
{
CountDownIn2.SetActive(true);
Debug.Log("COUNTDOWN2 active");
ValueText1.text = PersistentManagerScript.Instance.Value.ToString();
DontDestroyOnLoad(this.gameObject);
}
public void SetGameTimeEqualThree()
{
CountDownIn3.SetActive(true);
Debug.Log("COUNTDOWN3 active");
ValueText2.text = PersistentManagerScript.Instance.Value.ToString();
DontDestroyOnLoad(this.gameObject);
}
Any suggestions will be appreciated.
There are multiple ways to pass data between scenes. The most common recommendation is to use a Singleton pattern that is consumed by other scripts in each scene. However, this can be overly complicated.
Interestingly enough, Unity's newer ScriptableObjects can be used for a similar strategy. Since ScriptableObjects are persisted at a higher scope than scenes, you can use them to hold data between scenes without having to utilize statics and singletons. Unity even markets them as more than just data containers! I prefer to pass data between objects and scenes by creating a common scriptable object, and referencing that asset in each script that needs to share data (regardless of scene).
Here's an example using your requirement:
GameData.cs
[CreateAssetMenu(fileName = "GameData", menuName = "Game Data")]
public class GameData: ScriptableObject
{
float gameDuration; //This is where you will store and read your selected game duration
}
GameSelection.cs This script exists on Scene 1
public class GameSelection : Monobehaviour
{
public GameData gameData;
public void SetDuration(float time) //Call this method from each button with a different parameter
{
gameData.gameDuration = time;
}
}
Countdown.cs This script exists in Scene 2
public class Countdown: Monobehaviour
{
public GameData gameData;
float countdownTimer;
public void Start()
{
countdownTimer = gameData.gameDuration;
}
//... rest of your countdown script
}
Now you can create a GameData asset in your project folder and drag it into the inspector in Scene1, and the inspector in Scene2. If Scene1 changes the value of the timer, Scene2 will know about it. Additionally, you can set a default value for gameDuration on the GameData asset and run/test Scene2 without having to run Scene1 first!

Categories

Resources