Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Local Gravity Force

Discussion in 'Scripting' started by goopydoopyloops, May 10, 2015.

  1. goopydoopyloops

    goopydoopyloops

    Joined:
    May 10, 2015
    Posts:
    10
    I have recently been wanting to re-create the gravity from mario kart 8 (For educational purposes) I have played around with a script from a project that was given out in this video:


    As you can see, it is really close to what I am trying to simulate. The problem is, is that the gravity isn't really gravity at all, more of sticking to the mesh. What I want is for the rigidbody to fluctuate depending on the forces given. Here is the code that came with the project:

    Code (JavaScript):
    1. public var forwardSpeed:Number;
    2. public var steerAngle:Number;
    3. public var rotationT:float = 0.25;
    4.  
    5. function Update () {
    6.     var x:Number = Input.GetAxis("Horizontal");
    7.     var y:Number = Input.GetAxis("Vertical");
    8.  
    9.     if (HitTestWithRoad()) {
    10.     }
    11.     this.GetComponent.<Rigidbody>().velocity += y * transform.forward * forwardSpeed;
    12.      
    13.     this.GetComponent.<Rigidbody>().AddTorque(transform.up * x * steerAngle, ForceMode.Acceleration);
    14. }
    15.  
    16. function OnCollisionEnter(collision:Collision) {
    17.     if (collision.gameObject.tag == 'roadWall') {
    18.         //var contact:ContactPoint = collision.contacts[0];
    19.         //this.gameObject.transform.position += contact.normal * 0.2;
    20.     }
    21. }
    22.  
    23. function HitTestWithRoad() {
    24.     var position:Vector3 = transform.position + transform.TransformDirection(Vector3.up) * 0.2;
    25.     var direction:Vector3 = transform.TransformDirection(Vector3.down);
    26.     var ray:Ray = new Ray(position, direction);
    27.     var hit:RaycastHit;
    28.     var distance:float = 2;
    29.  
    30.     Debug.DrawLine(ray.origin, ray.origin + ray.direction * distance, Color.red);
    31.     var inGround:boolean = false;
    32.     if (Physics.Raycast(ray, hit, distance)) {
    33.         if (hit.collider.tag == 'road'){
    34.            this.transform.position = hit.point;
    35.          
    36.            //Debug.DrawLine(ray.origin, hit.point, Color.blue);
    37.            Debug.DrawLine(hit.point, hit.point + hit.normal, Color.green);
    38.          
    39.            var curUpVector:Vector3 = position - hit.point;
    40.            var hitUpVector:Vector3 = hit.normal;
    41.            Debug.DrawLine(hit.point, hit.point + curUpVector.normalized, Color.white);
    42.          
    43.            var targetQ:Quaternion;
    44.             //TODO: これから進む先でrayを落とす(sphereのvelocity.normalizeを参照)
    45.             var fPosition:Vector3 = transform.position + transform.TransformDirection(Vector3(0, 2.0, 1.0));
    46.             var fDirection:Vector3 = transform.TransformDirection(Vector3.down);
    47.            var fRay:Ray = new Ray(fPosition, fDirection);
    48.            var fHit:RaycastHit;
    49.            var fDistance:float = 4;
    50.            Debug.DrawLine(fRay.origin, fRay.origin + fRay.direction * fDistance, Color.cyan);
    51.            if (Physics.Raycast(fRay, fHit, fDistance)) {
    52.               if (fHit.collider.tag == 'road'){
    53.                    Debug.DrawLine(fHit.point, fHit.point + fHit.normal * fDistance, Color.magenta);
    54.                    targetQ.SetLookRotation(fHit.point - transform.position, hitUpVector);
    55.               }
    56.            }
    57.            if (targetQ == null) {
    58.                 Debug.Log("None Forward");
    59.                targetQ.SetLookRotation(transform.TransformDirection(Vector3.forward), hitUpVector);
    60.            }
    61.            this.gameObject.transform.rotation = Quaternion.Slerp(this.gameObject.transform.rotation, targetQ, rotationT);
    62.            inGround = true;
    63.         }
    64.     }
    65.  
    66.     return inGround;
    67. }
    The code does what was advertised. But the code is missing the "Loose" feel. Here is an example of what I mean:


    Any answers are greatly appreciated! Thank you
    ~Jacob
     
  2. goopydoopyloops

    goopydoopyloops

    Joined:
    May 10, 2015
    Posts:
    10
    This can either be compared with f-zero or mario kart either one :)
     
  3. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    8,999
  4. goopydoopyloops

    goopydoopyloops

    Joined:
    May 10, 2015
    Posts:
    10
  5. goopydoopyloops

    goopydoopyloops

    Joined:
    May 10, 2015
    Posts:
    10
    Would it work if I set the native gravitational force to floor? I think it would. How do I do that?
     
  6. goopydoopyloops

    goopydoopyloops

    Joined:
    May 10, 2015
    Posts:
    10
    I'm trying to contact the original poster of the original code, but he doesn't respoding
     
  7. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    The code is basically forcing the player to follow the road, by manipulating its velocity, position and rotation directly.

    You don't want that, you want to add a downwards force in the direction of the normal of the road. This will make the road following looser and more natural.
     
  8. goopydoopyloops

    goopydoopyloops

    Joined:
    May 10, 2015
    Posts:
    10
    Would I call that threw raycasting for the mesh or collude?
     
  9. goopydoopyloops

    goopydoopyloops

    Joined:
    May 10, 2015
    Posts:
    10
    Please help me, this has been bothering me for weeks and I can't figure out how to get the gravity to look natural. If it helps, I have an example of what I want here:
     
  10. goopydoopyloops

    goopydoopyloops

    Joined:
    May 10, 2015
    Posts:
    10
    Please help me I still can't figure it out!!!!!!!
     
  11. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    What have you tried?
     
  12. SnakeTheRipper

    SnakeTheRipper

    Joined:
    Dec 31, 2014
    Posts:
    136
    I think that shouldn't be very hard.

    You just need to align the car with the terrain and therefore, add a relative force down to the gameObject.

    Code (CSharp):
    1. rigidbody.AddRelativeForce(Vector3.down * 9.81f * Time.fixedDeltaTime);
     
  13. DustySkunk

    DustySkunk

    Joined:
    Sep 12, 2013
    Posts:
    13
    Just like SnakeTheRipper said. However unless I am missing something, the OP needs the character model to constantly be aligned in such a way that the local "down" is pointing toward the track. That requires aligning the object first so that local down is pointing toward the track.

    In that case, I would recommend raycasting below your object, getting the contact normal from the surface, aligning your object to that normal, then doing what he suggested. That way, Vector3.down will always be pointing toward the track.

    You could do this with collisions as well, but you may find that it isn't as consistent. YMMV
     
    SnakeTheRipper likes this.