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

public class CameraRotExp : MonoBehaviour
{
     private Transform _target;

    public enum LookCenterType
    {
        ParentChildren,Mesh,Vector3,
    }
    public LookCenterType lookCenterType = LookCenterType.Vector3;
    
    public Transform target
    {
        get { return _target; }
        set
        {
            _target = value;
            lookcenter = GetChildsCenter(_target);
            GetYspeed(_target);
            lookcenterlocal = _target.InverseTransformPoint(lookcenter);
            var render = _target.GetComponent<Renderer>();
            meshcenterlocal = render == null ? Vector3.zero : _target.InverseTransformPoint( render.bounds.center);
            StartCoroutine(MoveTarget());
        }
    }

    public float x_Speed = 1000;
    public float y_Speed = 1000;
    public float mmSpeed =10;
    public float xMinLimit = -70;
    public float xMaxLimit = 80;
    public float distance = 5;
    public float minDistance = 0.5f;
    public float maxDistance = 30;
    public bool isNeedDamping = true;
    public float x_OriginAngle = 30f;
    public float y_OriginAngle = 0f;
    public float damping = 8f;

    public bool IsMove = true;
    private bool inMoveState = false;
    private Vector3 lookcenter;
    private Vector3 lookcenterlocal;
    private Vector3 meshcenterlocal;
    private void Start()
    {
        try
        {
            lookcenter = GetChildsCenter(target);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }
    private void LateUpdate()
    {
        if (!IsMove) return;
        if (target)
        {
            if (!EventSystem.current.currentSelectedGameObject)
            {
                if (Input.GetMouseButtonDown(1) && !EventSystem.current.IsPointerOverGameObject())
                {
                    inMoveState = true;
                }
                if (Input.GetMouseButtonUp(1) && inMoveState || !Input.GetMouseButton(1))
                {
                    inMoveState = false;
                }
                if (inMoveState&&Input.GetMouseButton(1))
                {
                    y_OriginAngle += Input.GetAxis("Mouse X") * x_Speed * Time.deltaTime;
                    x_OriginAngle -= Input.GetAxis("Mouse Y") * y_Speed * Time.deltaTime;
                    x_OriginAngle = ClampAngle(x_OriginAngle, xMinLimit, xMaxLimit);
                }
            }
            
            if(!EventSystem.current.IsPointerOverGameObject())
            {
                distance -= Input.GetAxis("Mouse ScrollWheel") * mmSpeed;
                distance = Mathf.Clamp(distance, minDistance, maxDistance);
            }
            
            Quaternion rotation = Quaternion.Euler(x_OriginAngle, y_OriginAngle, 0.0f);
            Vector3 disVector = new Vector3(0.0f, 0.0f, -distance);
            Vector3 tempcenter =lookCenterType==LookCenterType.ParentChildren?_target.TransformPoint(lookcenterlocal):
                lookCenterType==LookCenterType.Mesh? _target.TransformPoint(meshcenterlocal):lookcenter;
            Vector3 position = rotation * disVector + tempcenter;
            if (isNeedDamping)
            {
                transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping);
                //transform.position = Vector3.Lerp(transform.position, position, Time.deltaTime * damping);
                transform.position = transform.rotation * disVector + tempcenter; 
            }
            else
            {
                transform.rotation = rotation;
                transform.position = position;
            }
        }
    }

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

    public void ban()
    {
        IsMove = false;
    }

    public void Noban()
    {
        IsMove = true;
    }

    /// <summary>
    /// ����ģ�͵����ĵ�
    /// </summary>
    /// <param name="tran"></param>
    /// <returns></returns>
    public Vector3 GetChildsCenter(Transform tran)
    {
        Vector3 center = Vector3.zero;
        Renderer[] renders = tran.GetComponentsInChildren<Renderer>();
        foreach (Renderer child in renders)
        {
            center += child.bounds.center;
        }
        center /= tran.GetComponentsInChildren<Renderer>().Length;
        Bounds bounds = new Bounds(center, Vector3.zero);
        foreach (Renderer item in renders)
        {
            bounds.Encapsulate(item.bounds);
        }
        return bounds.center;
    }

    public void GetYspeed(Transform tran)
    {
        if (tran.parent == null||tran.parent.parent==null)
        {
            y_Speed = 1000;
            x_Speed = 1000;
        }
        else if(tran.parent.parent.parent==null)
        {
            y_Speed = 1000;
            x_Speed = 1000;
        }
        else
        {
            y_Speed = 1000;
            x_Speed = 1000;
        }
    }

    IEnumerator MoveTarget()
    {
        IsMove = false;
        while (true)
        {
            Vector3 tempcenter =lookCenterType==LookCenterType.ParentChildren?_target.TransformPoint(lookcenterlocal):
                lookCenterType==LookCenterType.Mesh? _target.TransformPoint(meshcenterlocal):lookcenter;
            x_OriginAngle = ClampAngle(x_OriginAngle, xMinLimit, xMaxLimit);
            
            Quaternion rotation = Quaternion.Euler(x_OriginAngle, y_OriginAngle, 0.0f);
            Vector3 disVector = new Vector3(0.0f, 0.0f, -distance);
            Vector3 position = rotation * disVector + tempcenter;
            
            transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * damping);
            transform.position = Vector3.Lerp(transform.position, position, Time.deltaTime * damping);
            if(Vector3.Distance(transform.position,position)<0.001f) break;
            yield return new WaitForEndOfFrame();
        }
        IsMove = true;
    }

}


End

本文标题:Unity 相机通用移动脚本

本文链接:https://www.52unity.cn/archives/17.html

除非另有说明,本作品遵循CC 4.0 BY-SA 版权协议

声明:转载请注明文章来源。

最后修改:2025 年 07 月 01 日
如果觉得我的文章对你有用,请随意赞赏