# 2D character controller in unity (trying to get old-school platformers back)

This days I'm trying to create a 2D character controller with unity (using phisics). I'm fairly new to physic engines and it is really hard to get the control feel I'm looking for. I would be really happy if anyone could suggest solution for a problem I'm finding:

This is my FixedUpdate right now:

public void FixedUpdate()
{
Vector3 v=new Vector3(0,-10000*Time.fixedDeltaTime,0);

v.y=0;
if(state(MovementState.Left))
{
v.x=-_walkSpeed*Time.fixedDeltaTime+v.x;
if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=-_maxWalkSpeed;
}
else if(state(MovementState.Right))
{
v.x= _walkSpeed*Time.fixedDeltaTime+v.x;
if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=_maxWalkSpeed;
}

_body.velocity=v;

Debug.Log("Velocity: "+_body.velocity);
}


I'm trying here to just move the rigid body applying a gravity and a linear force for left and right. I have setup a physic material that makes no bouncing and 0 friction when moving and 1 friction with stand still. The main problem is that I have colliders with slopes and the velocity changes from going up (slower) , going down the slope (faster) and walk on a straight collider (normal). How could this be fixed? As you see I'm applying allways same velocity for x axis.

For the player I have it setup with a sphere at feet position that is the rigidbody I'm applying forces to.

Any other tip that could make my life easier with this are welcomed :).

P.D. While coming home I have noticed I could solve this applying a constant force parallel to the surface the player is walking, but don't know if it is best method.

• Old school platformers used hand tuned "cartoon physics" for jumping mechanics and direct speed control (ie. no physics at all) for walking movement. If you can rewrite the character controller, do so, because it's going to be difficult to poke and prod a squishy physics simulation into the crisp movements that old school games had. Jun 15 '12 at 10:08
• The problem of writting a custom one is that collision detection is lost. And it is not easy to rebuild it without using raycast (depending on the environment, etc... it could be a bunch of them). How do you handle this situations? Jun 15 '12 at 11:56
• You can have colliders on things that are still custom animated- when you use kinematic rigidbodies. I'd warrant that in most situations you don't really want real-world physics / forces etc for this sort of application. If you're looking for a more technical angle, perhaps research Human IK Aug 1 '12 at 13:26
• Def ditch physics in this situation. Mar 25 '14 at 7:00

If you are looking to mimic old school platformers step one is to ditch physics altogether. You will end up fighting the physics system to get the decidedly non-realistic motion of an old school platformer. Have a look at this CharacterController replacement that ditches physics altogether to get a good idea of one way to implement it.

You'd probably be happier going with what mheona recommended. But if you're going to use Unity's physics, then you probably want to use ForceMode.VelocityChange.

Example:

public void FixedUpdate()
{
var v = Vector3.zero;
if(state(MovementState.Left))
{
v.x=-_walkSpeed*Time.fixedDeltaTime+v.x;
if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=-_maxWalkSpeed;
}
else if(state(MovementState.Right))
{
v.x= _walkSpeed*Time.fixedDeltaTime+v.x;
if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=_maxWalkSpeed;
}

Debug.Log("Velocity: "+_body.velocity);
}


You should also apply global gravity in your project's Physics settings, and for objects that you want to fall faster, add a Constant Force component.

ForceMode.Impulse is similar but is affected by the rigidbody's mass. Makes it harder to tune.

Even if you dislike the built in Character Controller component(as I do), take a look at the Unity's example code for the 2D Gameplay Tutorial.

The code implements a complete 2D gameplay with moving platforms, enemies and boxes with collision, using the Character Controller.

But if you dont even want to take a look, I suggest you to minimize the use of physics and try to copy its behaviour with your own code. Depending on what kind of 2D game you are planning it may work pretty good. For instance, instead of applying force to Rigidbody.velocity to move your character you could mess directly with Transform.Translate(), which moves the object Transform.position based on its axis. You could determine the forward and back related to the object itself or maybe the platform or floor Transform.up, so you will know if its a ramp and kind of know its angle.

Also if you create some sort of speed control atributte(e.g. how long the key is pressed) you can apply it together with your direction while translating to prevent your character walking something too much inclined without some speed, much like they did on Sonic the Hedgehog for Genesis/Mega Drive.

If you choose to keep using physics I can't help you at all because I'm not so good at it, but be aware that it's a normal behaviour to go 'up a slope' slower as the body needs more force to keep up, like real life.

• The first thing I read when I got into unity was that tutorial. The problem is that the control feel is pretty bad. This is why I wanted to find my own solution. On the other hand when you commen about using the Transform.Translate() it is not that easy to do slopes and other things. You must ray cast several times (2 or 3 for the floor, more for the direction your are moving depending on the hero size). For mobile devices raycast is not good, and less if yo ahve to do 5..n per collision detection iteration. Perhaps I could be wrong, but I don't think so. Sep 21 '12 at 6:24

What you want it the built in Character Controller. By setting the step offset property on this component you can get a player to move up and down slopes with ease.

• Sorry for not commenting I knw there's a Character Controller in unity and that I have used it several times, but I don't like how it behaves. It is more suited for just FPS not a platform game where motion mechanics are one of the most importnat things. Jan 17 '12 at 8:06
• I think once you fiddle with the settings on the Character Controller it works well. What did you find lacking? Jan 17 '12 at 17:27
• First thing I don't like is that it is slow relative to usual rigid bodies with some ray cast. Knowing how to achieve it, I think I could do a more lightweight controller. Another problem is that being a capsule/sphere odd behaviour at platform edges (it can be solved with some more ray casts). This is why I want to roll my own. Jan 17 '12 at 18:31

I suppose it is because the force is not parallel to the platform and the result ends up being lower in rise and higher in descent.

If you apply a relative force to the coordinate system

AddRelativeForce


You want to keep a maximum speed in "x" and compare it against a scalar, remember that speed is a vector and compose v.x and v.y, in flat terrain v.y is zero, but necessarily on slopes is greater than zero.

The velocity changes according to the direction of the body, and its relative v.x changes with respect to its overall v.x.

This can modify your V in a way you do not want too:

if (Mathf.Abs (v.x)> _ maxWalkSpeed) v.x = _maxWalkSpeed;


maintaining the same global V.x may seem strange to the eye. (Unwanted Accelerations)