- Home /
Detect facing normal of trigger mesh?
I am making a top-down puzzle game, similar to the old Chip's Challenge... if anyone played that... I want to implement an ice-floor like in pokemon:
http://www.youtube.com/watch?v=n5A_meuzGpk
I have a problem, I have 360 degree movement, so detecting which direction i have approached the ice from can not be done by simply detecting button input. NOR can it be done by detecting the player's facing direction.
The reason is:
Pretend you are heading North-East, you approach an ice floor.
You COULD step on to the ice from the south, orrrrr you could step on to it from the west. Both could be achieved with a 45 degree facing angle, and pressing UP or RIGHT buttons will not tell us whether the player should slide north or east.
Notice that in Pokemon, the player can only slide in one of four directions, even though when you are not on the ice, you can go in 360.
Character controller and state machine are easy, I am stuck on figuring out which way I should slide.
How does the ice trigger know whether you should be going north or east when you hit the ice?
Neither do we. Do you?
Please, decide and describe desired behavior of you character. Also I would suggest you to think about making your character's controller a state machine and switch states based on which surface character is standing at the moment. If the surface is normal ground - use your 360 degree controlls, if it switches to ice - pick current acceleration, choose direction which one is greatest and slide, slide as long, as you can. :)
ah, I must refine my question.
Also I would suggest you to think about making your character's controller a state machine and switch states based on which surface character is standing at the moment.
That's what I'm doing already, the problem is not that, but the problem is finding out which direction I should slide once I am in the ice state.
The direction with the most acceleration is not necessarily the direction I should hope to slide. A North-East acceleration COULD mean you are approaching from the west, ORRRRRR it could mean you are approaching from the south.
I wouldn't want the character to slide east in this example if I am actually approaching from the south (Like in the pokemon video linked above, I would expect to slide north in this situation).
So, I guess, that's what you want.
If you place triggers on those ice tiles with their trasforms in the middle of tile, you can deter$$anonymous$$e which way to slide this way:
Once player enters trigger, you make a vector starting in players position and ending in center of tile. (trigger.transform.position - player.transform.position)
Then you compare modules of x and y of this vector and choose the greatest one. If the greatest is |x| - ok, you slide horizontally, left if x < 0, right if x > 0. If |y| is greater, slide vertically, y< 0 means down, y > 0 - means up.
Just draw it on a paper and you'll get it.
Edit: Okay I can see how that works now. Cool, thanks!
I also discovered I have a .normal property of the collision mesh I can use:
http://docs.unity3d.com/ScriptReference/ContactPoint-normal.html
Answer by incorrect · Feb 16, 2015 at 03:03 AM
If you place triggers on those ice tiles with their trasforms in the middle of tile, you can determine which way to slide this way:
Once player enters trigger, you make a vector starting in players position and ending in center of tile. (trigger.transform.position - player.transform.position)
Then you compare modules of x and y of this vector and choose the greatest one. If the greatest is |x| - ok, you slide horizontally, left if x < 0, right if x > 0. If |y| is greater, slide vertically, y< 0 means down, y > 0 - means up.
I finally got around to trying this, i got held up by other features. Anyway, this plan works great, one problem i am having is when i print my comparrison upon entering an ice tile:
if (!slide)
{
RaycastHit hit;
if (Physics.Raycast(transform.position, Vector3.down, out hit))
{
if (hit.collider.gameObject.tag == "IceFloor")
{
Debug.Log (hit.collider.gameObject.name);
Vector3 positionCompare = hit.collider.transform.position - transform.position;
if (positionCompare.x >= 0.45f)
{
Debug.Log ("EAST: " + positionCompare);
slideDir = Vector3.right;
}
slide = true;
}
}
}
SO$$anonymous$$ETI$$anonymous$$ES if i hit the tile at JUST the right angle... it will print(0.5, -0.3, -0.5) which is a problem because x0.5 means I should go slide west, while z-0.5 means I should slide north. Any way I can prevent this?
Note: for testing purposes, I am only enabling slide when approaching from EAST.
Answer by oneslyfox · Feb 15, 2015 at 06:09 AM
If you're building your terrain with blocks, you could give those blocks an "Ice" tag. Then, in your player control script, fire a quick raycast down to see if the ground is ice. If it is, and depending on which direction the player moves in, use rigidbody.constraints (http://docs.unity3d.com/ScriptReference/RigidbodyConstraints.html) to lock the movements to specific axis.
Detecting the movement direction can be done relative easily: First, you could compare last-frame and current-frame positions of the player. When she moved, it will result in the last movement direction. If you're using physics to drive the movement of the player, you could just check the velocity of the rigid body, which also will be the last movement direction. Anyways, YOU move the player, so you HAVE to somehow know where the player moved! It's just a matter of re-using the same code which changes the position of the player to figure out the movement direction based on the current (or previous) state of the player.
Your answer
Follow this Question
Related Questions
Velocity for movement 0 Answers
Making a character move automatically in one direction. 2 Answers
counting seconds that character is idle. 1 Answer
Problem getting players position. 0 Answers