I have a myCentralObject being a sort of super static for all kinds of game states
public class myCentralObject : MonoBehaviour {
public enum GravityDirection_is { down, left, up, right };
public static GravityDirection_is Global_Gravity = GravityDirection_is.down;
}
I can access this as I like, throughout the project, directly.
But now I’d like to abstract a little, and place a value picker for this enum into a bunch of objects to change in the Unity Editor, and then use switch/cases inside these same objects to check if their value is the current state of this enum
I thought this would be something like:
public class MadeContact : MonoBehaviour {
public myCentralObject.GravityDirection_is thisWayUp;
private void OnCollisionEnter2D(Collision2D other) {
switch (myCentralObject.Global_Gravity) {
case thisWayUp:
// doStuff in here
break;
But this causes this error, at thisWayUp:
“A constant value is expected…”
Perhaps my designer brain is wrongheaded here… I thought thisWayUp was an constant
switch (myCentralObject.Global_Gravity)
{
case myCentralObject.GravityDirection_is.up:
// doStuff in here
break;
}
BTW I switched variables of enums PLENTY of times. Otherwise there would be no much use in them. But on the other hand the last thing I would do is to say lordofduct is wrong ;).
This doesn’t pass the value of the object from the editor into the case.
I’m trying to get the object’s set gravity choice from the editor, and use it within the script, so the objects are modular, and can be set throughout the scene with the same script, but different influences on gravity.
All with one script that exploits the exposure of the enum’s fields within the editor, on the objects.
Why is your enum encapsulated in myCentralObject? When its supposed to be used in many classes it could also be free (outside a class).
When you want to compare the value of a variable against another you should use an == operator, not a switch. A switch is for executing different code paths for many/all distinct values of an enum. So to me its not really clear what you want to achieve. Shall only those objects “react” to gravity which have the same value as myCentralObject.Global_Gravity? If all objects shall react to their set direction why do you need to compare it to myCentralObject.Global_Gravity?
So I’m a little bit confused on what you want to achieve and what the actual problem is.
Are ABC + XYZ of the same type? For what criteria do you want to set values “globally” over the scene? Or shall every object be set manually?
Maybe its better to explain what you want to achieve in general or with an example.
Because I’m a designer, and OOP boggles me. I tried, initially, to create the enum above the class definition, and then access it. But couldn’t. Can’t figure out what I’m supposed to do to have access to it, or stop all the errors Unity throws at me when I try to make the enum outside a class.
Imagined a four walled box, in a 2D world. Inside the box is a ball. When the ball hits any of the walls, that wall becomes “down”, up goes the other way.
Each wall has a script, the same script, that identifies that it’s been hit by the ball. The switch needs to know which direction this wall considers to be UP (and down) so that it can request gravity be changed to these directions.
In order to have walls know which way they face, I have exposed the enum in the editor, by making it public. So I can move the walls around in the editor, duplicate as many of them as I like, and set their gravity change enum setting in the editor.
In the script attached to the walls, the enum setting is known.
How do I pass that enum value into a Switch?
The problem is NOT this example. It’s me trying to understand how I can expose an enum in the editor and then use the edited values within a single script on many different instances, each with only four possible enum settings, up, down, left or right.
I know this can be done with an If/else setup.
I’m trying to understand how to use enums in C# and Unity.
I hope this isn’t a futile effort to understand enums and their usage in Unity. Feel free to admonish me if it is.
Do all other walls change their direction or only the touched one?
Do you mean the direction of each wall instance or the static one? When each wall has another direction what do you need the static direction for? Is this the currently active direction from the last touched wall?
I have posted the method above. If its not the right variable just put another there. Here is an example from my Hexagon code which works also with directions:
public HexPositionClass GetRelativeHexPosition (HexDirection dir, int range, HexPositionClass actposition)
{// returns the hexposition (indizes in all 3 hexdirections (NOT worldaxis!)) of the hexagon in range-distance in dir-direction
int dx = actposition.X, dy = actposition.Y, dz = actposition.Z;
switch (dir) {
case HexDirection.Up:
dy = actposition.Y + range;
dz = actposition.Z - range;
break;
case HexDirection.Upright:
dx = actposition.X + range;
dz = actposition.Z - range;
break;
case HexDirection.Downright:
dx = actposition.X + range;
dy = actposition.Y - range;
break;
case HexDirection.Down:
dy = actposition.Y - range;
dz = actposition.Z + range;
break;
case HexDirection.Downleft:
dx = actposition.X - range;
dz = actposition.Z + range;
break;
case HexDirection.Upleft:
dx = actposition.X - range;
dy = actposition.Y + range;
break;
default:
Debug.Log ("Invalid Enum Value");
break;
}
return new HexPositionClass (dx, dy, dz);
}
So you define a variable of your enum. Put it in the switch and test against the cases you desire. In the first examle you posted only “case thisWayUp:” is false from what I can see here. There you put the values you want to test against (up down etc.).
I think an effort to learn is never futile. But enums are pretty straightfoward and “easy to use” from my POV. So I still can’t see your problem. Look in the Signature of lordofduct and read the last sentence. Maybe your problem is more a conceptual one than a syntactical one?
//untested
public class Wall : MonoBehaviour {
public myCentralObject.GravityDirection_is thisWayUp; // this is your per instance variable, can be edited in inspector
private void OnCollisionEnter2D(Collision2D other) {
switch (thisWayUp) { // here you switch it
case myCentralObject.GravityDirection_is.up: // here you test the possible values the enum can represent
// doStuff in here
break;
The walls don’t change. A wall being hit by the ball changes world gravity to its orientation.
I’m wanting to set the orientation of the walls in the editor, by way of giving them one of the enum’s settings of up, down, left, or right; arbitrarily.
Having done that, a script attached to each wall is (I’d hope) able to be aware of the orientation of the wall via this enum’s setting, coming from the editor.
When a ball hits a wall, within the wall’s attached script, OnCollisionEnter2D is called.
At this point, I’d like the Switch within the script on the wall to utilise the value set (describing its orientation) via the enum, so it can make a decision based on only two possible cases:
Case 1: Gravity is already in this orientation, so do nothing
Case 2: Gravity is in another orientation, so change accordingly
In the example of Case 1 and this “problem”, this requires the passing in of the setting from the editor, into the Case. Is this possible? If so, how?
Yes, I know this can be done by calculations, manually, or via other forms of conditionals, etc.
by way of example of how this problem might be solved in Swift:
let myConstant = currentState // myConstant is a constant of the value stored in currentState
The above is now a hardwired constant.
In fact, I think you could just do it like this:
This might be thought of as getting the value of the enum’s “variable” state for this object and storing it as a constant for this instance, within the editor, to the Script, via the above line.
C# seems to be much more stringent about what constitutes an acceptable setting source for a constant. Literals or nothing, it seems.
It seems difficult to take the values set in the editor, on objects in the editor, into a case for a Switch, directly.
Then you need no enum, a simple assignment is enough.
myCentralObject.Global_Gravity = thisWayUp;
You can also assign the value of the wall to global gravity direction when it is already at this value. The enum is only required when you want to do specific stuff for each direction.
Sorry but I’m close to giving up. I can’t rule out that I’m just too dumb to understand your problem. Please put the following code into a .cs file, attach it to a game object, set a direction in the inspector, hit play and press space. And then tell me what is not working as you expect/require it.
using UnityEngine;
public sealed class Wall : MonoBehaviour
{
public Direction walldir;
private void Update()
{
if( Input.GetKeyDown( KeyCode.Space ) )
{
switch( walldir )
{
case Direction.up:
Debug.Log("up");
break;
case Direction.down:
Debug.Log( "down" );
break;
case Direction.left:
Debug.Log( "left" );
break;
case Direction.right:
Debug.Log( "right" );
break;
}
}
}
}
public enum Direction
{
up, down, left, right
}
Note: I have exchanged OnCollisionEnter with Update to simply test it with a key press. Where you put the switch does not matter as long ats in the scope of the enum variable.
Sorry I didn’t kept reading after the question got violated. But for the original question
if(myEnum == myCentralObject.Global_Gravity)
{
// myEnum is equal to Global_Gravity
}
else switch(myEnum)
{
case GravityDirection_is.up:
//myEnum is Up
break;
//.........
}
I think the problem is the OP didn’t realize directionEnum.Up is a constant. It looks like a variable, so replacing it with an actual variable looks legal.
BUT…
C++ used to evaluate switch conditions on the fly. It wasn’t legal, but GCC did it. You’d see crazy stuff like “switch a>5:”. I think because of that plenty of people assumed switch conditions didn’t need to be constants, even for C# at first.
No. But switch statements are dumb anyway. Use an IF.
You could do stuff you’re asking about in an older language that C# was based on. It was funny since the rules said you couldn’t, but it still worked. You can’t use that language in Unity.