Search Unity

Carving effect challenge

Discussion in 'Editor & General Support' started by JulienB, Nov 30, 2011.

  1. JulienB

    JulienB

    Guest

    I am trying to make a carving effect similar to snowboard carving. In other words change the trajectory of an object with its orientation. I am pushing the object with a strong force at first, and I would like to redirect that force without reapplying force to the rigidbody.

    Here is an image for you to understand better:


    I wish that the new orientation of the object after the torque force is applied would make the object adopt a trajectory similar to the blue one instead of sliding on the yellow trajectory.

    If you have any hint on how to tackle this please help :), or if you have any other idea on how to tackle snowboard carving maybe without rigidbodies...

    I have tried attaching wheels to it and it was still sliding again...
    I also tried to apply constant force on local Z but its not realistic...

    Thank you !
     
  2. justinlloyd

    justinlloyd

    Joined:
    Aug 5, 2010
    Posts:
    1,680
    You have to disconnect the result you see on-screen from the physics taking place in the game.

    None of the surfing or snowboarding games I did ever used a true and proper physics system.

    On the PSX version of the snowboarding game I worked on, we did a very simple "physics" model that worked more like a steerable vehicle, it was more character controller than physics based. A PS2 snowboarding game used more advanced physics, but was still a complete cheat. There was some ragdoll stuff for when the player wiped out, but for the most part it was all custom physics.

    I did the surfing "physics" on a PS2 surfing game for Acclaim, that again, was more steerable vehicle with simple physics than a full physics solution. On another XBOX/PS2 surfing game, I wasn't involved with the physics at all, but from what I understand there were many physics cheats in there that had nothing to do with anything that Havoc or PhysX or ODE or any other physical simulation system.
     
  3. JulienB

    JulienB

    Guest

    Last edited by a moderator: Dec 1, 2011
  4. justinlloyd

    justinlloyd

    Joined:
    Aug 5, 2010
    Posts:
    1,680
    Got bored and threw this together tonight:

    $Untitled-1.jpg

    http://www.otakunozoku.com/Snowboard/WebPlayer.html

    A D to steer. Very quick test. Yes, there are issues, but for a couple of hours work it illustrates the point.

    Code:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. //using System;
    5.  
    6. public class SnowboardCharacterController : MonoBehaviour
    7. {
    8.     private const float LengthOfSnowboard = 1.5f;
    9.     private const float HalfSnowboardLength = LengthOfSnowboard / 2.0f;
    10.     private const float HeightOfRider = 2.0f;
    11.  
    12.     public float m_minForwardVelocity;
    13.     public float m_maxForwardVelocity;
    14.     public float m_maxAccelerationOnGround;
    15.     public float m_slopeAccelerationDivisor;
    16.     public float m_verticalNudge;
    17.     public float m_turnRate;
    18.     public float m_forwardFriction;
    19.     public float m_leanFactor;
    20.  
    21.     private float m_mountainAngle;
    22.     private float m_mountainSlope;
    23.     private Vector3 m_offset;
    24.     private Vector3 m_snowboardPosition;
    25.     private float m_forwardVelocity;
    26.     private float m_heading;
    27.     private float m_turnAngle;
    28.     public ParticleEmitter m_leftEmitter;
    29.     public ParticleEmitter m_rightEmitter;
    30.     public GameObject m_rearEmitter;
    31.     protected Vector3 m_velocity;
    32.     protected Transform m_myTransform;
    33.  
    34.     void OnGUI()
    35.     {
    36.         GUI.color = Color.red;
    37.         GUI.Label(new Rect(25, 25, 400, 25), "Slope: " + m_mountainSlope);
    38.         GUI.Label(new Rect(25, 50, 400, 25), "Angle: " + m_mountainAngle);
    39.         GUI.Label(new Rect(25, 75, 400, 25), "Snowboard Velocity: " + m_forwardVelocity);
    40.         GUI.Label(new Rect(25, 100, 400, 25), "Offset: " + m_offset);
    41.         GUI.Label(new Rect(25, 125, 400, 25), "Position: " + m_snowboardPosition);
    42.         GUI.Label(new Rect(25, 150, 400, 25), "Heading: " + m_heading);
    43.         GUI.Label(new Rect(25, 175, 400, 25), "Turn: " + m_turnAngle);
    44.     }
    45.  
    46.     void Reset()
    47.     {
    48.         m_verticalNudge = 0.025f;
    49.         m_minForwardVelocity = 0.5f;
    50.         m_maxForwardVelocity = 20.0f;
    51.         m_maxAccelerationOnGround = 5.0f;
    52.         m_forwardFriction = 0.25f;
    53.         m_slopeAccelerationDivisor = 10.0f;
    54.         m_turnRate = 30.0f;
    55.         m_leanFactor = 1.0f;
    56.     }
    57.  
    58.     void Start()
    59.     {
    60.         m_forwardVelocity = 0.0f;
    61.         m_heading = 0.0f;
    62.         m_myTransform = transform;
    63.         m_rearEmitter.particleEmitter.emit = true;
    64.     }
    65.  
    66.     public void Turn(float angle)
    67.     {
    68.         m_turnAngle = angle * m_turnRate;
    69.     }
    70.  
    71.     void Update()
    72.     {
    73.         // calculate the slope of the snowboard
    74.         // sample either end of the snowboard and determine the slope of the line, use that slope to angle the snowboard
    75.  
    76.         // calculate the slope of the mountain
    77.         // sample the four corners of the snowboard and determine the slope based on the normal of the polygon, use that normal to calculate the acceleration and the lean of the snowboard
    78.         Quaternion myRot = m_myTransform.rotation;
    79.         Quaternion currentHeadingRotation = Quaternion.AngleAxis(myRot.eulerAngles.y, Vector3.up);
    80.  
    81.         Vector3 ray = Vector3.down; //transform.TransformDirection(Vector3.down);
    82.         Vector3 frontEndOfSnowboard = m_myTransform.position + (currentHeadingRotation * new Vector3(0.0f, HeightOfRider, -HalfSnowboardLength));
    83.         Vector3 backEndOfSnowboard = m_myTransform.position + (currentHeadingRotation * new Vector3(0.0f, HeightOfRider, HalfSnowboardLength));
    84.         Vector3 middleOfSnowboard = m_myTransform.position + new Vector3(0.0f, HeightOfRider, 0.0f);
    85.         RaycastHit m_raycastFront;
    86.         Physics.Raycast(frontEndOfSnowboard, ray, out m_raycastFront);
    87.         RaycastHit m_raycastBack;
    88.         Physics.Raycast(backEndOfSnowboard, ray, out m_raycastBack);
    89.         RaycastHit m_raycastMiddle;
    90.         Physics.Raycast(middleOfSnowboard, ray, out m_raycastMiddle);
    91.  
    92.         float mountainSlope = (m_raycastBack.point.y - m_raycastFront.point.y) / LengthOfSnowboard;
    93.         m_mountainSlope = mountainSlope;
    94.         float mountainAngle = Mathf.Atan(mountainSlope) * Mathf.Rad2Deg;
    95.         m_mountainAngle = mountainAngle;
    96.  
    97.         // calculate acceleration and forward velocity based on slope of mountain
    98.         float accelerationFromAngle = mountainAngle / m_slopeAccelerationDivisor;
    99.         //float acceleration = Mathf.Min(mountainAngle / m_slopeAccelerationDivisor, m_maxAccelerationOnGround);
    100.         m_forwardVelocity += accelerationFromAngle * Time.deltaTime;
    101.         m_forwardVelocity = Mathf.Clamp(m_forwardVelocity, m_minForwardVelocity, m_maxForwardVelocity);
    102.         m_forwardVelocity -= m_forwardFriction * Time.deltaTime;
    103.  
    104.         // calculate new heading from amount of turn
    105.         m_heading += m_turnAngle * Time.deltaTime;
    106.  
    107.         // calculate rotation based on slope of mountain and snowboard heading and turn amount
    108.         Quaternion pitchQuat = Quaternion.AngleAxis(m_mountainAngle, Vector3.left);
    109.  
    110.         Quaternion yawQuat = Quaternion.AngleAxis(m_heading, Vector3.up);
    111.  
    112.         Quaternion rollQuat = Quaternion.AngleAxis(m_turnAngle * m_leanFactor, Vector3.forward);
    113.  
    114.         m_myTransform.rotation = yawQuat * pitchQuat * rollQuat;
    115.  
    116.         // update position based on forward velocity
    117.         Vector3 pos = m_myTransform.position;
    118.  
    119.         // my horizontal position updates based on my heading and my velocity
    120.         Vector3 forwardVelocity = Vector3.forward * -m_forwardVelocity * Time.deltaTime;
    121.         Vector3 headingOffset = yawQuat * forwardVelocity;
    122.         m_offset = headingOffset;
    123.         pos += headingOffset;
    124.         pos.y = m_raycastMiddle.point.y + m_verticalNudge;
    125.         m_myTransform.position = pos;
    126.         m_snowboardPosition = pos;
    127.     }
    128.  
    129. }
    P.S. Excuse the crappy code, still fighting a huge head cold that has now progressed to my lungs. :(
     
  5. JulienB

    JulienB

    Guest

    WOah !! Thanks a lot for that BIG help ! I am studying all this right now :) !! This will really improve my understanding.

    I did start my own snowboard, but it is nothing like yours... Time to do my homeworks !!!

    I hope you take some rest and recover from your cold !
     
    Last edited by a moderator: Dec 3, 2011
  6. dev01

    dev01

    Joined:
    May 3, 2010
    Posts:
    21
    the problem is my player bounces all the time
    can you give me instructions for using this script in unity

    1 setup
    2 linking script
    3 objects and names I'll need for it to work


    Can this be applied to joystick?
    maybe you could send me a scene file or something just to understand how you got this incredible scene going...
     
  7. Muktan

    Muktan

    Joined:
    Dec 4, 2012
    Posts:
    55
    yo dude did u find the solution for this ?
     
  8. justinlloyd

    justinlloyd

    Joined:
    Aug 5, 2010
    Posts:
    1,680
    Packaged up for use.
     

    Attached Files:

  9. Muktan

    Muktan

    Joined:
    Dec 4, 2012
    Posts:
    55
    tks a lot dude
     
  10. dev01

    dev01

    Joined:
    May 3, 2010
    Posts:
    21
    Can this type of motion be transferred to work with meshes and not terrain?
    I can't covert my curling wave to a terrain so... Or can someone modify the scripts basic movement for me? I'm no coder but love this !
     
  11. justinlloyd

    justinlloyd

    Joined:
    Aug 5, 2010
    Posts:
    1,680
    Yes it could be used on meshes representing waves. The exact same principle applies. I used the same techniques on 420 Big Wave Surfing on the PS2 and also on Transworld Surf on XBOX/PS2 that I used on various snowboarding games. The geometry changes shape in a surfing game so you have a few edge cases you need to account for that you do not in snowboarding games like SSX.
     
  12. dev01

    dev01

    Joined:
    May 3, 2010
    Posts:
    21
    So if I drop in mesh static wave it should work fine? How do I account for edges?
     
  13. dev01

    dev01

    Joined:
    May 3, 2010
    Posts:
    21
    How do I set an animation to play based on left or right with your script? I was also wondering how to perform a aerial jump and increase the turn if not grounded.(based on your script)
     
  14. justinlloyd

    justinlloyd

    Joined:
    Aug 5, 2010
    Posts:
    1,680
    I think you misunderstand. This script was just a quick hack to demonstrate a principle. The work I did on the surfing games, whilst using similar techniques, was somewhat different, accounting for edges, barrels, and a whole bunch of other stuff.

    This script is not a drop-in and twiddle a few numbers type of script. You are going to have to put some effort in to making the script achieve those features you are seeking.
     
  15. dev01

    dev01

    Joined:
    May 3, 2010
    Posts:
    21
    I've studied this code but can't seem to add a rigidbody to it because it floats up and bounces all over... I would really like to create a physics jump for this so it travels with a current forward velocity
    Any help would be great. Please