- Home /
How to smoothly rotate a 2d object with analog stick, to look in the same position as the analog stick?
I have numerous scripts for rotating a 2d object with analog stick, they all work but the rotation is not completely smooth. Its briefly unresponsive on NORTH, SOUTH, EAST, WEST, NORTH-EAST, NORTH-WEST, SOUTH-EAST and SOUTH-WEST. I have researched a lot and tried even more but nothing resolves this issue.
@hexagonius Could you please share how you resolved this issue. Thank you
I never had that issue. Sounds like this would happen with the d-pad, but that wouldn't be smooth at all.
What did you try?
It feels like i have tried everything :). I have managed to make it rotate with Quaternion.LookRotation, AngleAxis, Lerp and Eular, they all have this snapping in those positions. It has to do with deadzones and with the fact that the analog sensitivity is in a square and not a circle. I tried this to deal with deadzones and it didnt help
I have also gotten this script to turn the stick sensitivity into a circle, but when i attach it to the object I want to rotate it does nothing. Am i doing something wrong? I can also send you other scripts, so you can see in detail how i did the rotation. If you can help me please do, I just cant seem to find the right solution.
using UnityEngine; using System.Collections; using System;
public class JoyStick : $$anonymous$$onoBehaviour {
private float dirX = 0F;
private float dirY = 0F;
private Vector2 circlePoint = Vector2.zero;
private float circleRadius = 1;
void Update () {
dirX = Input.GetAxis( "JoyStick_X" );
dirY = -1 * Input.GetAxis( "JoyStick_Y" );
dirX = $$anonymous$$athf.Clamp( dirX, -1, 1 );
dirY = $$anonymous$$athf.Clamp( dirY, -1, 1 );
// $$anonymous$$akes into a single point the joystick values
Vector2 circlePoint = new Vector2( dirX, dirY );
circlePoint = correctCirclePoint( circlePoint ); // Converts it to a circle
circlePoint *= circleRadius; // $$anonymous$$akes it the radius we really need it at the end. Could easily be added at the end of the function with an argument
}
// Returns the "square" value of the joystick mapped to a circle of same radius
private Vector2 correctCirclePoint ( Vector2 point ){
// If the point given is at distance 0 from the center, then we don't need to convert it
if (Vector2.Distance(Vector2.zero, point) > 0) {
float xC = point[0]; // X coordinate of the point
float yC = point[1]; // Y coordinate of the point
float xC2 = $$anonymous$$athf.Pow( xC, 2 ); // Squared value of the X coordinate
float yC2 = $$anonymous$$athf.Pow( yC, 2 ); // Squared value of the Y coordinate
float xCercle = xC * ( $$anonymous$$athf.Sqrt( xC2 + yC2 - ( xC2 * yC2 ) ) / $$anonymous$$athf.Sqrt( xC2 + yC2 ) ); // Conversion of X
float yCercle = yC * ( $$anonymous$$athf.Sqrt( xC2 + yC2 - ( xC2 * yC2 ) ) / $$anonymous$$athf.Sqrt( xC2 + yC2 ) ); // Conversion of Y
return new Vector2( xCercle, yCercle );
}else{
return new Vector2( 0, 0 );
}
}
}
Answer by oStaiko · Jun 24, 2017 at 02:06 AM
By "Smooth" do you want an acceleration/deceleration effect, or just a constant speed effect? constant rotational speed from a to b is easy, but accel/decell is a bit tougher. I think Slerp works well to give the effect, but I'm not entirely sure. Something like this should work:
public MoveToRotation ()
{
Quaternion newDir = Quaternion.identity;
newDir.eulerAngles = new Vector3(0,angle,0);
transform.rotation = Quaternion.Slerp (transform.rotation, newDir, Time.deltaTime * torque);
rb.AddForce (transform.forward * acceleration);
}
This would mean you accel and slow down to get to a new rotation, but it'd probably feel awkward as players are often used to snapping controls, and the delay is a bit awkward. Basically you rotate faster for farther positions, so to get to point B fastest would mean to aim for C and stop early... Not the best, but its smooth for sure.
If all you want is a constant speed rotation, go with Lerp, it's basically the same implementation I think.
All I want is constant speed and for the object to face the same position the analogstick is in (imagine ai$$anonymous$$g in a topdown shooter). So I just replace Slerp with Lerp?
It turns out it was the controllers fault. I plugged in a ps3 controller and the snapping is gone