相机围绕物体旋转,并且有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

}

相关推荐
Vae_Mars9 小时前
C#中的delegate委托
开发语言·c#
恒锐丰小瑞12 小时前
率能SS6810H 32V/1A/双通道H桥驱动芯片,PWM电流控制与混合衰减模式,用于POS打印机/安防相机/机器人
嵌入式硬件·数码相机·机器人·硬件工程
公子小六13 小时前
基于.NET的Windows窗体编程之WinForms音频控件
windows·microsoft·c#·.net·音视频·winforms
绿浪198414 小时前
c# 结构体 能不能直接封送检测
开发语言·c#
新手unity自用笔记15 小时前
unity基于Socket的网络学习
网络·网络协议·学习·unity·c#·游戏引擎
恒锐丰小瑞15 小时前
率能SS6812T 40V/1A/双通道H桥驱动芯片,PWM电流控制与混合衰减模式(eTSSOP28),用于POS打印机/安防相机/机器人
单片机·嵌入式硬件·数码相机·机器人
格林威16 小时前
C#图像像素放大:邻域平均、双线性插值实现像素放大的C#实现代码
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·工业相机
AI的探索之旅16 小时前
图像格式与转换一文讲透:相机 / OpenCV / Qt
数码相机·qt·opencv
恒锐丰小瑞17 小时前
率能SS6811H 38V/1.6A/双通道H桥驱动芯片,PWM控制接口与低功耗睡眠模式,用于舞台灯光/安防相机/机器人
单片机·嵌入式硬件·数码相机·机器人
赵药师17 小时前
RGBD相机测尺寸Python以及原理详解
数码相机