查看: 2301|回复: 0
打印 上一主题 下一主题

[其他] U3D中摄像机绕屏幕中心点旋转缩放平移(转载)

[复制链接]

711

主题

10

听众

5805

积分

高级设计师

Rank: 6Rank: 6

纳金币
2954
精华
3

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2015-7-30 00:27:31 |只看该作者 |倒序浏览

之前做的都是摄像机绕某个物体旋转。直接修改的Rotation属性然后缩放用的是改摄像机FieldOfView的值最后发觉效果不仅不尽如人意而且平移后会错位。在借鉴了一个别人的摄像机代码后修改成功按住右键旋转,按住中键平移,滚轮缩放脚本拖放到摄像机上即可代码如下
  1. using UnityEngine;
  2. using System.Collections;

  3. public class FreeCameraController : MonoBehaviour {
  4.     //摄像机绕屏幕中心旋转缩放平移脚本

  5.     public float thetaSpeed = 250.0f;
  6.     public float phiSpeed = 120.0f;
  7.     public float moveSpeed = 10.0f;
  8.     public float zoomSpeed = 30.0f;

  9.     public float phiBoundMin = -89f;
  10.     public float phiBoundMax = 89f;
  11.     public bool useMoveBounds = true;
  12.     public float moveBounds = 100f;

  13.     public float rotateSmoothing = 0.5f;
  14.     public float moveSmoothing = 0.7f;

  15.     public float distance = 2.0f;
  16.     private Vector2 euler;

  17.     private Quaternion targetRot;
  18.     private Vector3 targetLookAt;
  19.     private float targetDist;
  20.     private Vector3 distanceVec = new Vector3(0, 0, 0);

  21.     private Transform target;
  22.     private Rect inputBounds;
  23.     public Rect paramInputBounds = new Rect(0, 0, 1, 1);

  24.     public Vector3 pivotPoint = new Vector3(0, 2, 0);

  25.     public void Start()
  26.     {
  27.         Vector3 angles = transform.eulerAngles;        //获取摄像机欧拉角
  28.         euler.x = angles.y;       
  29.         euler.y = angles.x;
  30.         //unity only returns positive euler angles but we need them in -90 to 90
  31.         euler.y = Mathf.Repeat(euler.y + 180f, 360f) - 180f;

  32.         GameObject go = new GameObject("_FreeCameraTarget");
  33.         go.hideFlags = HideFlags.HideAndDontSave | HideFlags.HideInInspector;
  34.         target = go.transform;

  35.         
  36.         target.position = pivotPoint;
  37.         targetDist = (transform.position - target.position).magnitude;
  38.         
  39.         targetRot = transform.rotation;
  40.         targetLookAt = target.position;
  41.     }

  42.     public void Update()
  43.     {
  44.         //NOTE: mouse coordinates have a bottom-left origin, camera top-left
  45.         inputBounds.x = GetComponent<Camera>().pixelWidth * paramInputBounds.x;
  46.         inputBounds.y = GetComponent<Camera>().pixelHeight * paramInputBounds.y;
  47.         inputBounds.width = GetComponent<Camera>().pixelWidth * paramInputBounds.width;
  48.         inputBounds.height = GetComponent<Camera>().pixelHeight * paramInputBounds.height;

  49.         if (target && inputBounds.Contains(Input.mousePosition))
  50.         {
  51.             float dx = Input.GetAxis("Mouse X");
  52.             float dy = Input.GetAxis("Mouse Y");

  53.             bool click1 = Input.GetMouseButton(1);
  54.             bool click2 = Input.GetMouseButton(2);


  55.             if (click2)                //按下鼠标中键,改变摄像机观察中心点位置
  56.             {
  57.                 dx = dx * moveSpeed * 0.005f * targetDist;
  58.                 dy = dy * moveSpeed * 0.005f * targetDist;
  59.                 targetLookAt -= transform.up * dy + transform.right * dx;
  60.                 if (useMoveBounds)
  61.                 {
  62.                     targetLookAt.x = Mathf.Clamp(targetLookAt.x, -moveBounds, moveBounds);
  63.                     targetLookAt.y = Mathf.Clamp(targetLookAt.y, -moveBounds, moveBounds);
  64.                     targetLookAt.z = Mathf.Clamp(targetLookAt.z, -moveBounds, moveBounds);
  65.                 }
  66.             }

  67.             else if (click1)        //按下鼠标右键旋转
  68.             {
  69.                 dx = dx * thetaSpeed * 0.02f;
  70.                 dy = dy * phiSpeed * 0.02f;
  71.                 euler.x += dx;
  72.                 euler.y -= dy;
  73.                 euler.y = ClampAngle(euler.y, phiBoundMin, phiBoundMax);
  74.                 targetRot = Quaternion.Euler(euler.y, euler.x, 0);
  75.             }

  76.             targetDist -= Input.GetAxis("Mouse ScrollWheel") * zoomSpeed * 0.5f;
  77.             targetDist = Mathf.Max(0.1f, targetDist);
  78.         }
  79.     }

  80.     public void FixedUpdate()        //每帧根据摄像机中线点位置不同重新定位摄像机的旋转和坐标
  81.     {
  82.         distance = moveSmoothing * targetDist + (1 - moveSmoothing) * distance;

  83.         transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, rotateSmoothing);
  84.         target.position = Vector3.Lerp(target.position, targetLookAt, moveSmoothing);
  85.         distanceVec.z = distance;
  86.         transform.position = target.position - transform.rotation * distanceVec;
  87.     }

  88.     static float ClampAngle(float angle, float min, float max)        //控制旋转角度不超过360
  89.     {
  90.         if (angle < -360f) angle += 360f;
  91.         if (angle > 360f) angle -= 360f;
  92.         return Mathf.Clamp(angle, min, max);
  93.     }
  94. }
复制代码
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

关闭

站长推荐上一条 /1 下一条

手机版|纳金网 ( 闽ICP备08008928号

GMT+8, 2024-4-29 15:29 , Processed in 0.084028 second(s), 28 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部