unity中的交互控制脚本

使用方法: 挂载到要控制的相机上

target 选定围绕中心物体

csharp 复制代码
using UnityEngine;

public class OrbitCameraController : MonoBehaviour
{
    public Transform target; // 目标物体的Transform
    public float distance = 10.0f; // 初始相机到目标的距离

    public float xSpeed = 250.0f;
    public float ySpeed = 100.0f;

    [Range(1.0f, 100.0f)]
    public float minDistance = 2.0f; // 最小距离
    [Range(1.0f, 100.0f)]
    public float maxDistance = 40.0f; // 最大距离

    [Range(-90, 90)]                    // 控制俯仰角范围 [-90, 90]
    public float minYAngle = -60f;      // 最小俯仰角(向下看)
    [Range(-90, 90)]
    public float maxYAngle = 60f;       // 最大俯仰角(向上看)

    // 阻尼设置
    public bool useDamping = true;
    public float dampingTime = 0.15f;

    private float x = 0.0f;
    private float y = 0.0f;

    private float targetX = 0.0f;
    private float targetY = 0.0f;
    private float targetDistance;

    private Vector3 velocity = Vector3.zero;

    void Start()
    {
        Vector3 angles = transform.eulerAngles;
        x = angles.y;
        y = ClampAngle(angles.x, -360, 360);

        targetX = x;
        targetY = y;
        targetDistance = distance;

        //Cursor.lockState = CursorLockMode.Locked;
    }

    void LateUpdate()
    {
        if (!target) return;

        // 处理鼠标拖动视角
        HandleMouseRotation();

        // 处理鼠标滚轮缩放
        HandleScrollWheelZoom();

        // 处理触控缩放
        HandleTouchInput();

        // 应用阻尼效果
        if (useDamping)
        {
            x = Mathf.SmoothDamp(x, targetX, ref velocity.x, dampingTime);
            y = Mathf.SmoothDamp(y, targetY, ref velocity.y, dampingTime);
            distance = Mathf.SmoothDamp(distance, targetDistance, ref velocity.z, dampingTime);
        }
        else
        {
            x = targetX;
            y = targetY;
            distance = targetDistance;
        }

        // 计算相机位置与旋转
        Quaternion rotation = Quaternion.Euler(y, x, 0);
        Vector3 position = rotation * new Vector3(0, 0, -distance) + target.position;

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

    void HandleMouseRotation()
    {
        if (Input.GetMouseButton(0)) // 鼠标左键拖动旋转
        {
            targetX += Input.GetAxis("Mouse X") * xSpeed * Time.deltaTime * 0.5f;
            targetY -= Input.GetAxis("Mouse Y") * ySpeed * Time.deltaTime * 0.5f;

            targetY = Mathf.Clamp(targetY, minYAngle, maxYAngle); // 限制上下角度
        }
    }

    void HandleScrollWheelZoom()
    {
        float scroll = Input.GetAxis("Mouse ScrollWheel");
        if (scroll != 0)
        {
            targetDistance -= scroll * 2f; // 滚轮灵敏度
            targetDistance = Mathf.Clamp(targetDistance, minDistance, maxDistance);

            UnityEngine.Debug.Log("相机距离: " + targetDistance);
        }
    }

    void HandleTouchInput()
    {
        if (Input.touchCount == 2)
        {
            Touch touchZero = Input.GetTouch(0);
            Touch touchOne = Input.GetTouch(1);

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

            float prevMagnitude = (touchZeroPrevPos - touchOnePrevPos).magnitude;
            float currentMagnitude = (touchZero.position - touchOne.position).magnitude;

            float difference = currentMagnitude - prevMagnitude;
            float scaleFactor = difference * 0.01f;

            targetDistance -= scaleFactor;
            targetDistance = Mathf.Clamp(targetDistance, minDistance, maxDistance);
        }
    }

    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);
    }
}
相关推荐
半杯咖啡半行码5 小时前
QML与 Qt Quick入门实战:从零基础到 C++ 双向通信详解
java·qt·交互
高升说6 小时前
无人机吊舱相机选型:稳定、变焦与画质的工程权衡
数码相机·无人机
畅想视界ThinkView6 小时前
病区护士站触控终端选型指南:分诊叫号与护理交互终端怎么挑
前端·microsoft·交互
平行云6 小时前
建筑BIM/3D可视化轻量级实时评审与分享方案
unity·ue5·3dsmax·实时云渲染·云桌面·云游戏·建筑bim
QYRese6 小时前
CAGR3.1%!抗辐射相机市场迎替换潮,核设施数字化、水下场景带来增量
大数据·数码相机
unicrom_深圳市由你创科技1 天前
多相机GigE Vision:触发与图像网段怎么分?
数码相机
2501_915106321 天前
Windows 上开发 Unity iOS,使用 KXBuild 进行真机调试、性能采样与打包 ipa
windows·vscode·unity·ios·个人开发·swift·敏捷流程
FFFFujige1 天前
【Unity】一个的Dots用Ruhanka踩坑记录
unity·游戏引擎
FLJwu1 天前
运动相机采购实战|第四篇(终章):一张清单走完选型全流程,把风险拦在源头
c语言·开发语言·数码相机·运动相机·oem 量产
光电的一只菜鸡1 天前
鱼眼镜头需要考虑color shading吗
数码相机