This question already has answers here:
Rotate GameObject over time
(2 answers)
Closed last month.
I count the angle at which the drone needs to turn so that it looks at the player. I figured it out, but the drone can change its targets and during the target change it abruptly changes its rotation. How can this transition be made smooth?
var finalAngle = Vector3.Angle(targetPosition - _droneTransform.localPosition, _droneTransform.forward);
_droneTransform.localEulerAngles = new Vector3(_finalPitch, finalAngle, _finalRoll);
You can use Vector3.RotateTowards()
https://docs.unity3d.com/ScriptReference/Vector3.RotateTowards.html
In this scenario to prevent the issue of Gimbal Lock I'd suggest pre calculation the quaternion rotations and use Quaternion.RotateTowards()
https://docs.unity3d.com/ScriptReference/Quaternion.RotateTowards.html
Precalculate the rotations using Quaternion.Euler()
https://docs.unity3d.com/ScriptReference/Quaternion.Euler.html
The quickest way to get a rotation that looks at a target is by using Quaternion.LookRotation()
https://docs.unity3d.com/ScriptReference/Quaternion.LookRotation.html
Related
This question already has answers here:
Unity3d - eulerAngles (local and global) totally different than what's in inspector
(2 answers)
Closed 5 years ago.
What i know about unity rotation is that, it show euler angle on inspector while behind the scene it use Quaternion. But I am surprised that my local euler angle and inspector rotation y are not same when my inspector value change from a positive number to a negative number. Why
I am using this
transform.localEulerAngles.y
to get local euler angles.
I noticed that it increasing in positive
like:
Inspector : Code LocalEulerAngle
97.04301: 97.04301 //matched
158.659: 158.659 //matched
-179.094 : 180.9064 //not matched
-170.812 : 189.1875 //not matched
Unity, and every popular game engine for that matter, uses Quaternions for all sorts of rotational representation and computation. Using Euler angles, you often run into issues like Gimbal lock and hence they are never used internally.
What you see in the inspector is for your own understanding and visualization. Quaternions are difficult (I so mean it!) to grasp so they are always hidden from the not-so-mathematical-genius common user. The values retrieved in code are quaternions represented as Euler, whereas the inspector values are, well, inspector values.
localEulerAngles use values between 0 and 360, as briefly stated in the documentation. They are mostly informative.
I am creating a 2D platformer game, and I already wrote the script that moves the sprite forwards and backwards successfully. However, I am extremely new to Unity and C#, so I have no idea how to freeze rotation of the sprite.
I tried to do it programatically (because the use gravity option did not appear in inspector) like so-
void Update () {
anim.SetBool("Grounded", grounded);
anim.SetFloat("Speed", Mathf.Abs(Input.GetAxis("Horizontal")));
rb2d.freezeRotation.freezeRotation = true;
}
but it obviously doesn't work. How do I correctly freeze rotation of the sprite with c#? Where do I put this code?
Thanks in advance-
George :)
What you could do to constraint the rotation on one axis of your object is:
Create a variable float freezeRotationX = 5.0f; //5.0 is just an example
And write this transfrom.rotation = Quaternion.Euler(freezeRotationX, transfrom.rotation.y, transfrom.rotation.z); This line should be in the Update methode.
This will fix the rotation on the X axis and leave the other ones with their current value.
Of course you can create a variable for each axis.
Hope that helps you.
This is very simple, you really don't have to use C#, you can just set the angular velocity of a rigidbody2D really high, but if that doesn't work, try constantly setting the transforms rotations to 0, (the code would look like this in the update function,
getcomponent<yourgameobject>().transform.rotation.z = 0
getcomponent<yourgameobject>().transform.rotation.x = 0
getcomponent<yourgameobject>().transform.rotation.y = 0
the syntax probably isn't correct, and it might slow down the game, but if your beginning unity it is a simple solution.
I am building a game that at one point relies on raw gyrometer readings. I am getting the readings using the following code (I'm using C#):
void Start () {
Input.gyrometer.enabled = true;
}
void Update() {
_guiText = Input.gyrometer.attitude.eulerAngles.ToString();
}
I'm displaying the values on screen in the OnGUI() method. As I'm using Unity I'm using a right-handed coordinate system and I've noticed that the Y value from the gyrometer corresponds to the X rotation in Unity.
The problem is that these values jump around massively. For example I can be holding the device at X:90° and rotate slowly through the Y Axis; after a certain point (around the 270° mark) the X will suddenly flip 180°. It means however, that if I start the app while the device is at 270° in the Y the X reading will be completely unusable. The same effect happens in the Z axis.
I have managed to get round this on iOS devices by resetting the gyro readings using the following snippet: Input.gyro.enabled = false; followed by Input.gyro.enabled = true; I use this to get an accurate reading of the device's absolute rotation and then I use rotational changes to get any other device movement. This doesn't work on Android however.
Has anyone come across this before? If so how did you get round it or is a bug that cannot be resolved?
This is because you are reading a conversion of Quaternion. Euler angles in Unity are just a friendly way to get a V3 representation of something that is hard to grasp. It is recommended not to affect eulerAngles directly as well as using them for reference. Instead, think of flat device as one rotation then start getting the angle between default rotation and current rotation and use that value to define your actions.
You can use Quaternion.Angle for that purpose.
I'm inexperienced with UnityScript and C#, and a solution I can study would be greatly appreciated.
The behavior I want is for Pickups to move in random directions on a terrain, changing direction if they encounter a rigid body or static object.
I tried the script "Wander.cs" available here:
http://wiki.unity3d.com/index.php/Wander
However, when played, the script turns the game object on end, and I cannot correct this. Also, objects tend to pool in corners instead of heading away.
There are two possibilities as far as I can understand your query.
I didn't try but hope it helps.
1- With help of parametric equation of circle i.e.
x=v.t.cos(theta)
y=v.t.sin(theta)
In you case:
x=v.t.cos(theta) + xDistance
z=v.t.sin(theta) + zDistance
where xDistance and zDistance are simple initial position value of your body. These value will not be changed after starting movement (during movement until collision occur).
In Update() apply these equations to your body with constant v and theta and increase t (t++ or t+= 0.1f) by time. When body collides, just retain the current translate (position) value. And start movement again, this time change the value of xDistance and zDistance with current value but only once.
2- With help of iTween. Its a free animation script available at Asset Store
You can use iTween.MoveTo to move body to any given direction (You can assign a random direction as well.). And stop and restart movement upon collision.
I currently have a method that checks to see if I go out of bounds either from either the top/bottom/sides. The object itself is a ball, and I have a question about getting the ball bouncing off the edges correctly? How do I go about this?
// The behavior is not quite what I want.
if ( InsideOfBounds )
{
Vector3 mCenter = Ball.getCenter();
Vector3 normalizeV = tempCenter;
normalizeV.Normalize();
mHeroBall.setVelocity(-testSpeed * normalizeV);
}
I can provide you with an example from a Breakout-clone written in XNA:
Ball.cs
Basically, you flip the right component of velocity to make a 'perfect' rebound. If you want, you can add friction or elasticity by multiplying by a coefficient like 0.95 or 1.1 so your ball speed change.
When you update the position of your object (ball), you want to check if the new value is out of bounds (and which bount Top\Bottom or Left\Right). If the it actually out of bounds, flip the correct element in your speed vector.
example: if the ball has passed the left bound then BallSpeed.X = -BallSpeed.X
don't forget to update the ball's position with the new speed and not the old at this point, or it will fly off the screen for the current frame (unless that isn't an issue).