相机围绕物体旋转,并且有Y轴角度限制

相机围绕物体旋转,并且有Y轴角度限制,可通过parameters.offset 修改使目标物不在画面中心

using UnityEngine;

using System.Collections;

using System.Collections.Generic;

using UnityEngine.EventSystems;

using UnityEngine.UI;

public class CameraController : MonoBehaviour

{

public static CameraController instance;

public Transform ModelRoot; //目标物

public Transform[] targets; //空物体

HideInInspector

public int index; // 当前的场景

private int comeBack = 0; // 返回主页计数

private Transform curtarget; // 当前摄像机锁定的目标

复制代码
[System.Serializable]
public class CameraParameters 
{
    public bool smoothFollow;   //  是否开启平滑跟随
    public float followSpeed;   // 跟随速度
    public float distance;      // 相机的初始距离
    public float minDistance;   // 最小距离
    public float maxDistance;   // 最大距离
    public float zoomSpeed;     // 缩放速度
    public float zoomSensitivity;     // 缩放灵敏度
    public float rotationSensitivity; // 旋转灵敏度
    public float yMinLimit; // 垂直最小值
    public float yMaxLimit; // 垂直最大值
    public Vector3 offset;  // 偏移量

    public float inFade = 0.6f;     //  材质淡入
    public float outFade = 1.0f;    //  材质淡出
}

public CameraParameters parameters;  //  相机相关参数

public float x { get; private set; } // 相机X方向旋转量
public float y { get; private set; } // 相机Y方向旋转量
public float distanceTarget { get; private set; } // 目标距离 

private Vector3 position;
private Quaternion rotation = Quaternion.identity;
private Vector3 smoothPosition;
private Camera cam;
[HideInInspector]
public bool isRay = true;  //  射线检测开关,在主场景才开启射线拾取
private GameObject rayTarget;
//  设备开机相关参数
public static bool isStart = false;

void Awake()
{
    instance = this;
    parameters = new CameraParameters();
    InitCameraParaDefault();  //    设置相机的默认参数

    index = 0;
    curtarget = targets[index];
    Vector3 angles = transform.eulerAngles;
    x = angles.y;
    y = angles.x;
    //目标距离
    distanceTarget = parameters.distance;
    smoothPosition = transform.position;

    cam = Camera.main;
}

void Update()
{
    if (isRay)
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//从摄像机发出到点击坐标的射线
        RaycastHit hitInfo;
        if (Physics.Raycast(ray, out hitInfo))
        {
            Debug.DrawLine(ray.origin, hitInfo.point, Color.blue);//划出射线,只有在scene视图中才能看到

            rayTarget = hitInfo.collider.gameObject;
        }
        else
        {
            rayTarget = null;
        }
    }

    UpdateTransform();
}


#region 相机控制脚本
//  默认的相机参数设置
private void InitCameraParaDefault()
{
    parameters.smoothFollow = false;
    parameters.followSpeed = 2.0f;
    parameters.minDistance = 0.0f;
    parameters.maxDistance = 10.0f;
    parameters.distance = 2f;
    parameters.zoomSpeed = 10.0f;
    parameters.zoomSensitivity = 1.0f;
    parameters.rotationSensitivity = 3.5f;
    parameters.yMinLimit = 0;
    parameters.yMaxLimit = 8;
    parameters.offset = new Vector3(-1.31f, 0.18f, -10.44f);

}

//  单个模型场景的相机参数设置 
/// <summary>
/// maxDistance参数大于或等于distance参数
/// </summary>
/// <param name="distance"></param>
/// <param name="minDistance"></param>
/// <param name="maxDistance"></param>
/// <param name="offsetY"></param>
private void InitCameraParaOneModel(float distance, float minDistance, float maxDistance, float offsetY = 0.0f)
{
    parameters.smoothFollow = false;
    parameters.followSpeed = 5.0f;
    parameters.minDistance = minDistance;
    parameters.maxDistance = maxDistance;
    parameters.distance = distance;
    parameters.zoomSpeed = 5.0f;
    parameters.zoomSensitivity = 1.0f;
    parameters.rotationSensitivity = 3.5f;
    parameters.yMinLimit = 0;
    parameters.yMaxLimit = 8;
    parameters.offset = new Vector3(0.0f, offsetY, 0.0f);
}
void LateUpdate()
{
    UpdateInput();
}

// 获取用户鼠标信息
public void UpdateInput()
{
    if (curtarget == null || !cam.enabled) return;

    bool rotate = Input.GetMouseButton(0);  //  判断鼠标是否右键按下

    //delta rotation
    if (rotate)
    {
        x += Input.GetAxis("Mouse X") * parameters.rotationSensitivity;
        y = ClampAngle(y - Input.GetAxis("Mouse Y") * parameters.rotationSensitivity, parameters.yMinLimit, parameters.yMaxLimit);
    }

    // Distance
    distanceTarget = Mathf.Clamp(distanceTarget + zoomAdd, parameters.minDistance, parameters.maxDistance);
}

// 更新相机位置
public void UpdateTransform()
{
    UpdateTransform(Time.deltaTime);
}

public void UpdateTransform(float deltaTime)
{
    if (curtarget == null || !cam.enabled) return;

    // Distance
    parameters.distance += (distanceTarget - parameters.distance) * parameters.zoomSpeed * deltaTime;
    // Rotation 
    rotation = Quaternion.AngleAxis(x, Vector3.up) * Quaternion.AngleAxis(y, Vector3.right);

    // Smooth follow
    if (!parameters.smoothFollow) smoothPosition = curtarget.position;
    else smoothPosition = Vector3.Lerp(smoothPosition, curtarget.position, deltaTime * parameters.followSpeed);

    // Position
    position = smoothPosition + rotation * (parameters.offset - Vector3.forward * parameters.distance);

    // Translating the camera
    transform.position = position;
    transform.rotation = rotation;
}

// Zoom input  放大缩小
private float zoomAdd
{
    get
    {
        float scrollAxis = Input.GetAxis("Mouse ScrollWheel");

        if (scrollAxis > 0) return -parameters.zoomSensitivity;
        if (scrollAxis < 0) return parameters.zoomSensitivity;
        return 0;
    }
}

// Clamping Euler angles
private float ClampAngle(float angle, float min, float max)
{
    if (angle < -360) angle += 360;
    if (angle > 360) angle -= 360;
    return Mathf.Clamp(angle, min, max);
}
#endregion

}

相关推荐
时光追逐者1 小时前
C# 哈希查找算法实操
算法·c#·哈希算法
三千道应用题2 小时前
C#语言入门详解(18)传值、输出、引用、数组、具名、可选参数、扩展方法
开发语言·c#
micoos2 小时前
C#-LinqToObject-Element
c#
忧郁的蛋~2 小时前
使用.NET标准库实现多任务并行处理的详细过程
开发语言·c#·.net
kalvin_y_liu2 小时前
四款主流深度相机在Python/C#开发中的典型案例及技术实现方案
开发语言·python·数码相机
格林威5 小时前
工业相机如何通过光度立体成像技术实现高效精准的2.5D缺陷检测
人工智能·深度学习·数码相机·yolo·计算机视觉
点灯小铭5 小时前
基于MATLAB的车牌识别系统
开发语言·单片机·数码相机·matlab·毕业设计·课程设计
索迪迈科技6 小时前
记一次 .NET 某中医药附属医院门诊系统 崩溃分析
windows·c#·.net·windbg
SunflowerCoder6 小时前
WPF迁移avalonia之触发器
c#·wpf·avalonia
长安——归故李10 小时前
【modbus学习】
java·c语言·c++·学习·算法·c#