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 }
我写了两个聚焦的方法,一个是立即聚焦,一个是有时间差的聚焦,大家可以自行选择需要的。
这里我把此脚本做成了单例,由于对单例的理解还比较浅显,所以看起来比较简单,如果各位道友有更好的单例方法,请多多指点,小弟谢过!!!
你有什么资格不努力!——进击的皮卡丘