摘要:本文原创,转载请注明出处http://www.cnblogs.com/AdvancePikachu/p/6742796.html
需求:
在游戏的任务编辑场景进行编辑的时候,摄像机需要在多个需要编辑的物体之间来回切换,如果只是用摄像机的移动旋转,对于相对位置较近的物体还好说,当相对位置过远的时候,就需要有一个聚焦的功能,可以很方便的自动把相机聚焦到需要编辑物体的一个相对可设置的位置。
如图:
如果有聚焦功能,就可以很方便的让摄像机在 Cube和Sphere之间聚焦。
public Transform _cube;
// Use this for initialization
void Start () {
_cube = GameObject.Find ("Cube").transform;
ViewSwitch.Instacne.GetRelativePosition (-, , );
} // Update is called once per frame
void Update () {
if(Input.GetKey(KeyCode.Space))
ViewSwitch.Instacne.GetData(this.transform,_cube);
}
一个简单的调用即可达到下图的效果:
废话不多说,上代码:
//===== AdvancePikachu 2017 ========
//文件功能描述;相机聚焦
//创建表示;AdvancePikachu 2017/4/20
//======================================================== using UnityEngine;
using System.Collections; public class ViewSwitch : MonoBehaviour { private static ViewSwitch instance; public static ViewSwitch Instacne {
get {
if (instance == null) {
GameObject go = new GameObject ();
go.name = "ViewSwitch";
instance = go.AddComponent<ViewSwitch> ();
}
return instance;
}
} public float speed = 10f; int method;
bool isBreakSwitch = true;
Transform startTransform;
Transform targetTransform;
Vector3 endPosition;
Quaternion endQuaternion;
Vector3 relativeEulers = new Vector3 (, , );
Vector3 relativePositon = new Vector3 (-, , ); /// <summary>
/// Gets the start transform.
/// </summary>
/// <returns>The start transform.</returns>
/// <param name="start">Start.</param>
Transform GetStartTransform(Transform start){
startTransform = start;
return startTransform;
} /// <summary>
/// Gets the target transform.
/// </summary>
/// <returns>The target transform.</returns>
/// <param name="target">Target.</param>
Transform GetTargetTransform(Transform target){
targetTransform = target;
GetEndPosition ();
GetEndQuaternion ();
return targetTransform;
} /// <summary>
/// Gets the relative position.
/// </summary>
/// <returns>The relative position.</returns>
/// <param name="forword">Forword.</param>
/// <param name="up">Up.</param>
/// <param name="right">Right.</param>
public Vector3 GetRelativePosition(float forword = -50f,float up = 30f,float right = 0f){
relativePositon = new Vector3(forword,up,right);
return relativePositon;
} /// <summary>
/// Gets the relative eulers.
/// </summary>
/// <returns>The relative eulers.</returns>
/// <param name="eulerX">Euler x.</param>
/// <param name="eulerY">Euler y.</param>
/// <param name="eulerZ">Euler z.</param>
public Vector3 GetRelativeEulers(float eulerX=20f,float eulerY=,float eulerZ=){
relativeEulers = new Vector3 (eulerX, eulerY, eulerZ);
return relativeEulers;
} /// <summary>
/// Gets the end position.
/// </summary>
/// <returns>The end position.</returns>
Vector3 GetEndPosition(){
endPosition = targetTransform.position +
targetTransform.forward * relativePositon.x +
targetTransform.up * relativePositon.y +
targetTransform.right * relativePositon.z;
return endPosition;
} /// <summary>
/// Gets the end quaternion.
/// </summary>
/// <returns>The end quaternion.</returns>
Quaternion GetEndQuaternion(){
endQuaternion = Quaternion.Euler (targetTransform.eulerAngles + relativeEulers);
return endQuaternion;
} /// <summary>
/// Gets the data.
/// </summary>
/// <param name="start">Start.</param>
/// <param name="target">Target.</param>
/// <param name="i">The index.</param>
public void GetData(Transform start,Transform target,int i=){
if (target != null)
isBreakSwitch = false;
else {
isBreakSwitch = true;
return;
} GetStartTransform (start);
GetTargetTransform (target);
method = i;
if (i == )
ViewChangeImmediately ();
} /// <summary>
/// Views the change.
/// </summary>
void ViewChange(){
if (!isBreakSwitch) {
startTransform.position = Vector3.Slerp (startTransform.position, endPosition, Time.deltaTime * speed);
startTransform.rotation = Quaternion.Slerp (startTransform.rotation, endQuaternion, Time.deltaTime * speed); if (Vector3.Distance (startTransform.position, endPosition) <= 0.5f &&
Quaternion.Angle (startTransform.rotation, endQuaternion) <= 0.5f) {
Debug.Log ("Camera Arrived at the specified location!");
isBreakSwitch = true;
}
} else
return;
} /// <summary>
/// Views the change immediately.
/// </summary>
void ViewChangeImmediately(){
if (!isBreakSwitch) {
startTransform.position = Vector3.Slerp (startTransform.position, endPosition, Time.time);
startTransform.rotation = Quaternion.Slerp (startTransform.rotation, endQuaternion, Time.time); if (Vector3.Distance (startTransform.position, endPosition) <= 0.5f &&
Quaternion.Angle (startTransform.rotation, endQuaternion) <= 0.5f) {
Debug.Log ("Camera Arrived at the specified location!");
isBreakSwitch = true;
}
} else
return;
} /// <summary>
/// Breaks the switch.
/// </summary>
/// <returns><c>true</c>, if switch was broken, <c>false</c> otherwise.</returns>
/// <param name="isBreak">If set to <c>true</c> is break.</param>
public bool BreakSwitch(bool isBreak=true){
isBreakSwitch = isBreak;
return isBreakSwitch;
} void Update () {
if (method == )
ViewChange ();
}
}
我写了两个聚焦的方法,一个是立即聚焦,一个是有时间差的聚焦,大家可以自行选择需要的。
这里我把此脚本做成了单例,由于对单例的理解还比较浅显,所以看起来比较简单,如果各位道友有更好的单例方法,请多多指点,小弟谢过!!!