Real rotating force

Hi!

I’m trying to spin a bottle (I’m calculating the first pos and end pos of the mouse) and apply forces to it according to the ‘swipe’ length/time, just like in real life.
After the initial swipe, the bottle should keep rotating based on the force of the swipe, and then stop after few seconds.
I managed to get it rotating according to the swipe, but not force dependent (it wouldn’t keep spinning afterwards).

Therefore, I hope you could help me here.
Thanks!

It's unlikely to be "real physics" as you won't capture the mass of the body doing the swiping. The swipe motion (as far as your screen is concerned) is just a speed. Your best bet might just be to get the orthogonal swipe speed and then let drag sort everything out on some sort of wheel collider.

–

you talk about force, but it should be torque. what exactly are you doing with the bottle?

–

Hi, Can someone help or give an idea how to achieve that?

–

If you only need to simulate a single bottle spinning on a single axis there's no reason to involve physics, just program it in lerping transform.rotation.y

–

Still looking for a way to do it. no one has an idea?

–

2 Answers

2

EDIT:

I’ve just noticed by “swiping” you mean mouse dragging. Sorry, I always link swiping to touch Input. You can still use my scipt and use the OnMouse methods instead of theTouchPhase statements.

You could determine the velocity of the swipe and relate it to the torque which causes the bottle to rotate. Something like Torque=touchSpeed*coeff. This is of course not a “real Force/Torque)” at all. You can experiment a litte bit to find a optimal value for coeff.
Use the Update - loop to progress your input and the Fixed Update loop to apply your force. Code could look like this (not complete nor tested):

Rigidbody bottle; 
bool isSwiping;
Touch thisTouch;
Vector2 origPos;
float touchSpeed;
Vector3 Torque;
float const minDist = //Put here some miminum value to let the finger movement be accounted for as a swipe

Update()
{
             if (Input.touchCount > 0) //Unity notices an User Touch Input
            {
                thisTouch = Input.GetTouch(0);
                switch (thisTouch.phase)
                {
                    case TouchPhase.Began:
                       origPos=thisTouch.position;
                       break;
                    case TouchPhase.Moved:
                       if((thisTouch.position.magnitude-origPos.magnitude)>minDist)
                       {
                             isSwiping=true;
                             touchSpeed=thisTouch.deltaPosition.magnitude / thisTouch.deltaTime;  
                             Torque=new Vector(touchSpeed*coeff,0,0);
                        }
                      break;
                    case TouchPhase.Ended:
                        isSwiping=false;
                        break;
                    default:
                        isSwiping=false;
                        break;
                }
            }
}

FixedUpdate()
{
if(isSwiping) bottle.AddRelativeTorque(Torque);
}

With this Implementation the bottle starts to rotate as soon as you start swiping (and constantly adds force to the bottle as long as you are swiping), You could also determine the average velocity of the whole swipe in TouchPhase.Ended, then the force is only added once (in that case you should maybe use ForceMode.Impulse). Note that with the latter kind of implementation the bottle only start rotating after the swipe has ended.
Edit: And you need of course some angular Drag. Otherwise the bottle won’t stop rotating

I tried this, but it still doesn’t work well. I can only drag the bottle within the x-axis but it won’t rotate afterwards. Hope you can help me!

    public float rotSpeed = 20; // speed for dragging x-axis only
public float speed = 0.1f; //for rotating
bool rotating = false; // is the bottle rotating?
Quaternion startPos; Quaternion endPos;

void OnMouseDown(){
	startPos = transform.rotation; //start pos
}
void OnMouseDrag(){

	//DRAG THE BOTTLE (ONLY IN X AXIS)
	float rotX = Input.GetAxis ("Mouse X") * rotSpeed * Mathf.Deg2Rad;
	transform.RotateAround (Vector3.up, -rotX);

}

void OnMouseUp(){

	endPos = transform.rotation; //end pos after dragging

	rotating = true;
}
	
void Update() {

	if (rotating) {
		transform.rotation = Quaternion.Lerp (startPos, endPos, Time.deltaTime * speed);
	}
	//TO:DO - end rotating
	//...
}