U3D中摄像机绕屏幕中心点旋转缩放平移

原创 2015年07月10日 12:08:31

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

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

    public float thetaSpeed = 250.0f;
    public float phiSpeed = 120.0f;
    public float moveSpeed = 10.0f;
    public float zoomSpeed = 30.0f;

    public float phiBoundMin = -89f;
    public float phiBoundMax = 89f;
    public bool useMoveBounds = true;
    public float moveBounds = 100f;

    public float rotateSmoothing = 0.5f;
    public float moveSmoothing = 0.7f;

    public float distance = 2.0f;
    private Vector2 euler;

    private Quaternion targetRot;
    private Vector3 targetLookAt;
    private float targetDist;
    private Vector3 distanceVec = new Vector3(0, 0, 0);

    private Transform target;
    private Rect inputBounds;
    public Rect paramInputBounds = new Rect(0, 0, 1, 1);

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

    public void Start()
    {
        Vector3 angles = transform.eulerAngles;
        euler.x = angles.y;
        euler.y = angles.x;
        //unity only returns positive euler angles but we need them in -90 to 90
        euler.y = Mathf.Repeat(euler.y + 180f, 360f) - 180f;

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

        
        target.position = pivotPoint;
        targetDist = (transform.position - target.position).magnitude;
        
        targetRot = transform.rotation;
        targetLookAt = target.position;
    }

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

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

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


            if (click2)
            {
                dx = dx * moveSpeed * 0.005f * targetDist;
                dy = dy * moveSpeed * 0.005f * targetDist;
                targetLookAt -= transform.up * dy + transform.right * dx;
                if (useMoveBounds)
                {
                    targetLookAt.x = Mathf.Clamp(targetLookAt.x, -moveBounds, moveBounds);
                    targetLookAt.y = Mathf.Clamp(targetLookAt.y, -moveBounds, moveBounds);
                    targetLookAt.z = Mathf.Clamp(targetLookAt.z, -moveBounds, moveBounds);
                }
            }

            else if (click1)
            {
                dx = dx * thetaSpeed * 0.02f;
                dy = dy * phiSpeed * 0.02f;
                euler.x += dx;
                euler.y -= dy;
                euler.y = ClampAngle(euler.y, phiBoundMin, phiBoundMax);
                targetRot = Quaternion.Euler(euler.y, euler.x, 0);
            }

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

    public void FixedUpdate()
    {
        distance = moveSmoothing * targetDist + (1 - moveSmoothing) * distance;

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

    static float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360f) angle += 360f;
        if (angle > 360f) angle -= 360f;
        return Mathf.Clamp(angle, min, max);
    }
}



相关文章推荐

[Unity基础]让物体朝摄像机观察方向移动(一)

情景一:假设有一个人,他面对北方,他背后有一台摄像机,正巧也是面对北方。现在,他向左转90度,面对西方。此时如果让他向前走,那么有两种情况。 情况一:以自身坐标系向前走。他将会向眼睛直视的方...
  • lyh916
  • lyh916
  • 2015年05月24日 15:52
  • 5109

Unity 移动摄像机的脚本(类似于魔兽争霸, LOL的摄像机移动方式)

类似LOL、魔兽争霸摄像机的移动,  当鼠标移动到窗口上下左右边界的时候, 移动摄像机。  将屏幕分为9份, 每一份一个标记, 标记划分参考计算机图形学 //整体移动速度...

Unity 摄像机按照中心点移动

场景里需要两个摄像机,两个Sprite。其中一组作为正在使用的对象,另一组作为复位的默认位置。 通过鼠标或者最多两个手指的手势可以控制摄像机观察点的移动。 以下这段代码在Windows和Andro...

unity3d控制camera移动旋转

第一次写博客,刚开始学习unity。把近期所学记录下来~     最近做的demo是控制一个摄像头在一个室内的场景中自由移动,类似于第一人称视角。     1.用鼠标和键盘控制 using Unity...

unity 实时 获得屏幕中心点的世界坐标

Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2,Screen.height/2,0));//射线 ...

Unity3D学习日记(五)实现围绕物品旋转的的摄像机控制

这个是我在公司项目里面发现的一个写的很不错的一个简单的围绕物品选择的一个摄像机控制方法,这个方法比我之前写方法好用而且修复我之前遇到的一个Bug问题,这里我就对这两个方法进行介绍...

Unity3d实现物体围绕某一点进行旋转

1,让一个物体围绕某一点旋转,有几种方法?分别是什么? 答:在这个点处放一个空物体B,则问题变为A绕着B旋转, 方法1:旋转函数transform.Rotate()来实现         方法2:B不...

Unity3D【脚本】鼠标对摄像机的控制 - 点击鼠标,摄像机围绕圆心旋转(第三次修改)

第一次发控制摄像机旋转代码是几个月前。 Unity3D【脚本】鼠标对摄像机的控制 - 点击鼠标右键,移动,摄像机围绕圆心旋转...

控制摄像机围绕目标旋转观察

using UnityEngine; using System.Collections; public class CameraController : MonoBehaviour { pu...

Unity中摄像机绕物体旋转和拉近拉远视角的操作

Unity中摄像机的重要性毋庸置疑,关于摄像机的操作也有很多,比如第一人称跟随,第二人称跟随,摄像机的拉近拉远等等,下面就暂时实现摄像机的拉近拉远和旋转: 创建新的场景,场景中添加一个cube,...
  • KHFlash
  • KHFlash
  • 2017年03月10日 17:07
  • 1164
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:U3D中摄像机绕屏幕中心点旋转缩放平移
举报原因:
原因补充:

(最多只允许输入30个字)