How to properly make variable Public so it can be accessed by another script? - c#

In Unity I have 2 GameObjects, a sphere and a capsule.
And I have a script attached to each.
Capsule script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CapsuleMesh : MonoBehaviour
{
public Mesh capsuleMesh;
void Awake()
{
capsuleMesh = GetComponent<MeshFilter>().mesh;
Debug.Log(capsuleMesh);
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
Sphere script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeMesh : MonoBehaviour
{
Mesh mesh;
void Awake()
{
mesh = GetComponent<MeshFilter>().mesh;
Debug.Log(mesh);
}
// Start is called before the first frame update
void Start()
{
mesh = capsuleMesh;
}
// Update is called once per frame
void Update()
{
}
}
The mesh = capsuleMesh here is giving me an error about "the name capsuleMesh does not exist in the current context".
I thought that making capsuleMesh public in the other script would make THIS script be able to access it without issue.
What am I doing wrong?

capsuleMesh is a class variable defined in the CapsuleMesh class. It's not a global variable you can use everywhere. You need a reference to the instance of the CapsuleMesh class to retrieve the mesh stored in the capsuleMesh variable.
I've reworked your both scripts to make them work. I've spotted a flaw in your scripts. I guess ChangeMesh is meant to change the mesh of the gameObject? If so, you need to assign a new value to the meshFilter.mesh. Assigning a new reference to the mesh class variable is not enough (it would be pretty long to explain why)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CapsuleMesh : MonoBehaviour
{
public Mesh Mesh
{
get ; private set;
}
void Awake()
{
Mesh = GetComponent<MeshFilter>().mesh;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeMesh : MonoBehaviour
{
// Drag & drop in the inspector the gameObject holding the `CapsuleMesh` component
public CapsuleMesh CapsuleMesh;
private MeshFilter meshFilter;
void Awake()
{
meshFilter = GetComponent<MeshFilter>();
}
void Start()
{
meshFilter.mesh = CapsuleMesh.Mesh;
}
}

Related

OnTriggerEnter in another script

Tell me please. I have a character. The character has a child element - sphere collider. This sphere is a trigger. There is a script that is located on the Terrain. How can I call the OnTriggerEnter function in this script which is located on the character sphere?
Terrain script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InventoryManager : MonoBehaviour
{
public Transform Human;
// Update is called once per frame
void Update()
{
var humanTrigger = Human.Find("Trigger");
humanTrigger OnTriggerEnter(Collider other) {
print(other);
}
}
}

Unity clone won't appear

I'm new to coding and i'm trying to spawn a clone of a ball in unity, but it won't appear.
It does spawn at the spawn point but it doesn't appear.
Here is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour
{
public GameObject ball;
public Transform spawnPoint;
// Start is called before the first frame update
void Start()
{
SpawnBall();
}
// Update is called once per frame
void Update()
{
}
void SpawnBall()
{
Instantiate(ball, spawnPoint.position, Quaternion.identity);
}
}
Edit: it's a 3d game and the mesh renderer is enabled.
Okay nevermind: i just redid the ball and it worked.
¯_(ツ)_/¯

Unity Says There is No Namespace called "Player"

I am trying make an infinite level generator that gets level parts I give to it and mix's them up to make infinite long an unique levels for me. but the problem is that When I Typed [SerializeField] private Player player; it said No namespace called "Player" which is odd because There are other code's were Player player is used and it works.Maybe I am just dumb but anyway here is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LevelGenerator : MonoBehaviour {
private const float PLAYER_DISTANCE_SPAWN_LEVEL_PART = 200f;
[SerializeField] private Transform levelPart_Start;
[SerializeField] private List<Transform> levelPartList;
[SerializeField] private Player player;
private Vector3 lastEndPosition;
private void Awake() {
lastEndPosition = levelPart_Start.Find("EndPosition").position;
int startingSpawnLevelParts = 5;
for (int i = 0; i < startingSpawnLevelParts; i++) {
SpawnLevelPart();
}
}
private void Update() {
if (Vector3.Distance(player.GetPosition(), lastEndPosition) < PLAYER_DISTANCE_SPAWN_LEVEL_PART) {
SpawnLevelPart();
}
}
private void SpawnLevelPart() {
Transform chosenLevelPart = levelPartList[Random.Range(0, levelPartList.Count)];
Transform lastLevelPartTransform = SpawnLevelPart(chosenLevelPart, lastEndPosition);
lastEndPosition = lastLevelPartTransform.Find("EndPosition").position;
}
private Transform SpawnLevelPart(Transform levelPart, Vector3 spawnPosition) {
Transform levelPartTransform = Instantiate(levelPart, spawnPosition, Quaternion.identity);
return levelPartTransform;
}
}
I have tried to make in into a game object but then I got even more errors
No namespace called "Player"
It makes me think that the problem is in the Using.
In some parts of your code it accepts it because you are using it or it is in the same namespace.
Assuming it is called like this, try adding the using as follows
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Player; (it can change but should be like this)

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.

Categories