0
\$\begingroup\$

When I load my scene, my character rotates +90 and -90 on the X axis very fast about 4 or 5 times, and then he stops at -90 on X axis (lays back down).

When I move the character, the rotations are just the way I want them, but I need to fix that weird bug at the beginning of the game.

Here's my character's movement logic. It's based on the rotation of the camera, which is a child of my character object.

void Update() {
    Vector2 vec = new Vector2(horizontal, vertical);
    vec = Vector2.ClampMagnitude(vec, 1);

    Vector3 camF = cam.transform.forward;
    Vector3 camR = cam.transform.right;

    camF.y = 0;
    camR.y = 0;
    camF = camF.normalized;
    camR = camR.normalized;

    transform.position += (camF * vec.y + camR * vec.x) * Time.deltaTime * MoveSpeed;

    Vector3 deltaPosition = transform.position - prevPosition;

    if (deltaPosition != Vector3.zero)
    {
        transform.forward = deltaPosition;
    }

    prevPosition = transform.position;
}

Scene

\$\endgroup\$
1
\$\begingroup\$

"camera is child object of my character"

Yup, there's your problem. Let's walk through what happens:

  1. We use the camera's forward to compute a new position for the character

  2. We use the new position to compute a new forward direction for the character

  3. The camera is a child of the character, so rotating the character changes the camera's forward

  4. But back in point 1, our calculation was based on the camera's forward!

    So now the next time we do that calculation, with a different forward, we get a different result...

  5. ...which computes a different forward direction for the character

  6. ...which changes the forward direction of the camera...

...so on and so on in a feedback loop, which creates the flickering rotation that you observe.

So, easy fix: don't make your camera a child of the character if you intend to use the camera to set the character's rotation. This avoids unintended feedback between the two sets of transformation logic.

You'll also want to ensure that your prevPosition is initialized and your horizontal and vertical inputs are populated correctly (we can't see that part of your code - don't hide so much from us if you want deep & useful help!), and you may also want to add a larger tolerance on the if (deltaPosition != Vector3.zero) line - possibly comparing deltaPosition.sqrMagnitude > 0.1 * Time.deltaTime * Time.deltaTime or somesuch.

\$\endgroup\$
  • \$\begingroup\$ I did not understand why did you want me to wrote Time.deltaTime two times. But i did what exactly what you asked me to do, it works better but now character just stays -90 on x axis, but not flipping. \$\endgroup\$ – AmonRa's Channel Apr 20 at 18:00
  • \$\begingroup\$ We multiply by deltaTime twice because deltaPosition already includes deltaTime, and we're taking its sqrMagnitude, which squares the deltaTime inside it. It sounds like you might want to calculate your rotation differently, since you're moving on the xy plane, but forward points along the local z axis. \$\endgroup\$ – DMGregory Apr 20 at 18:07
  • \$\begingroup\$ So how can i do that? \$\endgroup\$ – AmonRa's Channel Apr 21 at 12:31
  • \$\begingroup\$ Hard to say, since I've never seen your character or how it's supposed to be oriented in your world. Try editing your question to include a screenshot showing 3 things: 1) your character in your scene, 2) the local translation gizmo drawn on that character, so we can see which way its local axes point relative to its visuals, 3) the scene compass in the corner of the window, so we can compare this local orientation against the world coordinate axes. \$\endgroup\$ – DMGregory Apr 21 at 13:51
  • \$\begingroup\$ I've added the screenshot \$\endgroup\$ – AmonRa's Channel Apr 21 at 14:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.