- Home /
Rotating cube (World) when player reaches edge.
Hello everyone.
I am writing a script to auto-rotate a cube (the world in this game) so that when the player reaches the edge of the cube the cube rotates 90 degrees to display the next face of the cube. I have managed to do all this using 2 triggers per edge of the cube, so each face has 4 triggers. These triggers just rotate the cube by 90 degrees to position the next face, they also change the players transform.position to align with the edge of the new face, it also offsets the player upwards so he doesn't get flung into space when the cube rotates.
I Have included most of the code, all that is missing is the reaming RotateFace() functions. As they are just the same as the one included.
But basically I am just using an if statement to check for a collision by name and assign a "cameFrom" int, and then calling a particular face function (e.g FaceFive), which is a simple switch system using the "CameFrom" int.
And this works just fine for a bit, if you follow strict patterns. As when you go from face 1 to face 3 it works, but if you got to from face 1 to 3 after visiting face 5, then it doesn't work. It would seem the cube is remembering where it has been as so after a few turns the original rotation date I feed it no longer does what I want.
I thought I could get around this with the "cameFrom" int which will rotate according to the face the player came from. But this doesn't seem to work. I tried adding that useless Vecter3 at the top there to zero out the rotation on the collision event. But that doesn't help. I was up until 4 trying to get this working. Any ideas anyone? Any suggestions would be greatly appreciated.
using UnityEngine;
using System.Collections;
public class PlanetController : MonoBehaviour {
private GameObject Slab; // This is the player
private GameObject World;// This is the planet or world our player is on. All "Trigger" objects should be a child to the world object
private int cameFrom;
private Vector3 originalPos = new Vector3 (0f,0f,0f);
// Use this for initialization
void Start ()
{
Slab = GameObject.Find("Slab"); // Find and assign the player object
World = GameObject.Find("World");// Find and assign the world object
}
// Update is called once per frame
void Update ()
{
}
void OnTriggerEnter(Collider collider)
{
gameObject.transform.Rotate(originalPos);
if(collider.gameObject.name == ("Slab"))
{
if(gameObject.name == ("TriggerBlock01"))
{
cameFrom = 0;
RotateFaceFive();
}
if(gameObject.name == ("TriggerBlock02"))
{
cameFrom = 2;//
RotateFaceOne();
}
if(gameObject.name == ("TriggerBlock03"))
{
cameFrom = 0;//
RotateFaceSix();
}
if(gameObject.name == ("TriggerBlock04"))
{
cameFrom = 3;//
RotateFaceOne();
}
if(gameObject.name == ("TriggerBlock05"))
{
cameFrom = 3;//
RotateFaceThree();
}
if(gameObject.name == ("TriggerBlock06"))
{
cameFrom = 1;//
RotateFaceSix();
}
if(gameObject.name == ("TriggerBlock07"))
{
cameFrom = 2;
RotateFaceFive();
}
if(gameObject.name == ("TriggerBlock08"))
{
cameFrom = 2;//
RotateFaceThree();
}
if(gameObject.name == ("TriggerBlock09"))
{
cameFrom = 0; //
RotateFaceTwo();
}
if(gameObject.name == ("TriggerBlock10"))
{
cameFrom = 0;//
RotateFaceFour();
}
if(gameObject.name == ("TriggerBlock11"))
{
cameFrom = 0;//
RotateFaceThree();
}
if(gameObject.name == ("TriggerBlock12"))
{
cameFrom = 1;//
RotateFaceThree();
}
if(gameObject.name == ("TriggerBlock13"))
{
cameFrom = 1;//
RotateFaceFour();
}
if(gameObject.name == ("TriggerBlock14"))
{
cameFrom = 1;//
RotateFaceTwo();
}
if(gameObject.name == ("TriggerBlock15"))
{
cameFrom = 1;//
RotateFaceOne();
}
if(gameObject.name == ("TriggerBlock16"))
{
cameFrom = 0;//
RotateFaceOne();
}
}
}
public void RotateFaceOne()
{
switch(cameFrom)
{
case 0: //coming from face 1 to face 0
World.gameObject.transform.Rotate (90,0,0);
Slab.gameObject.transform.position = new Vector3(transform.position.x,transform.position.y + 1,transform.position.z - 1);
break;
case 1://coming from face 3 to face 0
World.gameObject.transform.Rotate (-90,0,0);
Slab.gameObject.transform.position = new Vector3(transform.position.x,transform.position.y + 1,transform.position.z + 1);
break;
case 2://coming from face 4 to face 0
World.gameObject.transform.Rotate (0,0,90);
Slab.gameObject.transform.position = new Vector3(transform.position.x + 1,transform.position.y + 1,transform.position.z);
break;
case 3://coming from face 5 to face 0
World.gameObject.transform.Rotate (0,0,-90);
Slab.gameObject.transform.position = new Vector3(transform.position.x - 1,transform.position.y + 1,transform.position.z);
break;
}
}
}
Ok, so a cheeky bump as I am still quite stuck on this one.
I have been reading some threads where people have done this sort of thing with sphere worlds, and that was done with ray casts. I just want to make this simple mechanism work, as i feel it would get too complicated using ray casts, especially with more complicated cube worlds, with stacked cubes and so on. I think the trigger event might be the best solution. But any and all ideas on how to get this to work would be a great help.
Thanks a million.
Ok. I have been doing some tests with Raycasting, as this seems like it might be a simpler solutions, and might shed a 100 lines or so of redundant code. :)
So, I have the ray emitted from the character at a fixed distance (15 units in this case) and when it hits a particular collider in the environment it will tell the cube to rotate. But I am still having the same issues with the rotation data building up in the transform of the cube object (world). So, if you follow some strict patterns, the rotation works fine. But if you walk around randomly the cube begins to rotate counter to where it should be rotating.
Any help on how I might be able to fix this issue would be very helpful.
Thanks.
And thanks to the $$anonymous$$ods for putting up with me posting things in the wrong area, most appreciated!
Without having the project to play with to see the issue, I'm just guessing at an answer. But I wonder if you wouldn't have better luck with an angle axis rotation (RotateAround()). As I walk from face to face, the vector that forms the axis is well defined and easy to calculate in local space.
Not a solution, but a suggestion: you should abstract your triggers so you can hold info with them. I.e. a little script that contains what face it is on and what the rotate too should be. That way you don't need these hardcoded if statements. You simply check the public variable of what face it's on and the expect one to go to in the trigger object and user that for your rotate logic (possibly including roberbu's suggestion as well).
A simple test project/scene would be helpful as well. Just a cube, something to represent the character, your colliders and the code you have.
Your answer
Follow this Question
Related Questions
Detecting multiple gameobjects 1 Answer
How to make a particle system play on trigger with another box collider 1 Answer
Detect trigger touching another trigger? 1 Answer
Child Object's collider setting off triggers 1 Answer
Can i Move/Rotate triggers without Rigidbodies? And other collider questions. 3 Answers