Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
0
Question by jmccnz · May 08, 2012 at 10:31 AM · physicsdriving

Implementing Simple Cart Physics?

Hi there,

I have been looking for a simpler solution than the realistic car based physics tutorials out there. I am working on a game with carts requiring only a simple physics system and the driving may not be realistic. So far i have implemented the following code using UnityEngine; using System.Collections;

/** Simple "cart" based physics system for moving carts controlled by a user player. */ public class CartMovementControl : MonoBehaviour {

 // every wheel contains useful wheel specific info
 public struct Wheel {
     public Transform transform;
     public GameObject go;
     public Rigidbody body;
     public bool turn;
     public float rotation;
     public float maxSteer;
     public float radius;
     public Vector3 previousLocation;
 };

 //cart properties
 public float speed = 45;
 public float maxSpeed;
 public float rotateSpeed;
 public float trueMaxSpeed;
 public float maxSteerAngle = 30;
 public float steeringRadius = 15;
 
 //public access state variables
 public Vector3 cartLocation;           // location of the center of the car
 public Vector3 cartHeading;            // current direction of the car
 public float wheelBase;                // distance between front and back wheels of the car
 
 //wheels
 public Wheel[] wheels;
 public GameObject wheelFL;
 public GameObject wheelFR;
 public GameObject wheelBL;
 public GameObject wheelBR;
 public float frontLeftRadius;
 public float frontRightRadius;
 public float backLeftRadius;
 public float backRightRadius;
 public RearWheelCollider rwc;
 
 //input
 public float turning;
 public float accel;
 public float brake;
 public bool reverse;
  
 void Update () {
     turning = Mathf.Clamp(Input.GetAxis("Horizontal"), -1, 1);
     accel = Mathf.Clamp(Input.GetAxis("Vertical"), 0, 1);
     brake = -1 * Mathf.Clamp(Input.GetAxis("Vertical"), -1, 0);
     
     if (rigidbody.velocity.sqrMagnitude == 0) {
         if (brake > 0) { reverse = true; }
         if (accel > 0) { reverse = false; }
     }
     
     if (reverse) { accel = -1*brake; }
     
     //turning should rotate any of the "turning wheels" (typically front)
     rotateCartDirection(turning);
     
     //acceleration needs be calculated along (with drag?)
     calculateCartAcceleration(accel);

     //rotate the cart wheels
     rotateCartWheels();
 }
 
 void Start() {
     rigidbody.centerOfMass = new Vector3(0, -1.5f, 0);
     rwc = GameObject.Find("RearWheels").GetComponent<RearWheelCollider>();
     trueMaxSpeed = maxSpeed * maxSpeed;
     //setup the wheel structs for each wheel object
     wheels = new Wheel[4];
     wheels[0] = setupWheelParameters(wheelFL, frontLeftRadius, true);
     wheels[1] = setupWheelParameters(wheelFR, frontRightRadius, true);
     wheels[2] = setupWheelParameters(wheelBL, backLeftRadius, false);
     wheels[3] = setupWheelParameters(wheelBR, backRightRadius, false);
 }
 
 void calculateCartAcceleration(float accel) {
     print(accel);
     if (Mathf.Abs(accel) < 0.15 || !rwc.isGrounded) return;
     Vector3 direction = transform.forward;
     if (accel < 0) { 
         direction = -transform.forward; 
         accel = -1 * accel;
     }
     rigidbody.AddForce(direction * accel * speed * 100);
      var v = rigidbody.velocity; // current speed
     // for limiting kart max speed  
     if(v.sqrMagnitude >= trueMaxSpeed){ // truemaxspeed is the max speed * max speed.
         rigidbody.velocity = v.normalized * maxSpeed;
        }
 }
 
 void rotateCartDirection(float turning) {
     //we cannot rotate the cart when it is not grounded (but can rotate the wheels)
     if (rwc.isGrounded) {
         float cartRotate = turning * steeringRadius * Time.deltaTime * rotateSpeed;
         transform.Rotate(0, cartRotate, 0);
     }
     
     //now apply additional rotations to the wheels
     foreach (Wheel wheel in wheels) {
         float rotateAngle = turning * wheel.maxSteer; //will be 0 if the wheel is not a turning wheel
         wheel.transform.localRotation = Quaternion.Euler(0, rotateAngle, 0);
     }
 }
 
 void rotateCartWheels() {
     for (int i = 0; i < wheels.Length; i++) {
         if (!rwc.isGrounded) {
             //in the air so just rotate freely at the maximum speed
             Wheel wh = wheels[i];
             wh.transform.Rotate(rigidbody.velocity.x, 0, 0);
         } else {
             //distance travelled = radius * angle of rotation
             Wheel wh = wheels[i];
             Vector3 dist = wh.transform.position - wh.previousLocation;
             double rad = wh.transform.localScale.y / 2.0;
             float xrotation = (float)((dist.x/rad) * rigidbody.velocity.x);
             wh.transform.Rotate(xrotation, 0, 0);
             wh.previousLocation = wh.transform.position;
         }
     }
 }
 
 Wheel setupWheelParameters(GameObject wheel, float radius, bool turn) {
     Wheel result = new Wheel();
     result.go = wheel;
     result.transform = wheel.transform;
     result.body = wheel.rigidbody;
     result.radius = radius;
     result.turn = turn;
     if (turn) 
         result.maxSteer = maxSteerAngle;
     else 
         result.maxSteer = 0;
     result.previousLocation = wheel.transform.position;
     return result;
 }

}

This works fine for moving the cart around and rotating the wheels.

I would like to know how I should implement some form of drag on the cart so it slows down due to friction with the road? Also is there any better way to implement the forward force (currently using the rigidbody.addForce(transform.foward...) method however this will not reduce force in any direction - currently the car can move forward and then rotate 90 degrees while still travelling forward. Also is there a way to stop the car rotating on the spot?

Any advice would be appreciated

Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Ahmed-Saleh · Jun 01, 2020 at 07:56 PM

if you want the cart to turn only when it is moving make the turning force a function of speed and play with the parameters a bit to get it right

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

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

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

limiting player rotation 0 Answers

Forklift Pallet Slides off Forks 1 Answer

2D 360 degress platformer example needed 0 Answers

Character Rides In Vehicle 1 Answer

How is wheelCollider RPM calculated exactly? 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