在Unity3D中如何让摄像机进行平滑的透视(perspective)和正视(orthographic)角度变换(就像编辑器中点击Gizmos一样的效果)

在Unity3D中如何让摄像机进行平滑的透视(perspective)和正视(orthographic)角度变换(就像编辑器中点击Gizmos一样的效果)

How to make a smooth  animation from orthographic to perspective projection with camera in Unity3D


U3D在Scene场景中编译器里有个XYX左边的Gizmos,点击中间Cube 就可以切换观看GameObject的透视(perspective)和正视(orthographic)角度,如图:

那么,如果我想在代码里动态实现,如何写呢?


(并没有想象的那么简单:在代码中调用camera.Projection的俩个枚举等等。这里面牵扯到一些Matrix矩阵之类的,大家往下看)

Unity Editor has this neat little feature to switch between orthographic and perspective projection with a fluent, natural animation (by clicking on the axis of the viewport cube).

How can I implement this effect in a custom application?

1、首先我设置如下场景,透过按钮点击Gizmos可以看出透视与正视的不同来:



透视(上)



大家注意cube的顶面的梯形上小下大与上大下小的区别!


2、最终结果我么我们期望能用一个按钮来控制俩种状态的切换。整体代码如下:BackupCameraProjectionChange.cs

using UnityEngine;
using System.Collections;

public class BackupCameraProjectionChange: MonoBehaviour
{

	 /// 
	 /// 相机透视改变是否触发(调用只需把此值改为true)
	 /// 
     public bool ChangeProjection = false; 
     private bool _changing = false;
     public float ProjectionChangeTime = 0.5f;
     private float _currentT = 0.0f;
 
     private void Update()
     {///检测,避免变换过程中发生混乱
         if(_changing)
         {
             ChangeProjection = false;
         }
         else if(ChangeProjection)
         {
             _changing = true;
             _currentT = 0.0f;
         }
     }
  /// 
  /// Unity3D中Update和Lateupdate的区别。Lateupdate和Update每一祯都被执行,但是执行顺序不一样,先执行Updatee然后执行lateUpdate。
 ///如果你有两个脚本JS1、JS2,两个脚本中都有Update()函数, 在JS1中有 lateUpdate ,JS2中没有。那么 lateUpdate 函数会等待JS1、JS2两个脚本的Update()函数 都执行完后才执行。
 /// 
     private void LateUpdate()
     {
         if(!_changing)
         {
             return;
         }
         //将当前的 是否正视图值 赋值给currentlyOrthographic变量
         bool currentlyOrthographic = Camera.main.orthographic;
         //定义变量存放当前摄像机的透视和正视矩阵信息;
         Matrix4x4 orthoMat, persMat;
         if(currentlyOrthographic)//如果当前摄像机为正视状态
         {
             orthoMat = Camera.main.projectionMatrix;
 
             Camera.main.orthographic = false;
             Camera.main.ResetProjectionMatrix();
             persMat = Camera.main.projectionMatrix;
         } else//否则当前摄像机为透视状态
         {
             persMat = Camera.main.projectionMatrix;
 
             Camera.main.orthographic = true;
             Camera.main.ResetProjectionMatrix();
             orthoMat = Camera.main.projectionMatrix;
         }
         Camera.main.orthographic = currentlyOrthographic;
 
         _currentT += (Time.deltaTime / ProjectionChangeTime);
         if(_currentT < 1.0f)
         {
             if(currentlyOrthographic)
             {
                 Camera.main.projectionMatrix = MatrixLerp(orthoMat, persMat, _currentT * _currentT);
             }
             else
             {
                 Camera.main.projectionMatrix = MatrixLerp(persMat, orthoMat, Mathf.Sqrt(_currentT));
             }
         }
         else
         {
             _changing = false;
             Camera.main.orthographic = !currentlyOrthographic;
             Camera.main.ResetProjectionMatrix();
         }
     }
 
     private Matrix4x4 MatrixLerp(Matrix4x4 from, Matrix4x4 to, float t)
     {
         t = Mathf.Clamp(t, 0.0f, 1.0f);
         Matrix4x4 newMatrix = new Matrix4x4();
         newMatrix.SetRow(0, Vector4.Lerp(from.GetRow(0), to.GetRow(0), t));
         newMatrix.SetRow(1, Vector4.Lerp(from.GetRow(1), to.GetRow(1), t));
         newMatrix.SetRow(2, Vector4.Lerp(from.GetRow(2), to.GetRow(2), t));
         newMatrix.SetRow(3, Vector4.Lerp(from.GetRow(3), to.GetRow(3), t));
         return newMatrix;
     }
 
    void OnGUI()
    {
        GUILayout.Label("New Camera.main.projectionMatrix:\n" + Camera.main.projectionMatrix.ToString());
        if ( GUILayout.Button("更改CameraProjection") ) {
            ChangeProjection = true;
        }
    }
}


 
  


把脚本附着在游戏物体 MainCamera上,
无需更改数值;直接运行如图:




至此,方法讲解完毕,大家多多揣摩。多多提出意见和建议。
喜欢音乐,热爱生活,哈喽,大家好,我是阿祥。



亲爱的,有个省钱利器我必须告诉你,能省很多Money! 点击下方文字即可打开

淘宝购物返现网


亲爱的,有个省钱利器我必须告诉你,能省很多Money! 点击下方文字即可打开

淘宝购物返现网

你可能感兴趣的:(总结笔记)