Unity視角轉動之攝像機環繞效果
阿新 • • 發佈:2019-01-27
using UnityEngine;
using System.Collections;
public class CameraLookAt : MonoBehaviour
{
public Transform 目標模型;
[Tooltip("x:最小;y:最大")]
public Vector2 距離範圍 = new Vector2(0.1f, 5f);
[Range(0f, 1f)]
public static float 距離滑動條值 = 0.5f;
public float 左右旋轉速度 = 2f;
public float 上下旋轉速度 = 2f;
[Tooltip("x:最小;y:最大")]
public Vector2 上下旋轉限制 = new Vector2(-20f,80f);
public float 移動延遲 = 4f;
#region MonoBehaviour
public void Start()
{
if (!目標模型)
{
目標模型 = new GameObject("目標模型").transform;
}
位置初始化();
Now距離滑動條值 = 距離滑動條值;
重置位置();
}
public static float mouseX = 0.0f;
public static float mouseY = 0.0f;
Vector2 oldPosition1;
Vector2 oldPosition2;
void Update()
{
if (Input.GetKey (KeyCode.Y)) {
距離滑動條值 -= Time.deltaTime * 0.5f;
距離滑動條值 = Mathf.Clamp(距離滑動條值, 0, 1);
}
if (Input.GetKey (KeyCode.H)) {
距離滑動條值 += Time.deltaTime * 0.5f;
距離滑動條值 = Mathf.Clamp(距離滑動條值, 0, 1);
}
if(Input.GetKey(KeyCode.A)){
mouseY += 0.8f;
}
if(Input.GetKey(KeyCode.D)){
mouseY -= 0.8f;
}
if (Input.GetKey (KeyCode.X)) {
mouseX += 0.8f;
}
if (Input.GetKey (KeyCode.W)) {
mouseX -= 0.8f;
}
#if UNITY_EDITOR || UNITY_STANDALONE || UNITY_WEBPLAYER
if (Input.GetMouseButton(0) )
{
mouseX += Input.GetAxis("Mouse X") * 左右旋轉速度;
mouseY -= Input.GetAxis("Mouse Y") * 上下旋轉速度;
}
else if (Input.GetAxis("Mouse ScrollWheel") != 0 )
{
距離滑動條值 += Input.GetAxis("Mouse ScrollWheel") * 0.5f;
距離滑動條值 = Mathf.Clamp(距離滑動條值, 0, 1);
}
if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved )
{
mouseX += Input.GetTouch(0).deltaPosition.x;
mouseY -= Input.GetTouch(0).deltaPosition.y;
}
else if (Input.touchCount > 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
{
var tempPosition1 = Input.GetTouch(0).position;
var tempPosition2 = Input.GetTouch(1).position;
if (isZoom(oldPosition1, oldPosition2, tempPosition1, tempPosition2))
{
if (距離滑動條值 > 0)
距離滑動條值 -= 0.05f;
}
else
{
if (距離滑動條值 < 1f)
距離滑動條值 += 0.05f;
}
oldPosition1 = tempPosition1;
oldPosition2 = tempPosition2;
}
}
#else
if (Input.touchCount == 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
mouseX += Input.GetAxis("Mouse X") * 左右旋轉速度;
mouseY -= Input.GetAxis("Mouse Y") * 上下旋轉速度;
}
}
else if (Input.touchCount > 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
{
var tempPosition1 = Input.GetTouch(0).position;
var tempPosition2 = Input.GetTouch(1).position;
if (isZoom(oldPosition1, oldPosition2, tempPosition1, tempPosition2))
{
if (距離滑動條值 > 0)
距離滑動條值 -= 0.05f;
}
else
{
if (距離滑動條值 < 1f)
距離滑動條值 += 0.05f;
}
oldPosition1 = tempPosition1;
oldPosition2 = tempPosition2;
}
}
#endif
}
void LateUpdate()
{
mouseY = ClampAngle(mouseY, 上下旋轉限制.x, 上下旋轉限制.y);
Quaternion toRotation = Quaternion.Euler(mouseY, mouseX, 0);
transform.rotation = Quaternion.Lerp(transform.rotation, toRotation, Time.deltaTime * 移動延遲);
if (目標模型 != null)
{
Vector3 toPosition = transform.rotation * new Vector3(0.0f, 0.0f, -Get當前距離()) + 目標模型.position;
transform.position = toPosition;
}
}
// void OnGUI()
// {
// if(GUI.Button(new Rect(10, 10, 200, 50), "重置位置"))
// {
// 重置位置();
// }
// }
#endregion
Vector3 StartAngles;
float Start距離滑動條值;
float Now距離滑動條值;
public void 位置初始化()
{
StartAngles = transform.eulerAngles;
Start距離滑動條值 = 距離滑動條值;
}
public void 重置位置()
{
mouseX = StartAngles.y;
mouseY = StartAngles.x;
距離滑動條值 = Start距離滑動條值;
}
float Get當前距離()
{
Now距離滑動條值 = Mathf.Lerp(Now距離滑動條值, 距離滑動條值, Time.deltaTime * 移動延遲);
return 距離範圍.x + (距離範圍.y - 距離範圍.x) * Now距離滑動條值;
}
#region Tools
/// <summary>
/// 放大/縮小
/// </summary>
/// <param name="oP1"></param>
/// <param name="oP2"></param>
/// <param name="nP1"></param>
/// <param name="nP2"></param>
/// <returns></returns>
bool isZoom(Vector2 oP1, Vector2 oP2, Vector2 nP1, Vector2 nP2)
{
float leng1 = Mathf.Sqrt((oP1.x - oP2.x) * (oP1.x - oP2.x) + (oP1.y - oP2.y) * (oP1.y - oP2.y));
float leng2 = Mathf.Sqrt((nP1.x - nP2.x) * (nP1.x - nP2.x) + (nP1.y - nP2.y) * (nP1.y - nP2.y));
if (leng1 > leng2)
return false;
else
return true;
}
/// <summary>
/// 限制旋轉最大/最小值
/// </summary>
/// <param name="angle">當前</param>
/// <param name="min">最小</param>
/// <param name="max">最大</param>
/// <returns></returns>
static float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
#endregion
}
using System.Collections;
public class CameraLookAt : MonoBehaviour
{
public Transform 目標模型;
[Tooltip("x:最小;y:最大")]
public Vector2 距離範圍 = new Vector2(0.1f, 5f);
[Range(0f, 1f)]
public static float 距離滑動條值 = 0.5f;
public float 左右旋轉速度 = 2f;
public float 上下旋轉速度 = 2f;
[Tooltip("x:最小;y:最大")]
public Vector2 上下旋轉限制 = new Vector2(-20f,80f);
public float 移動延遲 = 4f;
#region MonoBehaviour
public void Start()
{
if (!目標模型)
{
目標模型 = new GameObject("目標模型").transform;
}
位置初始化();
Now距離滑動條值 = 距離滑動條值;
重置位置();
}
public static float mouseX = 0.0f;
public static float mouseY = 0.0f;
Vector2 oldPosition1;
Vector2 oldPosition2;
void Update()
{
if (Input.GetKey (KeyCode.Y)) {
距離滑動條值 -= Time.deltaTime * 0.5f;
距離滑動條值 = Mathf.Clamp(距離滑動條值, 0, 1);
}
if (Input.GetKey (KeyCode.H)) {
距離滑動條值 += Time.deltaTime * 0.5f;
距離滑動條值 = Mathf.Clamp(距離滑動條值, 0, 1);
}
if(Input.GetKey(KeyCode.A)){
mouseY += 0.8f;
}
if(Input.GetKey(KeyCode.D)){
mouseY -= 0.8f;
}
if (Input.GetKey (KeyCode.X)) {
mouseX += 0.8f;
}
if (Input.GetKey (KeyCode.W)) {
mouseX -= 0.8f;
}
#if UNITY_EDITOR || UNITY_STANDALONE || UNITY_WEBPLAYER
if (Input.GetMouseButton(0) )
{
mouseX += Input.GetAxis("Mouse X") * 左右旋轉速度;
mouseY -= Input.GetAxis("Mouse Y") * 上下旋轉速度;
}
else if (Input.GetAxis("Mouse ScrollWheel") != 0 )
{
距離滑動條值 += Input.GetAxis("Mouse ScrollWheel") * 0.5f;
距離滑動條值 = Mathf.Clamp(距離滑動條值, 0, 1);
}
if (Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Moved )
{
mouseX += Input.GetTouch(0).deltaPosition.x;
mouseY -= Input.GetTouch(0).deltaPosition.y;
}
else if (Input.touchCount > 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
{
var tempPosition1 = Input.GetTouch(0).position;
var tempPosition2 = Input.GetTouch(1).position;
if (isZoom(oldPosition1, oldPosition2, tempPosition1, tempPosition2))
{
if (距離滑動條值 > 0)
距離滑動條值 -= 0.05f;
}
else
{
if (距離滑動條值 < 1f)
距離滑動條值 += 0.05f;
}
oldPosition1 = tempPosition1;
oldPosition2 = tempPosition2;
}
}
#else
if (Input.touchCount == 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved)
{
mouseX += Input.GetAxis("Mouse X") * 左右旋轉速度;
mouseY -= Input.GetAxis("Mouse Y") * 上下旋轉速度;
}
}
else if (Input.touchCount > 1)
{
if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
{
var tempPosition1 = Input.GetTouch(0).position;
var tempPosition2 = Input.GetTouch(1).position;
if (isZoom(oldPosition1, oldPosition2, tempPosition1, tempPosition2))
{
if (距離滑動條值 > 0)
距離滑動條值 -= 0.05f;
}
else
{
if (距離滑動條值 < 1f)
距離滑動條值 += 0.05f;
}
oldPosition1 = tempPosition1;
oldPosition2 = tempPosition2;
}
}
#endif
}
void LateUpdate()
{
mouseY = ClampAngle(mouseY, 上下旋轉限制.x, 上下旋轉限制.y);
Quaternion toRotation = Quaternion.Euler(mouseY, mouseX, 0);
transform.rotation = Quaternion.Lerp(transform.rotation, toRotation, Time.deltaTime * 移動延遲);
if (目標模型 != null)
{
Vector3 toPosition = transform.rotation * new Vector3(0.0f, 0.0f, -Get當前距離()) + 目標模型.position;
transform.position = toPosition;
}
}
// void OnGUI()
// {
// if(GUI.Button(new Rect(10, 10, 200, 50), "重置位置"))
// {
// 重置位置();
// }
// }
#endregion
Vector3 StartAngles;
float Start距離滑動條值;
float Now距離滑動條值;
public void 位置初始化()
{
StartAngles = transform.eulerAngles;
Start距離滑動條值 = 距離滑動條值;
}
public void 重置位置()
{
mouseX = StartAngles.y;
mouseY = StartAngles.x;
距離滑動條值 = Start距離滑動條值;
}
float Get當前距離()
{
Now距離滑動條值 = Mathf.Lerp(Now距離滑動條值, 距離滑動條值, Time.deltaTime * 移動延遲);
return 距離範圍.x + (距離範圍.y - 距離範圍.x) * Now距離滑動條值;
}
#region Tools
/// <summary>
/// 放大/縮小
/// </summary>
/// <param name="oP1"></param>
/// <param name="oP2"></param>
/// <param name="nP1"></param>
/// <param name="nP2"></param>
/// <returns></returns>
bool isZoom(Vector2 oP1, Vector2 oP2, Vector2 nP1, Vector2 nP2)
{
float leng1 = Mathf.Sqrt((oP1.x - oP2.x) * (oP1.x - oP2.x) + (oP1.y - oP2.y) * (oP1.y - oP2.y));
float leng2 = Mathf.Sqrt((nP1.x - nP2.x) * (nP1.x - nP2.x) + (nP1.y - nP2.y) * (nP1.y - nP2.y));
if (leng1 > leng2)
return false;
else
return true;
}
/// <summary>
/// 限制旋轉最大/最小值
/// </summary>
/// <param name="angle">當前</param>
/// <param name="min">最小</param>
/// <param name="max">最大</param>
/// <returns></returns>
static float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
#endregion
}