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. Dismiss Notice

Magnetic kart physics

Discussion in 'Scripting' started by tetriser016, Jan 19, 2016.

  1. tetriser016

    tetriser016

    Joined:
    Jan 3, 2014
    Posts:
    100
    UPDATE: Changed the title to avoid misunderstandings between realistic racing games and kart racing games.

    How can I achieve this?
    I want a solution for making a kart sticks to irregular tracks, similar to this and this.

    What should I use, physics or raycasts?

    I'm not sure if this thread is giving an appropriate solution...

    Don't tell me to buy an asset as I don't have money. (sorry...)

    If there any tutorials for this, please give me the link. If there's a C# code snippet, please post it.
     
    Last edited: Dec 15, 2016
  2. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
  3. tetriser016

    tetriser016

    Joined:
    Jan 3, 2014
    Posts:
    100
    @bigmisterb - Thanks for the thread, but the car script wasn't let the vehicle stick to the track, like in F-Zero X.
     
  4. Hyblademin

    Hyblademin

    Joined:
    Oct 14, 2013
    Posts:
    725
    I would use Physics.Raycast(). In F-Zero X/GX(AX), the vehicle is pulled toward the track unless it gets too far away, at which time normal gravity gets control. If you raycast downward from the vehicle you can get the surface normal and apply a gravity force in the direction of the track, given that it's close enough, or something like that. This is only a first step, of course, but I think it will lead to the most robust method.
     
  5. tetriser016

    tetriser016

    Joined:
    Jan 3, 2014
    Posts:
    100
    Can you please give me the code, @Hyblademin ? :)

    If you don't, can you just give me some hints?

    Note: I prefer a C# language...
     
  6. Hyblademin

    Hyblademin

    Joined:
    Oct 14, 2013
    Posts:
    725
    This should get you started:

    public static bool Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers,QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);

    I'll assume the vehicle object is running this script. At a sensible point in the code, we can add

    Code (CSharp):
    1. LayerMask trackMask;     //You'll need to initialize this to the correct mask, easiest with inspector
    2. float magnetDistance;     //Maximum distance that a vehicle can be pulled by the track
    3. float magnetForce;     //Magnitude of the magnet force
    4.  
    5. Vector3 localDown = transform.TransformPoint(transform.localPosition + Vector3.down);
    6.  
    7. if (Physics.Raycast(transform.position, localDown, magnetDistance, trackMask, false))
    8. {
    9.      rigidbody.useGravity = false;
    10.  
    11.      //Your magnetic force vector is magnetForce * localDown
    12.      //Apply the force to the rigidbody here
    13. }
    14. else
    15. {
    16.      rigidbody.useGravity = true;
    17. }
    This should raycast downward (locally) from the vehicle, and check whether you hit the track within the max distance. If it does, it overrides gravity and instead uses an attractive force directed locally downward from the vehicle, at a magnitude specified by you. If not, regular gravity is turned on. This allows the vehicle to disengage from the track due to sloppy/magnificent driving.

    You will probably need to debug this, since I just wrote it sitting at work. Also, the behavior isn't perfect, since it only casts downward from the vehicle, and will only pull the object in that direction. It also doesn't orient the vehicle, which F-Zero does do, so you'll have to add that if wanted.

    If this doesn't behave how you would like it to, you may get better results using Collider.ClosestPointOnBounds() or something to get the nearest point on the track and pull toward that. Other possibilities include Physics.SphereCast() or doing a radius sweep in Physics.OverlapSphere().
     
  7. tetriser016

    tetriser016

    Joined:
    Jan 3, 2014
    Posts:
    100
    @Hyblademin - Yes, the code even can't handle spherical tracks. Well, it's almost 6 months, do you have a correct solution? I'm not good enough with raycasts.
     
  8. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Sounds like you should learn how to do it. It's not rocket science. Generally don't think magnetic, think gravity along surface normal. So if the gravity always goes in the direction of the track's surface then things will appear magnetic. That's how it generally works. So you'll want to raycast from the local craft's orientation down (transform.down is direction to cast in) and then retrieve the normal. This normal in negative, is the gravity of the craft, which is applied using AddForce on the rigidbody ie rb.AddForce(-hit.normal * amount);

    You'll need to turn off gravity for the rigidbody and simply perform that. It's very trivial code.


    There is an asset that will do this on asset store as far as I can tell, why not ask them if it performs local gravity? https://www.assetstore.unity3d.com/en/#!/content/59662

    Waiting 6 months seems like a long time to be spoon fed code. Perhaps take matters into your own hands? It doesn't seem that expensive really or search online for hovercraft stuff in unity.
     
  9. tetriser016

    tetriser016

    Joined:
    Jan 3, 2014
    Posts:
    100
    @hippocoder - Well, not a hovercraft, it's an anti-gravity kart similar to Mario Kart 8.

    HoverKit looks promising, I'll check it out.
     
  10. tetriser016

    tetriser016

    Joined:
    Jan 3, 2014
    Posts:
    100
    @hippocoder - I'm back, and unfortunately, HoverKit is now deprecated so I can't purchase it... :(
    It has been 4 months since my last reply (I'm too busy with another game and finished on August)

    Additionally, I've learned a bit about raycasting and I may use my own solution for this. But it might not work as I expect I'm afraid...


    @Hyblademin - Do you have wrote a better code for this? Or something that can be mixed with Yoggy's car physics script for an almost complete magnetic (Sonic-like) kart?
     
  11. tetriser016

    tetriser016

    Joined:
    Jan 3, 2014
    Posts:
    100
    OK, I've almost figured it out, but it seems to fail hardly.

    My own solution, based on both @Hyblademin 's and @hippocoder' s gravity code hints:
    Code (CSharp):
    1. RaycastHit hit;
    2.         Vector3 localDown = transform.TransformPoint(transform.localPosition + Vector3.down);
    3.         if (Physics.Raycast(transform.position, localDown, out hit, magnetDistance, trackMask, QueryTriggerInteraction.UseGlobal))
    4.         {
    5.             body.useGravity = false;
    6.             body.AddForce(-hit.normal * magnetForce);
    7.         }
    8.         else
    9.         {
    10.             body.useGravity = true;
    11.         }
    My problem is, if the vehicle's mass is too low, the code makes the vehicle gone flying like crazy as it was floating outer-space. While with high mass, the vehicle will not move or move very slow.

    Even any solution I'm capable to do will causing the vehicle to "tumble".

    Any mistakes on my code?
     
    Last edited: Dec 14, 2016
  12. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    http://wiki.unity3d.com/index.php/WheelColliderSource-WheelColliderSource - the perfect hovercraft is really just a pretend suspension (kinda).

    You probably just want to just fix what you have, so I would recommend calculating the amount of force you need based on how much "compression" or close to the ground the origin of the force is to the ground (hit.distance will probably work), multiplied by some number you make up till it feels right. Dampening the effect so it doesn't do the behaviours you describe.

    pseudocode:

    float dist01 = hit.distance / magnetDistance;

    finalForce * (1-dist01) * power;

    Then apply somehow. Basically you want to make it only increase in power the closer it is to the ground, and also have some kind of damping going on which I haven't covered either - sorry it's been a while. But I'm 100% sure wheel collider source can mimick what you want too.
     
  13. Lord-Smingleigh

    Lord-Smingleigh

    Joined:
    Jan 23, 2013
    Posts:
    10
    How about a bunch of trigger volumes instead of raycasts. A car inside the volume has its "down" direction set for gravity-like acceleration and an "up" to make it orient correctly. As an example, a spherical body which is intended to be driveable will have a spherical trigger collider attached, and that will tell the car to orient its up direction away from the sphere centre and "fall" towards the centre of the sphere, whereas a more complicated track would have different "reorientation" colliders, perhaps simple box or sphere colliders, in strategic locations, to change the car's orientation.
     
  14. tetriser016

    tetriser016

    Joined:
    Jan 3, 2014
    Posts:
    100
    @hippocoder - Maybe that should work, but I want to make an arcade-style kart with an ability to stick on walls and ceilings same to Crash or Sonic racing games. Anything simpler than that? :(

    @Lord-Smingleigh - Well, I'll try to remake my code again later with triggers instead of raycasts.

    Wait, do you said "reorientation colliders"? Maybe that will work too.
     
  15. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    oh if it's that simple, and a kart racer, you just do your physics normally but change direction of gravity, and apply gravity each fixedupdate yourself (pointing along the ground normal)
     
  16. tetriser016

    tetriser016

    Joined:
    Jan 3, 2014
    Posts:
    100
    @hippocoder - Wow, that was fast! :D

    Well, do you mean is to change the world gravity or the kart's gravity itself? And how do I do that in code? (I'm not on my laptop right now...)

    P/S: I want to use the bouncy vehicle physics by @Munchy2007 as the base vehicle controller.
     
  17. tetriser016

    tetriser016

    Joined:
    Jan 3, 2014
    Posts:
    100
    Hey, I'm back.

    Another problem, how can I properly align the magnetic kart while attaching it to the surface normal?

    Sorry, I'm still a rookie with this thing. Some solutions from Unity Answers aren't helpful...

    (I want to combine my old magnet code with the aligning solution)
     
  18. Emile97

    Emile97

    Joined:
    May 28, 2017
    Posts:
    105
    Bro. Search for funcar kit on internet... Then tweak the code a little bit. After an hour get the physics perfectly working
     
  19. tetriser016

    tetriser016

    Joined:
    Jan 3, 2014
    Posts:
    100