0

enter image description here enter image description here

I want to acheive the same rotation you see in the inspector. In short: a smooth local Y rotation, toward a target

I have a Vector3 orientation: Vector3 dirOrientation = targetToLook.position - movingCamera.position;

So, every Update, what should I do ? I try many thing, but I don't realy understand Quaternion...

I just want to rotate localy in Y, toward a precise moving target, NOT in X or Z. and smoothly with some Lerp or Slerp.

Thanks !

Ugo Hed
  • 281
  • 2
  • 21

1 Answers1

1

Using the trick discussed in a similar question here and also here, we can define a helper method to point our local Y axis exactly in a particular direction, while turning our local Z axis to face (as close as possible) toward another direction.

Quaternion TurretLookRotation(Vector3 approximateForward, Vector3 exactUp)
{
    Quaternion rotateZToUp = Quaternion.LookRotation(exactUp, -approximateForward);
    Quaternion rotateYToZ = Quaternion.Euler(90f, 0f, 0f);

    return rotateZToUp * rotateYToZ;
}

Now we can use that in Update to face toward our target:

void Update() {
    // Form the direction we want to look towards
    Vector3 offsetToTarget = target.position - transform.position;

    // Preserve our current up direction
    // (or you could calculate this as the direction away from the planet's center)
    Vector3 up = transform.up;

    // Form a rotation facing the desired direction while keeping our
    // local up vector exactly matching the current up direction.
    Quaternion desiredOrientation = TurretLookRotation(offsetToTarget, up);

    // Move toward that rotation at a controlled, even speed regardless of framerate.
    transform.rotation = Quaternion.RotateTowards(
                            transform.rotation,
                            desiredOrientation,
                            maxDegreesPerSecond * Time.deltaTime
                         );

}
Ugo Hed
  • 281
  • 2
  • 21
DMGregory
  • 134,153
  • 22
  • 242
  • 357
  • Hello, your methode create a brutal flip upside/down when we are at an extreme angle, do you have any way of resolve this ? thanks – Ugo Hed Feb 02 '19 at 16:51
  • 1
    I'll need more details to diagnose the problem. Please provide a reproducible test case and a detailed description of how the specific symptoms you're observing differ from your desired behaviour. – DMGregory Feb 02 '19 at 17:04
  • https://www.youtube.com/watch?v=ENJ9X9Lobk8&feature=youtu.be It's the rotation up/down of the player: when I have a perpendicular normal: the player flip upside/down instant...

    I found something interesting: when I reduce the speed of the rotation, the problem disapear, when I have a fast speed, for non perpendicular case, the movement is smooth and fast, and when i'm perdendicular, the rotation is instant. Weird

    – Ugo Hed Feb 02 '19 at 17:29
  • 1
    I'm unable to reproduce the problem shown in the video using just the code above. The object rotates smoothly no matter how I change the target's position or desired up vector, even at high maxDegreesPerSecond speeds. The sudden snap might be coming from the code you're using to turn the object to match its new surface. I recommend posting a new Question containing a minimal, complete, verifiable example of all the code needed to reproduce the problem. – DMGregory Feb 02 '19 at 18:24
  • Sorry @DMGregory, the probleme was something Else. I have one other question if I May: If I want to get as result a Vector3, it seems like desiredOrientation.eulerAngle is not enought. Any thought? – Ugo Hed Mar 31 '19 at 11:24
  • 1
    No worries. Want to share an answer in case it helps others spot similar issues? To help track down the cause faster in future, it's often useful to create a minimal, complete, verifiable example in a new project, so you can isolate the code/project setup responsible. – DMGregory Mar 31 '19 at 11:27
  • I Have on other question if I May: If I want to get an Vector3 as result, desiredOrientation.eulerAngle doesn't work. I have managed to get my Vectro3 by creating an empty object, named Transform rotateEmpty, and then with my Quaternion desiredOrientation = TurretLookRotation(offsetToTarget, up);, I set to my empty object the desired rotation: rotateEmpty.rotation = desiredOrientation, and then I get my final Vector3 with Vector3 desiredVectorOrientation = rotateEmpty.forward.

    Do you know a way to get this vector without an empty object ? thanks

    – Ugo Hed Mar 31 '19 at 11:46
  • 1
    To share a question, use the "Ask Question" button at the top-right of the site. It looks like what you're describing is equivalent to Vector3 desiredForward = desiredOrientation * Vector3.forward though. – DMGregory Mar 31 '19 at 11:50
  • Thanks ! it's exactly what I wanted. I didn't knew I could multiply quaternion by vector like that. Sorry again for the mess. Next time i will not hesitate to create a separate question. – Ugo Hed Mar 31 '19 at 12:15