For no apparent reason Unity has started just now started showing errors in this code such as the attachment picture below.
I cannot get over this error and can't find a single explanation.
Since it seems fairly simple l think there might be some people who can give a hint.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Animation : MonoBehaviour
{
private Animation anim;
void Start()
{
anim = GetComponent<Animation>();
}
private void Update()
{
anim.Play();
}
}
Your own class is called Animation .. and no it has no such method ;)
Careful with naming your class equally to an already existing one.
You will now have to use explicitly UnityEngine.Animation everywhere
public class Animation : MonoBehaviour
{
private UnityEngine.Animation anim;
void Start()
{
anim = GetComponent<UnityEngine.Animation>();
}
private void Update()
{
anim.Play();
}
}
since otherwise the compiler will of course assume by Animation you are referring to your class itself.
In general: what is the purpose of calling Play every frame?
Related
I am currently working on making a class accessible from other scripts. Below is what I have coded.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(BoxCollider2D))]
// Start is called before the first frame update
public class _move
{
private float _sizex;
private float _sizey;
public _move(float sizx, float sizy....etc)
{
_sizex = sizx;
_sizey = sizy;
}
public void regularmove(float sizex, float sizey...etc)
{
GameObject _player;
_player = GameObject.GetComponent<GameObject>();
BoxCollider2D bc2d;
bc2d = _player.GetComponent <BoxCollider2D>();
bc2d.offset = new Vector2(locationx + 1, locationy);
}
}
however, when I try to compile it, it gives me an error.
cannot access non-static method"GetComponent"
on this line of code
_player = GameObject.GetComponent<GameObject>();
I do not know why this is happening because I have not declared the class as static, and do not really know the properties of GetComponent that well. Can someone tell me what is happening and how I can solve this?
Also, when I change
GameObject _player;
to
public GameObject player;
the scripts below suddenly cease to work, giving me errors like
cannot resolve symbol _player
what exactly is happening here?
Thanks in advance!
Whatever script creating the instance of the _move class (This is bad naming btw, it should be Move) should also pass its gameObject to the constructor.
// attributes here are not valid if your class is not a MonoBehaviour
public class Move
{
GameObject m_object;
public Move(GameObject obj, ...)
{
m_object = obj;
}
}
if your class is meant to be a MonoBehaviour component, then it has a GameObject member already and you can use the attributes:
[RequireComponent(typeof(BoxCollider2D),typeof(Rigidbody2D))]
// Start is called before the first frame update
public class Move : MonoBehaviour
{
void Start()
{
Debug.Log(gameObject.name);
}
}
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.
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();
}
}
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!
The unity standard component comes pre-packaged with errors on visual studio and im trying to learn so I tried playing around with the auto-correct system and got it down to the fewest errors I could.
I made sure I have the most up to date unity and VisualStudio with all relevant plugins.
https://gist.github.com/EgoSphere001/288818beb7ad0d2db2bdda028508c76e
Please look at your script again
public class PlayerMovement : MonoBehaviour
{
public PlayerMovement()
{
}
}
public Rigidbody rb;
// Start is called before the first frame update
private void Start() => Debug.Log("Hello, World!");
// Update is called once per frame
private void Update()
{
}
You are closing the PlayerMovement class ... so where does rb and Update belong to?! You expression body for Start is ok-ish but I would suggest to stick with a normal method declaration.
Also MonoBehaviours can not be generated using a constructor so the public PlayerMovement(){ makes no sense either.
Your script should probably look like this
public class PlayerMovement : MonoBehaviour
{
public Rigidbody rb;
// Start is called before the first frame update
private void Start()
{
Debug.Log("Hello, World!");
}
// Update is called once per frame
private void Update()
{
}
}
Also note: You should remove any empty Unity messages like Update, Start etc .. because Unity calls them anyway causing unnecessary overhead.