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

Question Adding Spin to a Ball

Discussion in 'Physics' started by UnityGuy1988, Aug 13, 2023.

  1. UnityGuy1988

    UnityGuy1988

    Joined:
    Jan 12, 2020
    Posts:
    24
    I would like to have my character be able to move a ball in-game, and was hoping to add the ability to impart spin on the ball. I have two questions:

    1. If the ball is free to move about in game, and I want to be able to add spin to it through the player's interaction, how do I define the necessary axis of rotation for the ball? Bearing in mind as the ball moves freely through the world its local axes will be rotating any which way and could be in any state of orientation. Is it possible to create a temporary axis for when the player causes the rotation (or spin) to occur, or can it only be done in relation to the standard X, Y & Z axes?
    2. If I apply spin to the ball (presumably the best way to do this is with 'Rigidbody.AddTorque()'), will the game calculate the bend in the trajectory (Magnus effect) on it's own, or is that something you have to add yourself?

    Any help would be much appreciated, cheers!
     
  2. Maeslezo

    Maeslezo

    Joined:
    Jun 16, 2015
    Posts:
    282
    About number 1, you have AddTorque and AddRelativeTorque.
    Since you want to add a torque taking the player into account, I'd say you should use AddTorque, which takes a torque vector in world coordinates. The direction of this vector is the rotation axis and the magnitude is the torque itself
    How to calculate this torque vector depends of the actual use case and the complexity of the model you want to design.
    Imagine a tennis racket colliding with the ball. Probably the torque axis direction would be (contact point ball vector)x(raquetVelocity), and the torque magnitude proportional to the racket speed (kind of)

    About number 2, Unity doesn't apply Magnus Effect by itself, you would have to apply it calculating the force by the angular velocity and adding the force to the rigid body
     
    Last edited: Aug 24, 2023
  3. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,611
  4. UnityGuy1988

    UnityGuy1988

    Joined:
    Jan 12, 2020
    Posts:
    24
    Thanks for the info! Since my original post I've managed to achieve something in the way of getting the ball to spin, and using the angular velocity crossed with the velocity I can make the ball swerve too. I've been using an arbitrary figure as scale factor for the Magnus force itself, as I'm struggling to figure out what the correct formula is to use...

    Thanks for the link, one thing that confuses me is the formula for calculating the magnitude of the force: 4/3 * pi * air density * (ball radius)^3 -correct me if I'm wrong, but are these all constants, meaning that the force will always be the same regardless of the spin and velocity? Unless air density in this case changes along with spin and velocity...

    Another thing I've found is that using AddForce() to impart the sideways force on the ball ends up with a cumulative effect that sees the ball gaining in velocity and magnus force and results in it spiralling up and out of the level in a very short space of time. I'm not sure why this is happening, if I use AddForce() on a frame by frame basis (or physics frame), each frame it should impart the appropriate amount of force given the velocity and spin of the ball, or so I thought... maybe 'Forcemode.Force' isn't the right one to use in this case?
     
  5. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,611
    The formula uses the cross product of the linear velocity and the angular velocity,(neither of them normalized) so its magnitude depends on both. If either angular or linear velocity are zero, their cross product (and hence the magnus force) will also be zero. As their magnitudes increase, so does the magnus force.

    The cross product magnitude is then scaled by a constant value, not replaced by it.

    About its cumulative effect, it’s a force (a mass-scaled acceleration) so it will change the speed of the object which has a cumulative effect: it’s how it should work.
     
    Last edited: Aug 29, 2023
  6. UnityGuy1988

    UnityGuy1988

    Joined:
    Jan 12, 2020
    Posts:
    24
    Ah okay, that makes sense, thought I was missing something there with the equation. I was thinking about the force implementation earlier and came to the conclusion that I must have given it too much acceleration, probably better to dial that back I think!
     
  7. avinash_unity236

    avinash_unity236

    Joined:
    Apr 12, 2023
    Posts:
    2
    Hello, I am also working something similar to this. My question is, to launch the ball is it better to calculate the velocity and assign it to the rigidbody,velocity or calculate force and assign to rigidbody.addForce. Which of the assignment will give me the better results? Similarly for the spin rigidbody.angularVelocity or rigidbody.addTorque?
    Any help would be much appreciated. Thank you
     
  8. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    1,611
    F = ma.

    Force equals mass times the change in velocity over time. So assigning the velocity directly ignores mass and ignores time passed since the last physics update, and also ignores the current velocity if any (since you're not adding to the current velocity, but replacing it).

    If you use forces instead, you'll need more force to impart the same acceleration on a heavy object vs a lighter one.

    In other words, using forces you get this:
    Code (CSharp):
    1.  
    2. velocity = velocity + force / mass * timeDelta;
    3.  
    Setting the velocity you get this:
    Code (CSharp):
    1.  
    2. velocity = newVelocity;
    3.  

    So it all depends on what you want to do exactly, there's no better method. They just do different things.
     
    Last edited: Sep 11, 2023
  9. avinash_unity236

    avinash_unity236

    Joined:
    Apr 12, 2023
    Posts:
    2
    Thank for your answer. I was wondering if you can point me in the direction on how to calculate a torque or angular velocity? Given the target direction, initial velocity, launch angle.

    Is there a formula to calculate the force/velocity required for the ball to reach the target location?

    I created a sample project to implement these features but the calculation were not so accurate.
     
  10. Ayla658

    Ayla658

    Joined:
    Sep 5, 2023
    Posts:
    4

    When adding spin to a ball, it's typically done in relation to the ball's local axes. While the ball may move freely through the world and have its local axes change orientation, you can still impart spin relative to its local axes at any given moment. You don't necessarily need to create a temporary axis for this.

    To add spin using `Rigidbody.AddTorque()`, you can provide a torque vector that represents the axis of rotation and the amount of torque to apply. You can use `Transform.TransformDirection` to convert a local direction to world space. Here's a simplified example:


    Code (CSharp):
    1. // Assuming 'rigidbody' is the Rigidbody component of your ball.
    2.    Vector3 localSpinAxis = transform.up; // Spin around the ball's up axis (Y-axis).
    3.    float spinForce = 10f; // Adjust this value to control the spin force.
    4.  
    5.    // Convert localSpinAxis to world space and apply torque.
    6.    Vector3 worldSpinAxis = transform.TransformDirection(localSpinAxis);
    7.    rigidbody.AddTorque(worldSpinAxis * spinForce);
    This code spins the ball around its local up axis (Y-axis). You can adjust the `localSpinAxis` and `spinForce` values to control the direction and intensity of the spin.
     
  11. UnityGuy1988

    UnityGuy1988

    Joined:
    Jan 12, 2020
    Posts:
    24
    Thanks for this, I've already done something similar to get the result I was looking for!
     
  12. itskhokhar

    itskhokhar

    Joined:
    Sep 22, 2023
    Posts:
    1
    To impart spin on a ball in a game and address your two questions:

    1. Defining the Axis of Rotation: You can indeed define a temporary axis for when the player imparts rotation or spin on the ball. This is often necessary in real-time simulations where the ball's local axes may be constantly changing due to its movement. You can create an axis by using a Quaternion or a Vector3 in Unity (assuming you're using Unity as your game engine). You can calculate this axis based on the player's input or desired effect.

    2. Simulating the Magnus Effect: The Magnus effect, which causes the trajectory of a spinning ball to bend, is not typically simulated automatically by game engines like Unity. You would need to implement this effect yourself. To do this, you'll need to apply forces to the ball based on its spin. The Magnus effect depends on various factors like the spin rate, ball speed, and ball size. You can use physics equations to calculate the forces to apply. You'll need to experiment and fine-tune these forces to achieve the desired effect realistically.
    In summary, you can define a temporary axis for ball rotation in relation to the player's interaction, and you'll need to manually simulate the Magnus effect by applying forces to the ball based on its spin to make the trajectory bend realistically in your game.

    using UnityEngine;

    public class BallController : MonoBehaviour
    {
    // Adjust these variables to control the spin and Magnus effect.
    public float spinForce = 100.0f; // The force to apply for spin.
    public float magnusCoefficient = 0.1f; // Coefficient for Magnus effect.
    public Vector3 initialSpinAxis = Vector3.right; // Initial spin axis (can be adjusted).

    private Rigidbody rb;

    private void Start()
    {
    rb = GetComponent<Rigidbody>();
    }

    private void FixedUpdate()
    {
    // Check for player input (e.g., when a key is pressed).
    float spinInput = Input.GetAxis("Spin"); // You can set up this input in Unity's Input Manager.

    // Apply spin torque to the ball based on player input.
    Vector3 spinTorque = initialSpinAxis * spinInput * spinForce;
    rb.AddTorque(spinTorque);

    // Calculate and apply the Magnus effect.
    Vector3 velocity = rb.velocity;
    Vector3 angularVelocity = rb.angularVelocity;

    Vector3 magnusForce = Vector3.Cross(angularVelocity, velocity) * magnusCoefficient;
    rb.AddForce(magnusForce);
    }
    }
     
    Ayla658 likes this.
  13. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    10,329
    If you're going to use AI for a reply then please state that you've used it as per the guidelines (1m).

    If you're going to post code, please use code-tags.

    Thanks.