- Home /
Some lines of codes are ignored once certain "if" statement(s) initiated.
Hello, in the code below i am trying to get my character to move while keeping its rotation same. I have a rotation command at the top of "FixedUpdate()". As i press "Fire2" character moves but its rotation in z axis starts to increase and stops at some point around "7" which means it completely ignores my rotation command. This gets fixed when i put the rotation command to method "update()", which makes zero sense to me. I would be glad if someone explains why this happens.(Rest of the script may be irrelevant but i wanted to put it just in case.)
public Sprite[] idleAnimation;
public Sprite[] jumpingAnimation;
public Sprite[] runAnimation;
public float jumpingVelocity;
public float runningVelocity;
SpriteRenderer mySprite;
Rigidbody2D physics;
int idleAnimNumber=0;
int RunningAnimNumber = 0;
bool idleAnimationControl=true;
bool runningAnimationControl = true;
void Start () {
mySprite = GetComponent<SpriteRenderer>();
physics = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
transform.eulerAngles = new Vector3(0,transform.rotation.y , 0);
physics.velocity = new Vector3(0, physics.velocity.y, 0);
if (Input.GetButton("Fire2"))
{
physics.velocity = new Vector3(runningVelocity, physics.velocity.y, 0);
}
if (idleAnimationControl)
{
mySprite.sprite = idleAnimation[idleAnimNumber];
idleAnimNumber++;
if (idleAnimNumber == 11)
{
idleAnimationControl = false;
}
}
else
{
mySprite.sprite = idleAnimation[idleAnimNumber];
idleAnimNumber--;
if (idleAnimNumber == 0)
{
idleAnimationControl = true;
}
}
if (physics.velocity.x != 0)
{
if (runningAnimationControl)
{
mySprite.sprite = runAnimation[idleAnimNumber];
RunningAnimNumber++;
if (RunningAnimNumber == 17)
{
runningAnimationControl = false;
}
}
else
{
mySprite.sprite = runAnimation[idleAnimNumber];
RunningAnimNumber--;
if (RunningAnimNumber == 0)
{
runningAnimationControl = true;
}
}
}
if (Input.GetButton("Fire1"))
{
if (physics.velocity.y == 0)
{
physics.velocity = new Vector3(physics.velocity.x, jumpingVelocity, 0);
}
}
if (physics.velocity.y > 0)
{
mySprite.sprite = jumpingAnimation[0];
}
else if (physics.velocity.y < 0)
{
mySprite.sprite = jumpingAnimation[1];
}
}
Answer by holistic1 · Aug 06, 2018 at 08:17 PM
transform.eulerAngles = new Vector3(0,transform.rotation.y , 0);
Yes that line was completely wrong and i wasn't aware of that for some reason. What i wanted to do was i wanted to lock x and z component of rotation to "0" and make the y component free. I still don't know how to do this but apparently unity allows me to constrain z component(2D) and i don't even need to change x since there is nothing that affects it. I simply deleted the line and constrained the Z component and it works as it intended to be.
transform.eulerAngles = new Vector3( 0, transform.rotation.eulerAngles.y, 0 );
That might have been what you intended using that approach, as it returns, from the eulerAngles property of Quaternion, a vector from which this version takes the Y axis rotation, leaving X and Z axis at zero.
transform.rotation = Quaternion.Euler(0, transform.rotation.y, 0);
Would it be correct to say that's equivalent of this?
No, it's actually quite worse than the original ;).....
Quaternion.Euler is a static function of Quaternion that can fashion a quaternion from euler angles, so that part is correct. The problem, here, is that transform.rotation.y does not get a euler angle, it is the same error of the original post, taking the y parameter from inside a quaternion, which is not an angle.
transform.rotation = Quaternion.Euler( 0, transform.rotation.eulerAngles.y, 0 );
THAT would be the same effect as I posted, give or take how the rotation is changed. Here, the Quaternion you create from the call to Euler replaces the quaternion in the Transform. The version I posted uses the Transform's property to do something nearly identical, but your code isn't creating the quaternion, the property's code is.
Answer by Bunny83 · Aug 06, 2018 at 06:50 PM
Your "rotation command" simply makes no sense:
transform.eulerAngles = new Vector3(0,transform.rotation.y , 0);
"transform.rotation" is a unit quaternion.which is a 4 dimensional complex number. The members of a unit quaternion are always in the range of -1 to 1. The components are not angles and therefore assinging them to eulerAngles just makes no sense. I have no idea what this line was meant to do. Since you're dealing with a rigidbody, rotating the object through the transform is generally not recommended. Though it depends on the actual usecase.
You should tell us what you "think" this line of code should do, then we can tell you how it can be achieved. Currently this line is the only code here that affects the rotation. Do you have another script that messes with the rotation?
Answer by JVene · Aug 06, 2018 at 06:51 PM
While I could address a lot about this code, I'll focus on this:
transform.eulerAngles = new Vector3(0,transform.rotation.y , 0);
because it relates more directly to your question. This isn't doing what you think it should. The x, y and z values inside the rotation are from the Quaternion named "rotation", and do not represent angles. They are part of the internals of the Quaternion. Read up on the makeup of quaternions in general (Google provides) to gain some understanding of what is inside a Quaternion.
This code is setting the rotation through transform's eulerAngles property, but it requires Euler angles, in degrees, to operate. What comes from transform.rotation.y is not an angle in the Y axis of rotation. It is, in an oversimplified explanation, part of a vector describing the orientation of the quaternion, but it is not an angle. What you require is to obtain the eulerAngles property of the Quaternion, as documented here. You want the y member of that property, which is an angle on the Y axis in degrees, as the transform.eulerAngles property expects. Whether or not that actually does what you require is perhaps more appropriate, but I can't guarantee this is the entire solution to your question.
You would benefit from a deeper review of the difference in usage of Update and FixedUpdate, though I can't really tell if your usage of FixedUpdate is entirely correct (or if it isn't). FixedUpdate is associated with the cycle of the physics engine. Update is associated with the frame flip.
When operating objects that use physics, FixedUpdate is appropriate, but when you control the object directly in code it can cause more problems than it seems to solve. It is usually more appropriate to use forces in FixedUpdate to act upon physics controlled objects, but that is beyond the scope of your initial question except that controlling rotation is one of those things that can contradict the physics engine's own calculations, causing confusion about what is really happening to the object. Usually, one chooses either to control an object with physics (and thus forces), or to disable physics on that object and control it in code more directly (by altering rotation and position in code). It is not unknown to do what you're doing here, but the results can be puzzling if you're not familiar with ho the interactions cause the results you're seeing.