untiy平移旋转缩放【自用源码】

##untiy平移旋转缩放【自用源码】

using DG.Tweening;
using System;
using UnityEngine;

namespace DR.ThreeDimensions
{
public class MouseExhibitionControl : MonoBehaviour
{
//相机跟随的目标物体,一般是一个空物体
[HideInInspector]
public Transform target;
public Vector3 jfcenter;

    private float MouseWheelSensitivity = 10; //滚轮灵敏度设置
    private float MouseZoomMin = 5; //相机距离最小值
    private float MouseZoomMax = 40; //相机距离最大值

    private float moveSpeed = 10; //相机跟随速度(中键平移时),采用平滑模式时起作用,越大则运动越平滑

    private float xSpeed = 250.0f; //旋转视角时相机x轴转速
    private float ySpeed = 120.0f; //旋转视角时相机y轴转速

    private int yMinLimit = 10;
    private int yMaxLimit = 70;

    private float x = 0.0f; //存储相机的euler角
    private float y = 0.0f; //存储相机的euler角

    private float Distance = 20; //相机和target之间的距离,因为相机的Z轴总是指向target,也就是相机z轴方向上的距离
    private Vector3 targetOnScreenPosition; //目标的屏幕坐标,第三个值为z轴距离
    private Quaternion storeRotation; //存储相机的姿态四元数
    public Vector3 CameraTargetPosition; //target的位置
    private Vector3 initPosition; //平移时用于存储平移的起点位置
    private Vector3 cameraX; //相机的x轴方向向量
    private Vector3 cameraY; //相机的y轴方向向量
    private Vector3 cameraZ; //相机的z轴方向向量

    private Vector3 initScreenPos; //中键刚按下时鼠标的屏幕坐标(第三个值其实没什么用)
    private Vector3 curScreenPos; //当前鼠标的屏幕坐标(第三个值其实没什么用)

    private void SynchronizationData()
    {
        CameraTargetPosition = target.position;
        targetOnScreenPosition = Camera.main.WorldToScreenPoint(CameraTargetPosition);
        storeRotation = transform.rotation;
        cameraX = transform.right;
        cameraY = transform.up;
        cameraZ = transform.forward;
        Distance = Vector3.Distance(transform.position, target.position);
        x = transform.eulerAngles.y;
        y = transform.eulerAngles.x;
    }


    void Start()
    {
        campass = GameObject.FindGameObjectWithTag("Camera");
        GameObject t = GameObject.FindGameObjectWithTag("Target");
        if (t) target = t.transform;
        else target = GameObject.Find("Target").transform;
        jfcenter = target.position;
        //这里就是设置一下初始的相机视角以及一些其他变量,这里的x和y。。。是和下面getAxis的mouse x与mouse y对应
        SetDistance();
        var angles = transform.eulerAngles;
        x = angles.y;
        y = angles.x;
        CameraTargetPosition = target.position;
        storeRotation = Quaternion.Euler(y, x, 0);
        transform.rotation = storeRotation; //设置相机姿态
        Vector3 position = storeRotation * new Vector3(0.0F, 0.0F, -Distance) + CameraTargetPosition; //四元数表示一个旋转,四元数乘以向量相当于把向量旋转对应角度,然后加上目标物体的位置就是相机位置了
        transform.position = storeRotation * new Vector3(0, 0, -Distance) + CameraTargetPosition; //设置相机位置
    }
    float cabinetMaxDis = 3;
    private void SetDistance()
    {
        int topdistance = MessageManager.Instance.GetSetttingValueToInt("topDistance");
        if (topdistance > 0)
        {
            Distance = topdistance;
        }
        string value = MessageManager.Instance.GetSetttingValue("cabinetMaxDis");
        if (!string.IsNullOrEmpty(value))
        {
            try
            {
                float dis = float.Parse(value);
                if (dis >= 2) { cabinetMaxDis = dis; }
            }
            catch (System.Exception)
            {

            }
        }

    }


    void Update()
    {
        switch (m_type)
        {
            case ControlType.top:
                //鼠标右键旋转功能
                RotateFunction();

                //鼠标滚轮放大缩小
                ZoomInAndOutFunction();

                //鼠标中键平移
                TranslationFunction();
                campass.SetActive(true);
                break;
            case ControlType.cabinet:
                //鼠标滚轮放大缩小
                ZoomInAndOutFunction();

                //鼠标中键平移
                TranslationFunction();
                campass.SetActive(false);
                break;
            case ControlType.device:
                //鼠标右键旋转功能
                RotateFunction();

                //鼠标滚轮放大缩小
                ZoomInAndOutFunction();

                //鼠标中键平移
                TranslationFunction();
                campass.SetActive(false);
                break;
            case ControlType.none:
                RotateFunction();
                ZoomInAndOutFunction();
                TranslationFunction();
                campass.SetActive(true);
                break;
            default:
                break;
        }


    }

    public static Action OnMouseButtonDown_2;
    private void TranslationFunction()
    {
        if (Input.GetMouseButtonDown(2))
        {
            if (OnMouseButtonDown_2 != null) OnMouseButtonDown_2();
            cameraX = transform.right;
            cameraY = transform.up;
            cameraZ = transform.forward;

            initScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetOnScreenPosition.z);
            Debug.Log("downOnce");

            //targetOnScreenPosition.z为目标物体到相机xmidbuttonDownPositiony平面的法线距离
            targetOnScreenPosition = Camera.main.WorldToScreenPoint(CameraTargetPosition);
            initPosition = CameraTargetPosition;
        }

        if (Input.GetMouseButton(2))
        {
            curScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetOnScreenPosition.z);
            //0.01这个系数是控制平移的速度,要根据相机和目标物体的distance来灵活选择
            target.position = initPosition - 0.01f * ((curScreenPos.x - initScreenPos.x) * cameraX + (curScreenPos.y - initScreenPos.y) * cameraY);

            //重新计算位置
            Vector3 mPosition = storeRotation * new Vector3(0.0F, 0.0F, -Distance) + target.position;
            transform.position = mPosition;

            // //用这个会让相机的平移变得更平滑,但是可能在你buttonup时未使相机移动到应到的位置,导致再进行旋转与缩放操作时出现短暂抖动
            //transform.position=Vector3.Lerp(transform.position,mPosition,Time.deltaTime*moveSpeed);

        }
        if (Input.GetMouseButtonUp(2))
        {
            Debug.Log("upOnce");
            //平移结束把cameraTargetPosition的位置更新一下,不然会影响缩放与旋转功能
            CameraTargetPosition = target.position;
        }
    }

    private void RotateFunction()
    {
        if (Input.GetMouseButton(1))
        {
            UIManager.Instance.GetWindow<NamePanel>().SetVisible(false);
            x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
            y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;

            y = ClampAngle(y, yMinLimit, yMaxLimit);              
            storeRotation = Quaternion.Euler(y, x, 0);
            var position = storeRotation * new Vector3(0.0f, 0.0f, -Distance) + CameraTargetPosition;

            transform.rotation = storeRotation;
            transform.position = position;
        }

    }

    private void ZoomInAndOutFunction()
    {
        if (Input.GetAxis("Mouse ScrollWheel") != 0) //鼠标滚轮缩放功能
        {
            if (Distance >= MouseZoomMin && Distance <= MouseZoomMax)
            {
                Distance -= Input.GetAxis("Mouse ScrollWheel") * MouseWheelSensitivity;
            }
            if (Distance < MouseZoomMin)
            {
                Distance = MouseZoomMin;
            }
            if (Distance > MouseZoomMax)
            {
                Distance = MouseZoomMax;
            }
            var rotation = transform.rotation;

            transform.position = storeRotation * new Vector3(0.0F, 0.0F, -Distance) + CameraTargetPosition;
        }
    }

    //将angle限制在min~max之间
    public 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);
    }

    void testScreenToWorldPoint()
    {
        //第三个坐标指的是在相机z轴指向方向上的距离
        Vector3 screenPoint = Camera.main.WorldToScreenPoint(CameraTargetPosition);
        Debug.Log("ScreenPoint: " + screenPoint);

        // var worldPosition = Camera.main.ScreenToWorldPoint(new Vector3(1,1,10));
        // Debug.Log("worldPosition: "+worldPosition);
    }
    public ControlType m_type;
    private GameObject campass;

    /// <summary>
    /// 刷新Cam操作脚本参数
    /// </summary>
    /// <param name="t_Cam">相机位置</param>
    /// <param name="t_target">target的位置</param>
    /// <param name="type">视角类型</param>
    public void RefrashTargetTransform(Vector3 pos, Vector3 rotate, Transform t_target, ControlType type)
    {
        print("刷新状态" + type);
        UIManager.Instance.SetWindowVisiableByType(type);
        transform.DOMove(pos, 1f);
        Tweener tweener = transform.DORotate(rotate, 1f);
        target.position = t_target.position;
        target.rotation = t_target.rotation;
        tweener.OnComplete(SynchronizationData);
        m_type = type;
        switch (type)
        {
            case ControlType.top:
                MouseZoomMin = 5;
                MouseZoomMax = Distance+20;
                yMinLimit = -10;
                yMaxLimit = 70;
                MouseWheelSensitivity = 10;

                break;
            case ControlType.cabinet:
                MouseZoomMin = 1;
                MouseZoomMax = cabinetMaxDis;
                yMinLimit = -90;
                yMaxLimit = 90;
                MouseWheelSensitivity = 1;

                break;
            case ControlType.device:
                MouseZoomMin = 0.4f;
                MouseZoomMax = 1;
                yMinLimit = -90;
                yMaxLimit = 90;
                MouseWheelSensitivity = 0.1f;

                break;
            case ControlType.none:
                MouseZoomMin = 5;
                MouseZoomMax = 40;
                yMinLimit = -10;
                yMaxLimit = 70;
                MouseWheelSensitivity = 10;

                break;
            default:
                break;
        }
    }

    //点击按钮查看设备背面
    //x变化为360倍数
    public void ButtonRotate(float finalangle = 360)
    {
        // float xpos = Input.mousePosition.x;
        UIManager.Instance.GetWindow<NamePanel>().SetVisible(false);
        float dif = finalangle - (x % 360);
        // float axis = dif / (xSpeed * 0.02f);//Input.GetAxis的值为所指定的轴上的位移量,即为当前坐标-上一次坐标值
        //强制设置鼠标位置 
        //SetCursorPos((int)(xpos + axis), (int)y);
        storeRotation = Quaternion.Euler(y, x + dif, 0);
        var position = storeRotation * new Vector3(0.0f, 0.0f, -Distance) + CameraTargetPosition;

        transform.rotation = storeRotation;
        transform.position = position;

        x = x + dif;
    }


}
public enum ControlType
{
    top,
    cabinet,
    device,
    none
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值