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

}

相关推荐
合方圆~小文9 小时前
AI摄像头精准识别技术依赖于深度算法
数据结构·数据库·数码相机·模块测试
无限进步_9 小时前
C语言数组元素删除算法详解:从基础实现到性能优化
c语言·开发语言·windows·git·算法·github·visual studio
自由的好好干活11 小时前
使用Qoder编写ztdaq的C#跨平台示例总结
linux·windows·c#·qoder
FuckPatience12 小时前
C# 实现元素索引由1开始的链表
开发语言·链表·c#
我是唐青枫16 小时前
C#.NET 范围与索引(Range、Index)完全解析:语法、用法与最佳实践
c#·.net
烛阴17 小时前
从`new()`到`.DoSomething()`:一篇讲透C#方法与构造函数的终极指南
前端·c#
深海潜水员18 小时前
【MonoGame游戏开发】| 牧场物语实现 第一卷 : 农场基础实现 (下)
vscode·游戏·c#·.net·monogame
合作小小程序员小小店19 小时前
图书管理系统,基于winform+sql sever,开发语言c#,数据库mysql
开发语言·数据库·sql·microsoft·c#
大侠课堂1 天前
C#经典面试题100道
开发语言·c#
时光追逐者1 天前
Visual Studio 2026 现已正式发布,更快、更智能!
ide·c#·.net·visual studio