6

What i want to do is to detect each side when my character(ThirdPerSonController) touch a cube. In fact my main goal is to detect when my player is standing on the cube surface on top. This is my script:

using UnityEngine; using System.Collections; public class Test : MonoBehaviour { void OnCollisionEnter(Collision collision) { ContactPoint contact = collision.contacts[0]; Vector3 normal = contact.normal; Vector3 inverseNormal = transform.InverseTransformDirection(normal); Vector3 roundNormal = RoundVector3(inverseNormal); ReturnSide(roundNormal); } Vector3 RoundVector3(Vector3 convertThis) { int x = (int)Mathf.Round(convertThis.x); int y = (int)Mathf.Round(convertThis.y); int z = (int)Mathf.Round(convertThis.z); Vector3 returnVector = new Vector3(x, y, z); return returnVector; } void ReturnSide(Vector3 side) { string output = null; switch (side) { case Vector3.down: output = "Down"; break; case Vector3.up: output = "Up"; break; case Vector3.back: output = "Back"; break; case Vector3.forward: output = "Front"; break; case Vector3.left: output = "Left"; break; case Vector3.right: output = "Right"; break; } Debug.Log(output + " was hit."); } // Use this for initialization void Start () { } // Update is called once per frame void Update () { } } 

I'm getting error on the line:

switch (side) 

Severity Code Description Project File Line Suppression State Error CS0151 A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type test.cs 33 Active

1
  • 3
    The simple answer is no, forget about this. The way you do this is very simply have a trigger or collider, ON EACH FACE. It's an absolute basic of making video games. Enjoy. Commented Nov 9, 2016 at 1:37

4 Answers 4

4

With C# 7, you can do this. You case use the when statement:

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/switch#the-case-statement-and-the-when-clause

So, for example, if you wanted to know which side of a cube is clicked, you can use something like this:

void OnMouseDown() { RaycastHit hit; Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hit, Mathf.Infinity)) { switch (hit.normal) { case Vector3 v when v.Equals(Vector3.up): Debug.Log("Up"); break; case Vector3 v when v.Equals(Vector3.left): Debug.Log("Left"); break; case Vector3 v when v.Equals(Vector3.back): Debug.Log("Back"); break; } } } 

I'm not sure about the efficiency of this method. YMMV.

Sign up to request clarification or add additional context in comments.

Comments

2

For people looking for an answer now:

You can't create a switch statement using Vector3 like the others have mentioned because there's no way to represent a Vector3 as a constant

However, you can convert the Vector3 into a type which can be constant and match against that. An easy way to do that is with a tuple:

public void MatchVector3(Vector3 vec) { switch ((vec.x, vec.y, vec.z)) { case (0,1,0): { Debug.Log("up"); break; } case (0,-1,0): { Debug.Log("down"); break; } case (-1,0,0): { Debug.Log("left"); break; } case (1,0,0): { Debug.Log("right"); break; } case (0,0,1): { Debug.Log("forward"); break; } case (0,0,-1): { Debug.Log("back"); break; } } } 

Though for this specific usecase of finding out if the player is standing on top of a box, you're definitely better off just using a separate collider, it's far easier to tweak

Comments

1

No, there is no way to make a switch/case using Vector3.

"A switch expression or case label must be a bool, char, string, integral, enum or corresponding nullable type."

Comments

0

No you cant use switch/case on vector3, but what you can do (what is not the best solution, but will do the job) is convert vector3d.x ,z and y and run them over switch case. Tho I dont think it will look good.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.