Search Unity

2D pendulum/rope swinging motion WITHOUT Physics

Discussion in 'Scripting' started by Yandalf, May 4, 2020.

  1. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    Hey everyone!
    I'm looking for a way to program a way for a 2D character to swing on a rope without using Unity's builtin Physics.
    That means no use of Rigidbodies or joints, no forces, nothing like that.
    I've been searching around for a bit and found out about simple harmonic movement, which when used to drive a rotation provides this very nice motion with easing in and out at the ends.
    However, the problem with this solution is that, as far as I've found, there's no easy way to change the angle reach or swinging speed without causing the rotation to jump.
    Does anyone have a better idea to solve this?

    Code (CSharp):
    1.     public Transform myPivotTransform;
    2.     public float MaxAngleDeflection = 30.0f;
    3.     public float SpeedOfPendulum = 1.0f;
    4.  
    5.  
    6.     void Update()
    7.     {
    8.         float angle = MaxAngleDeflection * Mathf.Sin(Time.time * SpeedOfPendulum);
    9.         myPivotTransform.localRotation = Quaternion.Euler(0, 0, angle);
    10.     }
    To reiterate with this code in mind, I need to be able to make a swinging motion that smoothly continues even when SpeedOfPendulum or MaxAngleDeflection changes during runtime.
    Thanks in advance!
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    You can do it with a few minor changes to the above.

    Change 1: have another variable called
    CurrentAngleDeflection
    and have it slowly move towards
    MaxAngleDeflection
    each frame, just somewhere in your Update loop. That way when you change
    MaxAngleDeflection
    , the
    CurrentAngleDeflection
    will gradually move towards that value. Something like this:

    Code (csharp):
    1. CurrentAngleDeflection = Mathf.MoveTowards( CurrentAngleDeflection,
    2.         MaxAngleDeflection,
    3.         RateOfDeflectionChange * Time.deltaTime);
    Change 2: instead of directly using Time.time (which starts at zero when your game launches), do this:

    -- Have your own
    float time;
    class variable
    -- In Update() add to it yourself, like so:

    Code (csharp):
    1. time += SpeedOfPendulum * Time.deltaTime;
    -- In your Mathf.Sin() argument, pass your
    time
    variable in (do not multiply it by anything!!), and multiply the result by
    CurrentAngleDeflection
     
    Bunny83 likes this.
  3. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    Hey Kurt!
    I should've thought of doing gradual changes instead of trying an immediate one. Thanks a bunch!
    I have a feeling I can make this work now :)
     
    Bunny83 and Kurt-Dekker like this.
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    I have confidence in you! GO!
     
    Bunny83 likes this.
  5. SpacePlantStudio

    SpacePlantStudio

    Joined:
    Dec 29, 2020
    Posts:
    2
    I realize I'm about a year late to this conversation, but the information here has been incredibly helpful! I'm a beginner and I'm missing a step in my implementation--perhaps someone might be able to help?

    I'm trying to get a "grapple" mechanic integrated in my own custom physics system in a C# Unity 2D project. I have an invisible Transform child to my Player functioning as a "grapple check."

    Ideally, whenever GetButtonDown("Grapple") is called, I want a few things to happen:
    1. The GrappleCheck transform checks for any objects on the "canGrapple" layer mask.
    2. if a canGrapple item is detected, I want a rope-like line to shoot out from the player and connect to the detected item.

    3. I want the player to maintain their momentum as they are pulled into the pendulum swing of the grappled item and to be able to use that momentum to release the grapple and fling themselves onto platforms etc.

    I have step one down and with the advice listed in the above posts I have a concept for a great system for smooth pendulum motion. However, I'm missing step 2.

    Here's what I have (The actual Input called from a separate "PlayerInput" script):

    Code (CSharp):
    1. public void OnGrappleInputDown()
    2.     {
    3.         if (Physics2D.OverlapCircle(m_GrappleCheck.position, canGrapple))
    4.         {
    5.             Debug.Log("Grapple Go");
    6.          }
    7.     }
    This works great for consistent position-based, conical detection. However, I am at a loss as to how to generate a "rope-like" object to serve as the source for the pendulum motion code. I can't find any tutorials or information for this without using built in physics, rigidbodies and rope systems etc.

    Any ideas would be incredibly helpful! If you need more information from me, please let me know. I'm incredibly green but eager to learn.

    I should say too--I'm an animator, so if I need to do something like animate a full rope cycle of some sort, I can do that if there is no "rope-generating" function in Unity 2D that does not rely on a rigidbody.
     
    Last edited: Feb 19, 2021
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,726
    This is a very multi-layered problem, with a little bit of code and a LOT of scene and prefab and asset setup.

    You're welcome to dabble in it yourself but a better way might be to just do some tutorials and learn from them, then take that knowledge back to influence your own implementation.

    I don't think this approach would be useful, for these reasons:

    - upon connect you would need to back-calculate where in the animation timeline to start.

    - it's trivial to do a constant-radius rotation in code

    - To look good the rate of swing must be at least a bit physics-y, taking into account your incoming speed at the moment of grapple.

    If you have issues, come back and start your own post. Hijacking old threads is explicitly against forum rules.

    When you post, make the new thread, and here is how to report your problem productively in the Unity3D forums:

    http://plbm.com/?p=220

    How to understand compiler and other errors and even fix them yourself:

    https://forum.unity.com/threads/ass...3-syntax-error-expected.1039702/#post-6730855

    If you post a code snippet, ALWAYS USE CODE TAGS:

    How to use code tags: https://forum.unity.com/threads/using-code-tags-properly.143875/
     
    Bunny83 and SpacePlantStudio like this.
  7. SpacePlantStudio

    SpacePlantStudio

    Joined:
    Dec 29, 2020
    Posts:
    2
    Kurt, thank you so much for the informative and speedy response! I apologize for my poor forum etiquette! Thanks very much for the links and the help!
     
    Bunny83 and Kurt-Dekker like this.