Fork me on GitHub

Unity 相机的聚焦功能

摘要:本文原创,转载请注明出处http://www.cnblogs.com/AdvancePikachu/p/6742796.html

需求:

      在游戏的任务编辑场景进行编辑的时候,摄像机需要在多个需要编辑的物体之间来回切换,如果只是用摄像机的移动旋转,对于相对位置较近的物体还好说,当相对位置过远的时候,就需要有一个聚焦的功能,可以很方便的自动把相机聚焦到需要编辑物体的一个相对可设置的位置。

如图:

 如果有聚焦功能,就可以很方便的让摄像机在 Cube和Sphere之间聚焦。

 1 public Transform _cube;
 2     // Use this for initialization
 3     void Start () {
 4         _cube = GameObject.Find ("Cube").transform;
 5         ViewSwitch.Instacne.GetRelativePosition (-10, 1, 0);
 6     }
 7     
 8     // Update is called once per frame
 9     void Update () {
10         if(Input.GetKey(KeyCode.Space))
11             ViewSwitch.Instacne.GetData(this.transform,_cube);
12     }

 

一个简单的调用即可达到下图的效果:

 

 

废话不多说,上代码:

  1 //===== AdvancePikachu 2017 ========
  2 //文件功能描述;相机聚焦
  3 //创建表示;AdvancePikachu 2017/4/20
  4 //========================================================
  5 
  6 using UnityEngine;
  7 using System.Collections;
  8 
  9 public class ViewSwitch : MonoBehaviour {
 10 
 11     private static ViewSwitch instance;
 12 
 13     public static ViewSwitch Instacne {
 14         get {
 15             if (instance == null) {
 16                 GameObject go = new GameObject ();
 17                 go.name = "ViewSwitch";
 18                 instance = go.AddComponent<ViewSwitch> ();
 19             }
 20             return instance;
 21         }
 22     }
 23 
 24     public float speed = 10f;
 25 
 26     int method;
 27     bool isBreakSwitch = true;
 28     Transform startTransform;
 29     Transform targetTransform;
 30     Vector3 endPosition;
 31     Quaternion endQuaternion;
 32     Vector3 relativeEulers = new Vector3 (20, 0, 0);
 33     Vector3 relativePositon = new Vector3 (-50, 30, 0);
 34 
 35     /// <summary>
 36     /// Gets the start transform.
 37     /// </summary>
 38     /// <returns>The start transform.</returns>
 39     /// <param name="start">Start.</param>
 40     Transform GetStartTransform(Transform start){
 41         startTransform = start;
 42         return startTransform;
 43     }
 44 
 45     /// <summary>
 46     /// Gets the target transform.
 47     /// </summary>
 48     /// <returns>The target transform.</returns>
 49     /// <param name="target">Target.</param>
 50     Transform GetTargetTransform(Transform target){
 51         targetTransform = target;
 52         GetEndPosition ();
 53         GetEndQuaternion ();
 54         return targetTransform;
 55     }
 56 
 57     /// <summary>
 58     /// Gets the relative position.
 59     /// </summary>
 60     /// <returns>The relative position.</returns>
 61     /// <param name="forword">Forword.</param>
 62     /// <param name="up">Up.</param>
 63     /// <param name="right">Right.</param>
 64     public Vector3 GetRelativePosition(float forword = -50f,float up = 30f,float right = 0f){
 65         relativePositon = new Vector3(forword,up,right);
 66         return relativePositon;
 67     }
 68 
 69     /// <summary>
 70     /// Gets the relative eulers.
 71     /// </summary>
 72     /// <returns>The relative eulers.</returns>
 73     /// <param name="eulerX">Euler x.</param>
 74     /// <param name="eulerY">Euler y.</param>
 75     /// <param name="eulerZ">Euler z.</param>
 76     public Vector3 GetRelativeEulers(float eulerX=20f,float eulerY=0,float eulerZ=0){
 77         relativeEulers = new Vector3 (eulerX, eulerY, eulerZ);
 78         return relativeEulers;
 79     }
 80 
 81     /// <summary>
 82     /// Gets the end position.
 83     /// </summary>
 84     /// <returns>The end position.</returns>
 85     Vector3 GetEndPosition(){
 86         endPosition = targetTransform.position +
 87         targetTransform.forward * relativePositon.x +
 88         targetTransform.up * relativePositon.y +
 89         targetTransform.right * relativePositon.z;
 90         return endPosition;
 91     }
 92 
 93     /// <summary>
 94     /// Gets the end quaternion.
 95     /// </summary>
 96     /// <returns>The end quaternion.</returns>
 97     Quaternion GetEndQuaternion(){
 98         endQuaternion = Quaternion.Euler (targetTransform.eulerAngles + relativeEulers);
 99         return endQuaternion;
100     }
101 
102     /// <summary>
103     /// Gets the data.
104     /// </summary>
105     /// <param name="start">Start.</param>
106     /// <param name="target">Target.</param>
107     /// <param name="i">The index.</param>
108     public void GetData(Transform start,Transform target,int i=0){
109         if (target != null)
110             isBreakSwitch = false;
111         else {
112             isBreakSwitch = true;
113             return;
114         }
115 
116         GetStartTransform (start);
117         GetTargetTransform (target);
118         method = i;
119         if (i == 1)
120             ViewChangeImmediately ();
121     }
122 
123     /// <summary>
124     /// Views the change.
125     /// </summary>
126     void ViewChange(){
127         if (!isBreakSwitch) {
128             startTransform.position = Vector3.Slerp (startTransform.position, endPosition, Time.deltaTime * speed);
129             startTransform.rotation = Quaternion.Slerp (startTransform.rotation, endQuaternion, Time.deltaTime * speed);
130 
131             if (Vector3.Distance (startTransform.position, endPosition) <= 0.5f &&
132                 Quaternion.Angle (startTransform.rotation, endQuaternion) <= 0.5f) {
133                 Debug.Log ("Camera Arrived at the specified location!");
134                 isBreakSwitch = true;
135             }
136         } else
137             return;
138     }
139 
140     /// <summary>
141     /// Views the change immediately.
142     /// </summary>
143     void ViewChangeImmediately(){
144         if (!isBreakSwitch) {
145             startTransform.position = Vector3.Slerp (startTransform.position, endPosition, Time.time);
146             startTransform.rotation = Quaternion.Slerp (startTransform.rotation, endQuaternion, Time.time);
147 
148             if (Vector3.Distance (startTransform.position, endPosition) <= 0.5f &&
149                 Quaternion.Angle (startTransform.rotation, endQuaternion) <= 0.5f) {
150                 Debug.Log ("Camera Arrived at the specified location!");
151                 isBreakSwitch = true;
152             }
153         } else
154             return;
155     }
156 
157     /// <summary>
158     /// Breaks the switch.
159     /// </summary>
160     /// <returns><c>true</c>, if switch was broken, <c>false</c> otherwise.</returns>
161     /// <param name="isBreak">If set to <c>true</c> is break.</param>
162     public bool BreakSwitch(bool isBreak=true){
163         isBreakSwitch = isBreak;
164         return isBreakSwitch;
165     }
166 
167     void Update () {
168         if (method == 0)
169             ViewChange ();
170     }
171 }
View Code

我写了两个聚焦的方法,一个是立即聚焦,一个是有时间差的聚焦,大家可以自行选择需要的。

这里我把此脚本做成了单例,由于对单例的理解还比较浅显,所以看起来比较简单,如果各位道友有更好的单例方法,请多多指点,小弟谢过!!!

posted @ 2017-04-21 11:35 进击的皮卡丘 阅读(...) 评论(...) 编辑 收藏