When you hit the V key, the camera smoothly and slowly moves from a first person view(fpv) to a third person view(tpv).
I want to be able to control the smoothness of the movement, and length of time it takes to go from point A to point B.
Here’s my code, so far I have the camera moving from fpvPoint to tpvPoint just fine, but it snaps instantly into position with no smooth/slow transition at all.
I’ve been stuck on this for four days now so if you’ve any idea let me know, I’ve tried many different methods.
if (Input.GetButtonDown ("View"))
{
//Toggle First/Third Person View Positions
fpCam = !fpCam;
}
var smooth : float = 10.0;
var vel : float = 0.00;
if (Input.GetButtonDown ("View"))
{
//If First Person View = True, then move camera from FPVPoint and resolve crosshairs
if (fpCam == true)
{
var moveCamFromX = Mathf.SmoothDamp(fpvPoint.transform.position.x, tpvPoint.transform.position.x, vel, smooth);
var moveCamFromY = Mathf.SmoothDamp(fpvPoint.transform.position.y, tpvPoint.transform.position.y, vel, smooth);
var moveCamFromZ = Mathf.SmoothDamp(fpvPoint.transform.position.z, tpvPoint.transform.position.z, vel, smooth);
fpCamera.transform.position.x = moveCamFromX;
fpCamera.transform.position.y = moveCamFromY;
fpCamera.transform.position.z = moveCamFromZ;
fpcrosshair.active = false;
tpcrosshair.active = true;
}
//If First Person View = False, then move camera to FPVPoint and resolve crosshairs
else
{
var moveCamToX = Mathf.SmoothDamp(tpvPoint.transform.position.x, fpvPoint.transform.position.x, vel, smooth);
var moveCamToY = Mathf.SmoothDamp(tpvPoint.transform.position.y, fpvPoint.transform.position.y, vel, smooth);
var moveCamToZ = Mathf.SmoothDamp(tpvPoint.transform.position.z, fpvPoint.transform.position.z, vel, smooth);
fpCamera.transform.position.x = moveCamToX;
fpCamera.transform.position.y = moveCamToY;
fpCamera.transform.position.z = moveCamToZ;
tpcrosshair.active = false;
fpcrosshair.active = true;
}
}
A simple one I did was to use some trigonometry like Sin or Cos to calculate values from one side of a curve to another, then scale it to fit into a 0 to 1.0 range, then multiply that by the position along a straight line between the two points. Thus it starts out very smoothly, speeds up, slows down, and ends smoothly.
Some code (untested, but based on something I did in 2D in another language):
EndX=StartX+((EndX-StartX)*((Cos((TweenPosition*180)+181))+1.0)/2.0) 'Return the tweened X coordinate
EndY=StartY+((EndY-StartY)*((Cos((TweenPosition*180)+181))+1.0)/2.0) 'Return the tweened Y coordinate
EndZ=StartZ+((EndZ-StartZ)*((Cos((TweenPosition*180)+181))+1.0)/2.0) 'Return the tweened Z coordinate
Use the same start and end coords each time and just modify TweenPosition 0…1 which you can increment with equal-sized steps each frame. The above code is from the BlitzMax basic language. Once you’ve calculated EndX,EndY you need to set your camera’s transform.position to it.
If you need to transition between two rotations of the camera, you could use similar code and use rotation degrees for Start and End variables.
Cos is the Cosine function, not sure what Unity’s syntax is, maybe like Mathf.Cos or something?
You don’t want to fire a moveTo in an Update loop. Will moveToUpdate work for you? If not set a variable to false when you fire that iTween that won’t allow it to refire that iTween until iTween can fire an onComplete callback that will reset the variable to true. Vague I know but I hope it helps some.
Thanks for your reply! Great to see you guys are active on the forums :]
I’m going to try your method, but to be honest I’m not experienced with callbacks, nor do I really know what function types to use, and when. I’m still quite new to this.
Ok, got it to work, iTween really is awesome, the results are better than I had hoped for.
If you drop this script on a cube with a transform of 0,0,0 and setup the input for the “View” button (I have it mapped to V), when you hit the View key the cube will smoothly move up 1 unit, and when you hit it again it will smoothly move down one unit.
private var moveCube : boolean;
moveCube = false;
function Update()
{
if (Input.GetButtonDown ("View"))
{
moveCube = !moveCube;
}
if (moveCube == true)
{
if (Input.GetButtonDown ("View"))
{
iTween.moveTo(this.gameObject, {"y" : 1.0});
}
}
else
{
if (Input.GetButtonDown ("View"))
{
iTween.moveTo(this.gameObject, {"y" : 0.0});
}
}
}
The way to do this without the help of the iTween library is not as straight forward as I would have hoped, but does use the Lerp function.
For simplification, I’ll use the Mathf.Lerp function to demonstrate.
float result;
float t = 0.0F;
float speed = 30.0F;
public void Update(){
t += Time.deltaTime;
result = Mathf.Lerp( 0, 100, t / speed );
}
This will increment result from 0 to 100 over 30 seconds. The same method can be used for the Vector3.Lerp, replacing the appropriate values with Vector3’s instead of floats.