Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
4
Question by Major · Apr 13, 2014 at 05:17 PM · carweapontopdown2d-gameplaycars

Top Down 2D Car Physics

What I want to do is to make a top down game implementing the Unity3d 2d system. When I say top down I mean from the roof of the car. I want to be able to steer the car realistically like what the wheel collides do in car demo.

Before anyone says it: I have spent a great deal of time searching already.

Comment
Add comment · Show 7
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image AlucardJay · Apr 13, 2014 at 05:33 PM 1
Share

I'm fairly sure you asked this question before and it got closed. (http://answers.unity3d.com/questions/685731/top-down-2d-car-physics.html), and you deleted it when there were useful comments given ....

avatar image Major · Apr 13, 2014 at 10:07 PM 0
Share

the useful comment wasn't useful. And it was closed for being a duplicate question when it wasn't a duplicate.

avatar image getyour411 · Apr 13, 2014 at 10:19 PM 0
Share

I want to design a game please copy/paste code isn't what UA is for; if you have a specific question about how to accomplish a part of this, you should revise this question and be specific; this is a duplicate question (Google Unity car physics 2D) in general, but without any specifics it's also so vague.

avatar image Major · Apr 13, 2014 at 10:23 PM 0
Share

Okay let me make this very clear one more time. I ALREADY SEARCHED THIS TOPIC FOR A GOOD COUPLE OF HOURS. THAT $$anonymous$$EANS GOGGLING UNITY3D CAR PHYSICS 2D. WHAT CO$$anonymous$$ES UP IS FRO$$anonymous$$ THE SID$$anonymous$$ NOT THE TOP DOWN. READ THE ORIGINAL POST.

avatar image getyour411 · Apr 13, 2014 at 10:25 PM 0
Share

The original post seems to have been deleted; there are many examples of car physics 2D you still haven't specified what part of this game design you have in $$anonymous$$d that you need help with; 'how do I write my entire car steering' isn't really a specific question, it's a code request at best.

Show more comments

4 Replies

· Add your reply
  • Sort: 
avatar image
8

Answer by ijidau · Nov 04, 2015 at 04:00 AM

I know it's far too late, but I used the hints above to create the following script, please excuse the verbose syntax. I have the public variables set to 5 (acceleration) and 3 (steering). I'm posting because someone may still find this useful:

 using UnityEngine;
 using System.Collections;
 
 public class 2dCarController : MonoBehaviour {
 
     public float acceleration;
     public float steering;
     private Rigidbody2D rb;
 
     void Start () {
         rb = GetComponent<Rigidbody2D>();
     }
 
     void FixedUpdate () {
         float h = -Input.GetAxis("Horizontal");
         float v = Input.GetAxis("Vertical");
 
         Vector2 speed = transform.up * (v * acceleration);
         rb.AddForce(speed);
 
         float direction = Vector2.Dot(rb.velocity, rb.GetRelativeVector(Vector2.up));
         if(direction >= 0.0f) {
             rb.rotation += h * steering * (rb.velocity.magnitude / 5.0f);
             //rb.AddTorque((h * steering) * (rb.velocity.magnitude / 10.0f));
         } else {
             rb.rotation -= h * steering * (rb.velocity.magnitude / 5.0f);
             //rb.AddTorque((-h * steering) * (rb.velocity.magnitude / 10.0f));
         }
 
         Vector2 forward = new Vector2(0.0f, 0.5f);
         float steeringRightAngle;
         if(rb.angularVelocity > 0) {
             steeringRightAngle = -90;
         } else {
             steeringRightAngle = 90;
         }
 
         Vector2 rightAngleFromForward = Quaternion.AngleAxis(steeringRightAngle, Vector3.forward) * forward;
         Debug.DrawLine((Vector3)rb.position, (Vector3)rb.GetRelativePoint(rightAngleFromForward), Color.green);
 
         float driftForce = Vector2.Dot(rb.velocity, rb.GetRelativeVector(rightAngleFromForward.normalized));
 
         Vector2 relativeForce = (rightAngleFromForward.normalized * -1.0f) * (driftForce * 10.0f);
 
 
         Debug.DrawLine((Vector3)rb.position, (Vector3)rb.GetRelativePoint(relativeForce), Color.red);
 
         rb.AddForce(rb.GetRelativeVector(relativeForce));
     }
 }

Obviously this is just a model of 2D topdown car physics (no tyre model). It calculates the drift and counteracts this with an opposing force, shown with the debug.draw red line. The steering is reduced to zero when stationary to prevent the car spinning on the spot. Rigidbody drag and angularDrag are both set to 1.

The most interesting calculation is the dirftForce, which I got the concept from: http://docs.unity3d.com/Manual/AmountVectorMagnitudeInAnotherDirection.html

Note that I modify RigidBody2D rotation directly, but you can try AddTorque as shown (commented out).

I'm not terribly good with maths, but I hacked away at this until I got it roughly working as intended.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image sarpdoruk · May 12, 2016 at 07:51 AM 0
Share

This works great, thank you for sharing.

avatar image IAMBATMAN · Dec 28, 2016 at 12:27 AM 0
Share

You are the best! This one is the best for my game :)

avatar image kdorland · Oct 14, 2018 at 06:43 PM 3
Share

I liked this version a lot, and decided to simplify the math and add some comments. Also, I added a speed limit to the car.

For anyone who's interested:

 using UnityEngine;
 using UnityEngine.Tilemaps;
 
 public class CarController : $$anonymous$$onoBehaviour {
     public float maxSpeed;
     public float acceleration;
     public float steering;
 
     private Rigidbody2D rb;
     private float currentSpeed;
 
     private void Start()
     {
         this.rb = GetComponent<Rigidbody2D>();
     }
 
     private void FixedUpdate()
     {
         // Get input
         float h = -Input.GetAxis("Horizontal");
         float v = Input.GetAxis("Vertical");
                 
         // Calculate speed from input and acceleration (transform.up is forward)
         Vector2 speed = transform.up * (v * acceleration);
         rb.AddForce(speed);
 
         // Create car rotation
         float direction = Vector2.Dot(rb.velocity, rb.GetRelativeVector(Vector2.up));
         if (direction >= 0.0f)
         {
             rb.rotation += h * steering * (rb.velocity.magnitude / maxSpeed);
         }
         else
         {
             rb.rotation -= h * steering * (rb.velocity.magnitude / maxSpeed);
         }
 
         // Change velocity based on rotation
         float driftForce = Vector2.Dot(rb.velocity, rb.GetRelativeVector(Vector2.left)) * 2.0f;
         Vector2 relativeForce = Vector2.right * driftForce;
         Debug.DrawLine(rb.position, rb.GetRelativePoint(relativeForce), Color.green);
         rb.AddForce(rb.GetRelativeVector(relativeForce));
 
         // Force max speed limit
         if (rb.velocity.magnitude > maxSpeed)
         {
             rb.velocity = rb.velocity.normalized * maxSpeed;
         }
         currentSpeed = rb.velocity.magnitude;
     }
 
 }
 
 

avatar image sheherezade007 kdorland · Mar 10, 2021 at 10:14 PM 0
Share

This is the code I've been looking for! Thanks a Million!

avatar image
6

Answer by nexis717 · Oct 22, 2015 at 08:11 AM

A bit of an old question but, thought I would pitch in, in case anyone else comes across the question, looking for an answer. Jeff and Major have pretty much worked it out but, to provide a little more fleshed out answer in C# I found that playing around with the rigidbody 2d drags helped with getting more realistic feeling car movements. You could modify or remove the noGas() method, and move it into the FixedUpdate() if you wanted. I found that this helped with braking and a more realistic stop, when not accelerating.

  1. Add a Rigidbody 2D component to your Car object (turn the Gravity Scale to 0) and then implement a script along the lines of the following:

      public float power = 3;
         public float maxspeed = 5;
         public float turnpower = 2;
         public float friction = 3;
         public Vector2 curspeed ;
         Rigidbody2D rigidbody2D;
     
         // Use this for initialization
         void Start () {
             rigidbody2D = GetComponent<Rigidbody2D>();
         }
         
     
         void FixedUpdate()
         {
             curspeed = new Vector2(rigidbody2D.velocity.x,    rigidbody2D.velocity.y);
     
             if (curspeed.magnitude > maxspeed)
             {
                 curspeed = curspeed.normalized;
                 curspeed *= maxspeed;
             }
     
             if (Input.GetKey(KeyCode.W))
             {
                 rigidbody2D.AddForce(transform.up * power);
                  rigidbody2D.drag = friction;
             }
             if (Input.GetKey(KeyCode.S))
             {
                 rigidbody2D.AddForce(-(transform.up) * (power/2));
                 rigidbody2D.drag = friction;
             }
              if (Input.GetKey(KeyCode.A))
             {
                 transform.Rotate(Vector3.forward * turnpower);
             }
              if (Input.GetKey(KeyCode.D))
             {
                 transform.Rotate(Vector3.forward * -turnpower);
             }
     
             noGas();
     
         }
     
         void noGas()
         {
             bool gas;
             if(Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.S))
             {
                 gas = true;
             }
             else
             {
                 gas = false;
             }
     
             if (!gas)
             {
                 rigidbody2D.drag = friction * 2;
             }
         }
    
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Jeff-Kesselman · Apr 14, 2014 at 12:24 AM

So, you can work this out yourself if you know what a force is and what acceleration is.

(1) Start with a basic model: Track velocity in X and Y and add it times delta time into your position on update Try that and see how it behaves like an object in space.

(2) When you add velocity, add it in the "steering direction". See how it behaves like a car with no traction

(3) Add an opposing force at right angles to the steering direction and proportional to the velocity on that angle, this adds traction.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Major · Apr 17, 2014 at 11:59 PM 0
Share

I have all of that already except I have no idea how to implement 3. I have been working on it for a while, but I just don't understand enough to work it out. :(

 var power : float = 3;
 var maxspeed : float = 5;
 var turnpower : float = 2;
 
 var friction : float = 10;
 
 var curspeed : Vector2;
 
 function Update () 
 {
     curspeed = Vector2(rigidbody2D.velocity.x, rigidbody2D.velocity.y);
     if(curspeed.magnitude > maxspeed)
     {
         curspeed = curspeed.normalized;
         curspeed *= maxspeed;
     }
         
     if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.W))
     {
         rigidbody2D.AddForce(transform.up * power);
     }
     
     if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.S))
     {
         rigidbody2D.AddForce(-(transform.up) * power);
     }
     
     if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.A))
     {
         transform.Rotate(Vector3.forward * turnpower);
     }
     
     if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.D))
     {
         transform.Rotate(Vector3.forward * -turnpower);
     }
 }
avatar image
0

Answer by sandro_lord · Feb 25, 2019 at 05:51 PM

ok i am 5 years late but just in case somone stumbles on this. i have made a simple script which works but has no friction so you cant drift with this one, but its shorter than others.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class drive : MonoBehaviour
 {
     Rigidbody2D rb;
     float rotation;
     float x;
     float y;
     public float speed=1;
     public float turnspeed = 1;
     int temp=0;
     // Start is called before the first frame update
     void Start()
     {
         rb = GetComponent<Rigidbody2D>();
     }
 
     // Update is called once per frame
     void Update()
     {
         rotation = rb.rotation;
         rb.rotation = rotation - Input.GetAxis("Horizontal")*turnspeed*Time.deltaTime*10;
         rotation=Mathf.Deg2Rad* rotation;
         x = Mathf.Sin(rotation) * speed * Time.deltaTime*10;
         y = Mathf.Cos(rotation) * speed * Time.deltaTime*10;
 
         rb.velocity=new Vector2(-x,y);
     }
 }
 

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image SergioCanRam · Sep 13, 2019 at 10:29 AM 0
Share

Your answer was helpful for me, Sandro_lord ....I am a complete newbie, I am trying to improve your code adding code so that the car can go backwards...I'll let you know! :)

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

33 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Top Down 2D Car Physics 0 Answers

Multiple Cars not working 1 Answer

TOP down 2d car physics 0 Answers

stabilize car? help! 0 Answers

Ignoring force of impact for rotation axis only 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges