Reputation: 13
I'm trying to learn C#, but I'm having some problems with creating a variable across classes in Unity.
Node Class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Node {
public Vector3 dimensions;
public int jointType;
public Vector2 jointLimit;
public int recursiveLimit;
public int nodeId;
public List<int> to;
public int fro;
public Node (Vector3 dim, int jointT, Vector2 jointL, int recLim, int id){
dimensions = dim;
jointType = jointT;
jointLimit = jointL;
recursiveLimit = recLim;
nodeId = id;
}
}
Connection Class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Connection {
public Vector3 position;
public Vector3 orientation;
public float scale;
public int reflection;
public bool terminalOnly;
public int[] to;
public int fro;
public Connection (Vector3 pos, Vector3 orien, float scl, int refl, bool term, int[] to, int fro){
position = pos;
orientation = orien;
scale = scl;
reflection = refl;
terminalOnly = term;
this.to = to;
this.fro = fro;
}
}
I'm trying to have a Node variable and a Connection variable that are both accessible by the GenoManager class and the BodyPart class (which there will be many of).
BodyPart class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BodyPart : MonoBehaviour {
public BodyPart block;
public bool finished;
//Initialization
void Start () {
finished = false;
}
//Generation of all blocks [incomplete]
void Update () {
while (!finished) {
BodyPart newPart = Instantiate (block, transform.position + Vector3(0,10,0), transform.rotation) as BodyPart;
newPart.transform.localScale = p.nodes[0].dimensions; //This line also has the error CS0119
//This line has the error CS0176
//Trying to Scale by the dimensions (a Vector3) of the
first Node in the nodes array
finished = true;
}
}
}
GenoManager Class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class GenoManager : MonoBehaviour {
public BodyPart block;
public Transform pos;
// Update is called once per frame
void Update () {
}
public static List<Node> nodes = new List<Node> ();
Node t = new Node (new Vector3(1,4,1), 1, Vector2.up, 2, 0);
static int[] testList = { 1, 2 };
public static Connection te = new Connection (Vector3.up, Vector3.up, 1.5f, 1, false, testList,0);
void Start(){
//Node Test Generation
nodes.Add(t);
print (nodes [0]);
//Root Block Generation
BodyPart newPart = Instantiate (block, pos.position, pos.rotation) as BodyPart;
newPart.transform.localScale = nodes[0].dimensions;
}
}
Basically what I'm asking is, how would I go about making a variable that can be created in one class and viewed by other classes? (Also, sorry if the formatting is off, this is my first time posting on StackOverflow.)
Thanks in advance.
Upvotes: 1
Views: 3246
Reputation: 54638
Variable that can be ... viewed by other classes?
In C# variables are really defined within a class. You don't pass them around. You can pass around a Class or a Struct that have public properties (don't use public fields) that hold values.
how would I go about making a variable that can be created in one class and viewed by other classes?
Ideally you want to use Dependency inversion principle. That is to say that if class A requires access to a value (dependency) for it to function at any point in time, you should pass it as part of the constructor. Ideally, you would construct class B (the dependency) which would implement an interface that gives only the necessary properties/methods/access needed for other classes (class A). For example:
static Main()
{
var person = new Person { Age = 21 };
var bartender = new Bartender(person);
if (bartender.CanServeAlcohol())
{
}
}
public interface ICustomer
{
int Age { get; }
// Ideally this should be a DateTime with a function
// that returns the age, so this is really just an example
}
public class Customer : ICustomer
{
public int Age { get; set; }
}
public class Bartender
{
public ICustomer _customer;
public Bartender(ICustomer customer)
{
_customer = customer;
}
public bool CanServeAlcohol()
{
return _customer.Age >= 21;
}
}
In this example, the Customer
is created, but only what is needed via the Interface is available. The Bartender now has access to the Customer
but doesn't have access to change the Age
. Since Bartender
requires a customer to be created, you can't accidentally not include a Customer
when creating one.
Once you understand this principle, I highly recommend looking into Dependency Injection Frameworks which can do these things for you automatically. Popular frameworks I am familiar with are Autofac, Unity, Ninject, StructureMap.. etc. There are many other and they all pretty much do the same thing.
(realize this isn't the best example, because a real bartender can serve more than one person, but it works for your example)
I HIGHLY RECOMMEND you don't use Static Fields. There are many many issues with them (threading can be a serious issue, they tend to become god objects and make it harder to implement extensionibility).
Upvotes: 1
Reputation: 43
You'd use a public static
variable
https://unity3d.com/learn/tutorials/topics/scripting/statics
using System;
public class ContainsStaticVariable
{
public static string ExampleStaticVariable = "I am the value of a static variable";
}
public class DisplayContentsOfStaticVariable
{
public static void Main()
{
Console.WriteLine(ContainsStaticVariable.ExampleStaticVariable);
Console.WriteLine("Press return to exit...");
Console.ReadLine();
}
}
If you don't want the value to be changed at runtime, you can use public const
Upvotes: 0