Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Simple pendulum movement

Discussion in 'Scripting' started by mrCharli3, Dec 8, 2018.

  1. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    363
    I have a ball at the end of a string, the string is attached to a cube with the following script on it. The ball moves back and forth kind of like a pendulum, but with a constant speed. How can I make it so the speed is more like a pendulum? i.e slow down before changing direction.

    Here is the relevant logik I use, only for the x-axis to keep it short:

    Code (CSharp):
    1.  
    2. void Start()
    3.     {
    4.         _rotateUntil = transform.rotation.eulerAngles * -1; //sets the point of changing direction, i.e if I start at 30 degress, I change dir at -30 degrees.
    5.     }
    6.  
    7. void FixedUpdate()
    8.     {
    9.         transform.Rotate(_dir * Time.deltaTime * _currentSpeed);
    10.         Swing();
    11.     }
    12.  
    13. private void Swing()
    14.     {
    15.         float angle = 0;
    16.         float target = 0;
    17.         angle = (transform.rotation.eulerAngles.x > 180) ? transform.rotation.eulerAngles.x - 360 : transform.rotation.eulerAngles.x;
    18.          target = _rotateUntil.x;
    19.          if (angle <= target)
    20.               ChangeDir();
    21. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    3,563
    What you want is simple harmonic motion:

    https://en.wikipedia.org/wiki/Simple_harmonic_motion

    You can trivially get close to this in Unity by simply using the Mathf.Sin() of a steadily advancing variables, rather than pingponging linearly between to limits.

    I would just put a local pivot into the gameObject hierarchy and drive that directly.

    If you wanted that pivot to swing along the +Z axis, this would be the code:

    Code (csharp):
    1. float MaxAngleDeflection = 30.0f;
    2. float SpeedOfPendulum = 1.0f;
    3.  
    4. float angle = MaxAngleDeflection * Mathf.Sin( Time.time * SpeedOfPendulum);
    5. myPivotTransform.localRotation = Quaternion.Euler( 0, 0, angle);
    Speed of 1.0 implies a period of 2 * pi. Speed of Mathf.PI * 2 would be a period of one second.
     
    mrCharli3 likes this.
  3. mrCharli3

    mrCharli3

    Joined:
    Mar 22, 2017
    Posts:
    363
    I knew there had to be some way that didnt involve over 100 lines of code. This is exactly what I was looking for. You are the best!
     
    Kurt-Dekker likes this.