Search Unity

Source Surfing Phyiscs?

Discussion in 'Physics' started by Drowzee, Oct 10, 2017.

  1. Drowzee

    Drowzee

    Joined:
    Aug 16, 2015
    Posts:
    27
    Obviously I don't expect exact code on how this works, but I was wondering if anyone understood how it's done in source, and possibly a general idea of how you'd duplicate that in Unity? Mostly out of general curiosity, although I might try to make something out of it if I have the patience :p
     
  2. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    Please elaborate as to the definition of "source surfing physics". You mean wave surfing?
     
    Ironmax likes this.
  3. BoogieD

    BoogieD

    Joined:
    Jun 8, 2016
    Posts:
    236
    Try Googling 'physics source code', download and study it.
     
  4. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    Here is an article on it with some code and references
    http://flafla2.github.io/2015/02/14/bunnyhop.html
    https://steamcommunity.com/sharedfiles/filedetails/?id=184184420

    Ill post the code from one of those sites here with a small edit.
    Keep in mind that since the code uses Time.fixedDeltaTime, it probably expects to be ran in FixedUpdate
    Code (CSharp):
    1. // accelDir: normalized direction that the player has requested to move (taking into account the movement keys and look direction)
    2. // prevVelocity: The current velocity of the player, before any additional calculations
    3. // accelerate: The server-defined player acceleration value
    4. // max_velocity: The server-defined maximum player velocity (this is not strictly adhered to due to strafejumping)
    5. private Vector3 Accelerate(Vector3 accelDir, Vector3 prevVelocity, float accelerate, float max_velocity)
    6. {
    7.     float projVel = Vector3.Dot(prevVelocity, accelDir); // Vector projection of Current velocity onto accelDir.
    8.     float accelVel = accelerate * Time.fixedDeltaTime; // Accelerated velocity in direction of movment
    9.  
    10.     // If necessary, truncate the accelerated velocity so the vector projection does not exceed max_velocity
    11.     if(projVel + accelVel > max_velocity)
    12.     {
    13.         //accelVel = max_velocity - projVel;
    14.         accelVel = Mathf.Max(0f, max_velocity - projVel); //I found this to be better
    15.     }
    16.  
    17.     return prevVelocity + accelDir * accelVel;
    18. }
    19.  
    20. private Vector3 MoveGround(Vector3 accelDir, Vector3 prevVelocity)
    21. {
    22.     // Apply Friction
    23.     float speed = prevVelocity.magnitude;
    24.     if (speed != 0) // To avoid divide by zero errors
    25.     {
    26.         float drop = speed * friction * Time.fixedDeltaTime;
    27.         prevVelocity *= Mathf.Max(speed - drop, 0) / speed; // Scale the velocity based on friction.
    28.     }
    29.  
    30.     // ground_accelerate and max_velocity_ground are server-defined movement variables
    31.     return Accelerate(accelDir, prevVelocity, ground_accelerate, max_velocity_ground);
    32. }
    33.  
    34. private Vector3 MoveAir(Vector3 accelDir, Vector3 prevVelocity)
    35. {
    36.     // air_accelerate and max_velocity_air are server-defined movement variables
    37.     return Accelerate(accelDir, prevVelocity, air_accelerate, max_velocity_air);
    38. }

    A few things...
    I think some base testing values can be...
    max_velocity_air = .3f
    air_accelerate = 100

    Edit-
    I am not sure about this part, but I am assuming you will also need to make sure your character controller system has a "slope limit" of which if the angle of the surface you are standing on is too steep, then isGrounded will be false and no friction should be applied.
    Air strafing should handle the rest.

    I am also assuming by surfing you mean this
     
    Last edited: Oct 15, 2017
    Deleted User likes this.
  5. AlanMattano

    AlanMattano

    Joined:
    Aug 22, 2013
    Posts:
    1,501
    Making some experiment in the past for surfing and windsurfing simulation, my conclusion was:
    • Make a collider wave mesh is GPU expensive but there is some asset in the asset store.
    • Add some kind of mesh deformation when the surf is passing.
    • Put a low CG on the surfboard RB to stabilise it.
    • Make a tail tween fin of the surfboard that produces side lift and drag (vertical stabiliser as rubber).
      If is arcade, then only drag and angle control direction.
    • Add lift to the surfboard when is moving, perpendicular to the board and square the velocity.
    • The surfer animation use inverse kinematic or "Final Ik" to be on board.
    • Push the CG and surfer back when is increasing in speed.