Tween code for RotateAround to a Vector3

Still pretty new to Unity and Quaternion math but I think I can explain this. I created the attached image to help.

I have this pillar located at 0,0,0 and a camera that orbits around at a fixed distance and is always looking at the center of the pillar. What I want is to be able click on tiles A or C and have the camera (no matter is current position) tween to points B or D respectively. But it must travel in an arc (the dashed line) so as to remain at that static distance. At the same time the camera must slerp so that its Y axis is pointing straight up while the Z axis looks at the tile’s position.

Here’s what I have so far but no idea how to “tween” along the arc. I hesitate to show this as it may be useless in light of a better solution.

void Update(){
Vector3 relativePos = _activePanel.transform.position - MainCamera.transform.position;
Quaternion rotation = Quaternion.LookRotation(relativePos);

Quaternion current = MainCamera.transform.localRotation;
// this handles the look rotation pretty well
MainCamera.transform.localRotation = Quaternion.Slerp(current, rotation, Time.deltaTime * 3f);
// this section however should be my tween logic
MainCamera.transform.Translate(3 * Time.deltaTime, 0, 0);
}

Thanks!

It's kinda hard to tell from your drawing, so I'll ask: is the camera moving on the y-axis? As far as I can tell, you want the camera to - Face the pillar - Be at the same height as the click - Be in a straight line out from the click Is that correct?

I'm after the same information as Baste. Can you clarify: 1. Does the Camera move in the Y axis? (up and down the pillar) 2. Does the Camera move in the Z axis? (towards and away from the pillar) I'd also suggest taking a look at [Coroutines][1]. Separating your tween logic away from the Update method might help you to better visualize a solution. [1]: http://unity3d.com/learn/tutorials/modules/intermediate/scripting/coroutines

Thanks guys, sorry I didn't clarify that. You're both correct. The camera is intended to move up or down in Y as needed so as to point directly at the center of the tile when complete. (positioned at points B or D) I didn't want to confuse my question by talking about the Z axis as I'm pretty sure I'll be able to extrapolate that functionality once I've covered this problem. I will most likely use Coroutines in the end so if that ends up making it easier to explain to me feel free.

2 Answers

2

I think you’re going about it the wrong way. Instead, imagine the square with the blue line at A, and having it move up and around to B. Then the camera is just along for the ride (it’s glued to the end of the stick, so is always in the correct spot, looking the correct way. If fact, you could possibly just child the camera that way.)

If you simply lerp from A to B, you’ll go inside the pillar, which would slightly reduce cam distance. Plus you can to compute the new angle each time, and might go through the center and snap-flip angles. Instead, I’d think of the movement in 2 parts: up/down and angle.

Say that A to B is currently 60 degrees and 4 meters up. Simple circumference math can tell you the distance for 60 degrees, if you like. But either way, do some rough math – maybe it takes 1 second for each 60 degrees and 2 seconds for 4 meters, so 3 seconds total. I’m assuming you want movement to feel smooth.

Then lerp from 0 to 60 degs, and 0 to 4 meters, both over 3 seconds. At each point, you can compute the exact position and facing of the square from the new angle/ht, as well as the line coming out of it from the center. Place the camera there, looking at the square.

Your solution seems way too complicated. It’s often easier to do less maths and more Unity! I’m assuming that you want to move the camera on the y-axis as well as rotating it around the pillar, to be at height with the click.

If that’s the case, solve your problem like this:

First, set the camera as a child of an empty object that’s in the center of the pillar. The camera should be looking directly at this empty object.

Then, when the player clicks a point on the pillar, you do two things:

  • rotate the camera’s parent to face the click. This will make the camera rotate, at a fixed distance from the pillar.
  • Move the camera’s parent to the same y-coordinate as the click.
  • Both of these things needs to be done over time, with Vector3.MoveTowards and Vector3.RotateTowards. You probably want to time the rotation and y-movement to finish at the same time, so you get a smooth experience.

In this way you’ll get exactly the movement you want, without using any difficult maths that’ll take a bunch of headache.

Remember, whenever you want something in Unity to orbit another object, rotating parent objects is a ton easier than doing the maths. Also, whenever you do anything whatsoever with Quaternions, take a second to figure out if you can do it without Quaternions. That’ll usually be the case, and easier.

I will definitely consider this but I should mention that the camera is bound to a separate orbit system when a tile is not active. That is, I can click and drag to cause the camera to orbit anywhere around the pillar where its center focal point is clamped with the Y axis. That doesn't remove this parented solution but it will mean I have to back track and consider the wide spread impact. IMO it would actually be simpler to devise a way to tween between any two points on a sphere's surface. It has to have been done before.