Method is not changing outer variable C# - c#

I want to change a outer variable (var1) inside a method to be able to use a getter to return it's value. But somehow var1 is only changed within the function and not global. How do I change the value of var1 inside of a method globally?
The code is really simple:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class PlayerMovement : MonoBehaviour
{
private float var1 = 0f;
void Update()
{
var1 = 5;
print(var1); // output: 5
}
public float GetVar1()
{
print(var1);
return var1; // output: 0
}
}
The update method is called by the gameengine unity itself and the getter is called in another class.
The class that calls the getter is here:
public class bullet : MonoBehaviour
{
public PlayerMovement playerdata;
private float output;
void Update()
{
output = playerdata.GetVar1();
}
}

If you expect output of a bullet instance to be 5, then you need to call Update() on the playerdata instance first:
public class bullet : MonoBehaviour
{
public PlayerMovement playerdata;
private float output;
void Update()
{
playerdata.Update();
output = playerdata.GetVar1();
}
}
I also note that unless bullet is incomplete code, you're not creating an instance of the PlayerMovement class, so you will get a NullReferenceException.

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.

"Field BackGroundElement.speed is never assigned to, and will always have its default value 0"

Getting this while trying to make a game on Unity, I pretty much copied this code from a source, yet it's still not working can anyone explain why?
It's underlined green and its speed;
This is also happening on another field labled backgroundElements;
public class BackgroundElement : MonoBehaviour{
[SerializeField]
private float **speed;**
public void Move()
{
transform.Translate(Vector2.left * speed * Time.smoothDeltaTime);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameManager : MonoBehaviour
{
[SerializeField]
private BackgroundElement[] backgroundElements;
void Start()
{
}
void Update()
{
if (true)
{
foreach (BackgroundElement element in backgroundElements)
{
element.Move();
}
}
}
}

How could i fix an error (cs0120) in unity?

In unity, I'm trying to make a press of a button increase the speed of the player. However, each time I run it. It gives me:
Error CS0120: An object reference is required for the non-static
field, method, or property 'PlayerController.speed'
I've already tried changing order of the code, so what could I do?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Upgrader1 : MonoBehaviour
{
void Start()
{
GameObject Player = GameObject.Find("Player");
PlayerController PlayerController = Player.GetComponent<PlayerController>();
}
public void Upgrade1()
{
PlayerController.speed++;
}
}
public class Upgrader1 : MonoBehaviour
{
PlayerController PlayerController; //It should be member variable
void Start()
{
GameObject Player = GameObject.Find("Player");
PlayerController = Player.GetComponent<PlayerController>();
}
public void Upgrade1()
{
PlayerController.speed++;
}
}
it's always a good thing to use proper naming conventions.
PlayerController _PlayerController;
void Start() {
GameObject Player = GameObject.Find("Player");
_PlayerController = Player.GetComponent<PlayerController>();
}
public void UpgradeSpeed() // I changed the name according to its functionality
{
_PlayerController.speed++;
}
With this, you won't put PlayerController class reference again by mistake.

How can I link my C# scripts so that item count influences score in my Unity game?

I am trying to make it so that collecting an item will cause the score to increase. After perusing the documentation for Unity, I have written the following C# scripts. CollectableItem.cs is attached to the items in the game. ScoreBoard.cs is attached to the UI display. I'm getting the error message, "'ScoreBoard.score' is inaccessible due to its protection level." If I make the variables in ScoreBoard.cs public, I get a different error message: "An object reference is required for the non-static field, method, or property 'ScoreBoard.score'."
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CollectibleItem : MonoBehaviour {
[SerializeField] private string itemName;
[SerializeField] private int pointsValue;
void OnTriggerEnter(Collider other) {
Managers.Inventory.AddItem(itemName);
Destroy(this.gameObject);
ScoreBoard.score += pointsValue;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ScoreBoard : MonoBehaviour {
[SerializeField] private Text scoreLabel;
private int score;
void Start () {
score = 0;
}
void Update () {
scoreLabel.text = "Score: " + score.ToString();
}
}
UPDATE: Here is Take 2 on CollectibleItem.cs. Now I'm being informed that "board" does not exist in the current context...
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CollectibleItem : MonoBehaviour {
[SerializeField] private string itemName;
[SerializeField] private int pointsValue;
void Start() {
var uiObject = GameObject.Find("Timer");
ScoreBoard board = uiObject.GetComponent<ScoreBoard>();
}
void OnTriggerEnter(Collider other) {
Managers.Inventory.AddItem(itemName);
Destroy(this.gameObject);
board.score += pointsValue;
}
}
This is not able to work because you make a so-called static access to the ScoreBoard class. That means you try to change the variable of the ScoreBoard class. What you want to do is to change the variable on one of the instances. When the UI Object is created, an instance of the class of your ScoreBoard-Script is created. Like every item has its own instance of CollectibleItem.
You can get the instance in this way:
var uiObject = GameObject.Find("Name of UI Object");
ScoreBoard board = uiObject.GetComponent<ScoreBoard>();
You can do this in Start() and save the ScoreBoard variable in the script where your other private variables reside and use it later in the trigger, or you can do this directly in your Trigger function and directly set the score:
board.score += pointsValue;
EDIT: You have to place the declaration of Scoreboard inside the class:
ScoreBoard board;
void Start ()
...
Or put the code from start to OnTriggerEnter.

Getting Transform of Enum Objects

I am confused about how to get the transform component of Enum objects that are bones of a character.
This is easily done in Mecanim by using the GetBoneTransform method, so I am trying to write a function to do this when I am not using a Mecanim skeleton.
The following is my class:
using UnityEngine;
using System.Collections;
public class GetTransform : MonoBehaviour
{
public enum BradBodyBones
{
JtPelvis = 0,
JtSkullA = 1,
JtSkullB = 2
}
void Start()
{
GetEnumTransform(JtPelvis); // This is the error line.
}
Transform GetEnumTransform(BradBodyBones boneName)
{
Transform tmpTransf;
GameObject enumObject = GameObject.Find(boneName.ToString());
tmpTransf = enumObject.transform;
return tmpTransf;
}
}
I know this is wrong, because JtPelvis in the Start() is highlighted red, so can someone please help me understand how I can do this?
In other words, how can I implement a function similar to GetBoneTransform of Unity's HumanBodyBones enumeration that when I use it in my Start() for example, it gives me the transform of JtPelvis?
Basically, GetEnumTransform(JtPelvis); of my Start() should return the transform component of that bone...
Enum is better to be use in case that your enum list does not have a potential to be changed during the application life cycle. I was using enum, for example, in case of odd/even, dice numbers (1 to 6), week (Sunday to Saturday) and so on.
In your case, I was changing the architecture.
Something like:
public class GetTransform : MonoBehaviour
{
Transform GetEnumTransform(BodyBones bodyBone)
{
return bodyBone.GetBodyBoneTransform();
}
}
class BodyBones
{
protected Transform _transform;
public BodyBones(Transform transform)
{
_transform = transform;
}
public Transform GetBodyBoneTransform()
{
return _transform;
}
}
class JtPelvis : BodyBones
{
public JtPelvis (Transform transform): base(transform)
}
class JtSkull : BodyBones
{
public JtSkull (Transform transform): base(transform)
}
What you want is a dictionary. Using an enum also is safer, as you won't be affected by a small typo. You then have to make the appropriate transforms. For instance, your code could look like this:
public class GetTransform : MonoBehaviour
{
public Transform headBone;
public Transform pelvisBone;
private Dictionary<myBonesBody,Transform> mEnumToBone;
void Start() {
mEnumToBone=new Dictionary<myBonesBody,Transform>();
mEnumToBone.Add(myBodyBone.skull,headBone); //Continue as such.
mEnumToBone[myBodyBone.skull]; //This is how you retrieve the value from the dictionary
}
public Transform GetTransform(myBonesBody part) {
return mEnumToBone[part];
}
}
using UnityEngine;
using System.Collections;
public class GetTransform : MonoBehaviour
{
public enum BradBodyBones
{
JtPelvis = 0,
JtSkullA = 1,
JtSkullB = 2
// more here later ...
}
void Start()
{
// Debug.Log(BradBodyBones.JtSkullA); // JtSkullA which is a string!
// Debug.Log((int)(BradBodyBones.JtSkullA)); // 1 which is an integer!
// GameObject Pelvis = GameObject.Find("JtPelvis");
// Debug.Log(Pelvis.transform.position.x);
Debug.Log(GetEnumTransform(BradBodyBones.JtPelvis).position.x);
Debug.Log(GetEnumTransform(BradBodyBones.JtPelvis).position.y);
Debug.Log(GetEnumTransform(BradBodyBones.JtPelvis).position.z);
}
Transform GetEnumTransform(BradBodyBones boneName)
{
Transform tmpTransf;
GameObject enumObject = GameObject.Find(boneName.ToString()); // GameObject.Find(boneName.ToString()).GetComponentInChildren<BradBodyBones>();
tmpTransf = enumObject.transform;
return tmpTransf;
}
}
Many thanks to ehh + Caramiriel + PearsonArtPhoto for helping me resolve this.

Categories