- Home /
Acceleration and Inertia in Top-Down 2D Game (C#)
Hey everybody!
I'm working on a prototype of a player controller that's more or less a guy on a bicycle. The game is built in 3D but is for all intents and purposes a top-down 2D driving game. I'm representing the player with a sprite with a box collider
My requirements for the bike are simple, but are proving difficult for me to implement 'cause I'm neither the best physics guy nor the best coder. I'd like help figuring out how to get rolling with these bullet points:
8-Directional (or even analog) Movement
Acceleration and building momentum while a directional button is being held down (When the biker is pedalling)
A maximum speed at which the bike "tops out" and ceases to accelerate
Deceleration/drag and eventual stop while no directional buttons are being held down (when the biker stops pedalling)
I've got something that kinda works here:
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
// Exposed to Editor for Easy manipulation
public float moveSpeed; // player's base movement speed
// START - Use this for initialization
void Start ()
{
// Nothing yet!
}
// UPDATE is called once per frame
void Update ()
{
// Kinda Works:
rigidbody.AddForce((Input.GetAxis("Horizontal")), 0,(Input.GetAxis("Vertical")),ForceMode.VelocityChange);
}
}
This gives me a bit of acceleration and resistance, which is nice. However, there are some problems with this code:
No control over rate of acceleration (I need this exposed to the editor so I can easily tweak it)
Almost immediate stop (no decelerating drift when fingers are off the keys -- also ideally exposed to editor)
Using two keys (say Up and Left) at once gives me double speed when moving diagonally.
And I've tried modifying this, replacing it, and jury-rigging it with no real success. I've also tried toying with Unity's built-in stuff for acceleration, but it's eluding me.
Can anyone explain how to get this working? My most strenuous requirement here is that I need to understand what I'm doing pretty well so I can modify it moving forward with the project.
Answer by cpm32 · Oct 12, 2015 at 04:16 PM
For anyone after a copy/paste script to drop into a 5.1 character to make it move like Mario, here you go. There is currently no slow down but that's not too hard to add in.
using UnityEngine;
using System.Collections;
public class Bug2 : MonoBehaviour {
public float moveForce;
public float maxSpeed;
private Vector3 v;
void Update () {
v = new Vector3(Input.GetAxis("Horizontal"),
Input.GetAxis("Vertical"), 0.0f);
}
void FixedUpdate() {
GetComponent<Rigidbody2D>().velocity = Vector3.ClampMagnitude
(GetComponent<Rigidbody2D>().velocity, maxSpeed);
GetComponent<Rigidbody2D>().AddForce(v.normalized * moveForce);
}
}
Answer by robertbu · Jan 20, 2014 at 12:28 AM
You need to multiply the vector by your moveSpeed in order to use moveSpeed.
The immediate stop is likely because you've modified 'Drag' in your Rigidbody component. If so, set this back to 0.0 to start.
You can normalize the vector you use for moving to solve this issue.
using UnityEngine; using System.Collections;
public class Bug2 : MonoBehaviour {
// Exposed to Editor for Easy manipulation public float moveSpeed = 1.0f; // player's base movement speed void Update () { Vector3 v = new Vector3(Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical")); rigidbody.AddForce(v.normalized * moveSpeed,ForceMode.VelocityChange); } }
Thanks for your answer, robertbu! It was helpful: Normalizing the vector works for my diagonal problem. I've also adjusted rigidbody.drag and gotten some favorable results.
I'm still not getting anywhere with acceleration, however. As a hack, I've tried incrementing drag in the update function based on button down ( -= if a button is down, += if it's not) to give the vehicle smooth acceleration and deceleration by changing its drag, but it's not really working, likely because update happens way too fast to be noticeable.
I want the bike to kind of chug to get up to speed, and drift when you cease providing it input, kind of like the original Sonic the Hedgehog, if he were running on a flat surface. Takes a second to get going, then goes nice and fast, and slows to a stop only after you've had your finger off the Dpad for a few moments.
Any suggestions on how to get an editor-exposed acceleration variable that I can use to get up to max speed?
Please don't post comments as answers. Check out the Tutorial Video
Here is a bit of an extension to the previous script. Set Rigidbody.drag to 0.0. Play with moveForce to see if you can't get what you want. 'maxSpeed' will limit the maximum speed the object can obtain.
using UnityEngine;
using System.Collections;
public class Bug2 : $$anonymous$$onoBehaviour {
public float moveForce = 2.0f;
public float maxSpeed = 4.5f;
private Vector3 v;
void Update () {
v = new Vector3(Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical"));
}
void FixedUpdate() {
rigidbody.velocity = Vector3.Clamp$$anonymous$$agnitude (rigidbody.velocity, maxSpeed);
rigidbody.AddForce(v.normalized * moveForce);
}
}
Your answer
Follow this Question
Related Questions
add acceleraction to ship controls 0 Answers
ball loses momentum 4 Answers
Vehicle - terrain collision design 1 Answer
How can I remove momentum/inertia? 0 Answers
Simulating Fighter Jet Physics (with addForce () ) 2 Answers