Unity 模型操作,旋转视角,放大缩小

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

/// <summary>
/// 模型旋转放大缩小操作
/// </summary>
public class ModelOperation : MonoBehaviour
{
    public Transform target;
    public float xSpeed = 200;
    public float ySpeed = 200;
    public float mSpeed = 10;
    public float yMinLimit = -50;
    public float yMaxLimit = 50;
    public float distance = 2;
    public float minDistance = 2;
    public float maxDistance = 30;

    public bool needDamping = true;
    public float damping = 5.0f;

    public float x = 0.0f;
    public float y = 0.0f;
    public float z = 0.0f;

    private float _touchMoveSpeed;

    private void Awake()
    {
        _touchMoveSpeed = 0.001f;
    }

    void Start()
    {
        mSpeed = 1;
        damping = 20;
        yMinLimit = -360;
        yMaxLimit = 360;
    }

    void LateUpdate()
    {
        if (target)
        {
            if (Input.GetMouseButton(0) && !IsPointerOverUI() && Input.touchCount != 2)
            {
                needDamping = false;
                x += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
                y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;

                y = ClampAngle(y, yMinLimit, yMaxLimit);
            }

            distance -= Input.GetAxis("Mouse ScrollWheel") * mSpeed;
            distance = Mathf.Clamp(distance, minDistance, maxDistance);
            Quaternion rotation = Quaternion.Euler(y, x, 0.0f);
            Vector3 disVector = new Vector3(0.0f, 0.0f, -distance);
            Vector3 position = rotation * disVector + target.position;
            
            if (needDamping)
            {
                transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * damping);
                transform.position = Vector3.Lerp(transform.position, position, Time.deltaTime * damping);
            }
            else
            {
                transform.rotation = rotation;
                transform.position = position;
            }

            // 双指缩放处理
            if (Input.touchCount == 2 && Input.touches[0].phase == TouchPhase.Moved && Input.touches[1].phase == TouchPhase.Moved)
            {
                Touch touchZero = Input.touches[0];
                Touch touchOne = Input.touches[1];

                Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition;
                Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;

                float prevTouchDeltaMag = (touchZeroPrevPos - touchOnePrevPos).magnitude;
                float touchDeltaMag = (touchZero.position - touchOne.position).magnitude;

                float deltaMagnitudeDiff = prevTouchDeltaMag - touchDeltaMag;

                distance += deltaMagnitudeDiff * _touchMoveSpeed; // 缩放速度可以调整
                distance = Mathf.Clamp(distance, minDistance, maxDistance);

                Quaternion rotation1 = Quaternion.Euler(y, x, 0.0f);
                Vector3 disVector1 = new Vector3(0.0f, 0.0f, -distance);
                Vector3 position1 = rotation1 * disVector1 + target.position;

                if (needDamping)
                {
                    transform.rotation = Quaternion.Lerp(transform.rotation, rotation1, Time.deltaTime * damping);
                    transform.position = Vector3.Lerp(transform.position, position1, Time.deltaTime * damping);
                }
                else
                {
                    transform.rotation = rotation1;
                    transform.position = position1;
                }
            }
            needDamping = true;
        }
    }

    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);
    }

    bool IsPointerOverUI()
    {
        PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
        eventDataCurrentPosition.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
        List<RaycastResult> results = new List<RaycastResult>();
        EventSystem.current.RaycastAll(eventDataCurrentPosition, results);
        return results.Count > 0;
    }

    public void OrbUpdate(OrbUpdateData orbUpdateData)
    {
        target = orbUpdateData.transform;
        distance = orbUpdateData.distance;
        minDistance = orbUpdateData.minDistance;
        maxDistance = orbUpdateData.maxDistance;
        x = orbUpdateData.vertical;
        y = orbUpdateData.horizontal;
        _touchMoveSpeed = orbUpdateData.touchMoveSpeed;
    }
}

public class OrbUpdateData
{
    public Transform transform;// 目标
    public float distance;// 默认距离
    public float minDistance;// 最小距离
    public float maxDistance;// 最大距离
    public float horizontal;
    public float vertical;
    public float touchMoveSpeed;
};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值