- Home /
2D sprite with rigidbody - movement stalling in 3D environment
As a learning experience, I'm trying to put together something that looks like Legend of Dungeon, which is a 3d isometric (I've read some the developers blog posts so know it is) world with 2d sprites.
I've given my empty player object a sprite renderer and changed the material to sprite-diffuse for dynamic lighting. I'm moving the player with transform.translate. I've got some coloured lights in there and it looks and works smoothly. Apart from I have no collision control yet.
So... I add a 3d collider (which I've read elsewhere is the way to do it), but it's not actually colliding with my 3d scenery (which at present are just cubes with box colliders) it just passes through them .
So I realise at this point that my player also needs a rigidbody, right? So I do that and change my code to use:
rBody.velocity = new Vector3(horizontal * speed,0,0);
in FixedUpdate(). Where horizontal is GetAxis or GetAxisRaw. All as per the Unity docs.
Problem: it moves as before but randomly freezes the motion, as if the player has become stuck. it only gets moving again with random wiggling of the horizontal axis. I've tried several times removing and recreating the problem and it happens every time. There aren't any other factors or assets in there to affect project.
What am I doing wrong??? Alternatively, how should I be handling movement and collisions in this scenario?
Ok, so after more trial and error (and a lot of coffee)..
By replacing the individual box colliders on the cubes that make up the floor, with just one big 'floor' collider the problem goes away. But, when I put two of these new floor pieces together, the player sometimes gets stuck passing over the two, but only then.
Is this expected? Is it a bug? Any opinion on this would be gratefully received.
Answer by orchard800 · Dec 06, 2015 at 03:33 PM
Here's the official answer from Unity.
I logged it as bug and after looking into it, this is the reply I received. I thought I would post here as I have read many posts about users having similar issues, but they never seem to find an answer. Here's why:
It is not designed in any way to be like this, but there is no good way to fix it besides changing world geometry. In fact, this is a long standing issue. Quote from what one of our developers said:
"Putting colliders side-by-side may visually seem as if they're continuous from the gizmo rendering POV but from a numerical perspective, it isn't a continuous surface. This causes the colliders to catch. Sliding a collider over this surface (such as a Box) would cause the collider to catch on an edge. This is a well know problem and isn't a bug, it's just the way the solver works."
You could also check this site, even though it is covering from a 2D standpoint, the main idea stays the same.
Answer by Aggrojag · Nov 29, 2015 at 04:33 AM
I personally would use 2D colliders for a legend of dungeon type of game, as this is what I'm comfortable with. When in 2D you should still use velocity (via the rigidbody2D component). The reason for using velocity rather than translation is translation doesn't work as closely with the physics that Unity has created.
As far as possible problems, I'd imagine your Z axis could be off, possibly the collider isn't set up properly, or maybe even the collider itself is rotating. Without knowing a fair bit about what you're doing, it's really hard to say. Perhaps showing how your scene is set-up along with full movement code would result in a better answer.
PS: You say random wiggling, so I'm thinking this is a rotation issue. Lock rotation on the axis causing you trouble and see if that works. If not, repost with more information please.
Hi @PianoHandsThePerson and thanks for the quick answer.
Ok, this may be a dumb question, but in Legend of Dungeon, the player can move in 3 dimensions (up/down, left/right and up and down the stairs), so would a 2d collider and rigidbody allow me to do that? ie wouldn't that allow the player to walk through the back wall and off the platform?
$$anonymous$$y scene is simply a 4x6 row of cubes(vert collision). Sat on top of that is my player and a single cube (to test horiz coll.). He falls in to place with gravity, to make sure he's sat on top of the floor.
$$anonymous$$y code:
using UnityEngine;
using System.Collections;
public class Player$$anonymous$$ovement : $$anonymous$$onoBehaviour
{
public float speed = 5f;
Rigidbody rBody;
float horizontal;
float vertical;
void Start ()
{
rBody = GetComponent<Rigidbody>();
}
void Update ()
{
horizontal = Input.GetAxis("Horizontal");
}
void FixedUpdate()
{
rBody.velocity = new Vector3(horizontal * speed,0,0);
}
}
I can move the player around for a few seconds in any sequence of left and right movement. Interestingly, since I cleaned up this code to paste here, I removed the vertical axis movement and its now impossible to get it going again once it freezes and you have to stop the game. It's as if Unity is freezing but thats not the case and my PC's resources only calm down once it freezes, so it's not like its trying to compute some heavy maths or anything.
The player's rigidbody is already set up with constrained rotation on all axes, but I like that line of inquiry...
I will try the 2d collider in the meantime. but if you could elaborate that would be great! Thanks!
Update: I have added a 2d collider and 2d rigidbody but now he just falls straight through the floor.
2D colliders only act on other 2D colliders. EDIT: A$$anonymous$$A, make sure your ground is using a 2d Collider
As far as how that would work on a 2D plain, your "up and down" would be a change in the Y Axis, then you would just unrestrain that upon using a ladder. You would want to be removing "use gravity" as well from the rigidbody(2d), allowing for change in Y velocity, and restraining the yPosition (and zeroing out YVelocity once reaching this position).
If you're using a 2D rigidbody, it changes the call to rBody = GetComponent(); - $$anonymous$$ake sure you're not getting an error.
Beyond that, I see no error in the code that would cause this.
Showing how the scene is set up, including both the player and the ground object would help immensely.
Wouldn't using 2d colliders stop characters passing each other on the x axis even if they had different z values. ie if one tried to pass behind the other, they would collide, right?
Here are some pics of the scene with relevant details presented in the inspector:
Ok, so going back to the original problem: Through further testing I have found that un-freezing rotation on the z axis (although the character does roll) OR turning off gravity on the rigidbody, completely stops the stalling problem stops, leading me to agree that it's something to do with it trying to rotate or somehow getting stuck on the floor.
But how to solve this?
You're right about the z axis not mattering, and it stopping things. In this type of game, your Y Axis would function as your z axis. It may not be as effective as a 3D environment, but that's the approach I personally would start out with.
As far as possible problems, try creating a new box, make it rather large, and test on that. $$anonymous$$y feeling is that all the small boxes either have gaps, or are offset.