unity 限制 相机移动 区域(无需碰撞检测)

news2024/11/19 18:37:11

限制功能原著地址:unity限制相机可移动区域(box collider)_unity限制相机移动区域_manson-liao的博客-CSDN博客

一、创建限制区域

创建一个Cube,Scale大小=1,添加组件:BoxCollder,调整BoxCollder的Size(此为限制区域)

二、代码(功能:WADS(或者上下左右方向键)以及使用Q E上升下降移动和鼠标等控制相机的移动转向等,限制功能是类里的方法为:limitation(),放在Update里执行即可)


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
namespace Twq
{
    /// <summary>
    /// wasd控制  (使用中)
    /// </summary>
    public class CameraController03 : MonoBehaviour
    {

        public static CameraController03 Instance;
        [Header("模型")]
        public Transform targetmodel;
        public static Transform target;
        [Header("鼠标滚轮灵敏度")]
        [SerializeField]
        private int MouseWheelSensitivity = 2;
        [Header("最近距离")]
        [SerializeField]
        public int MouseZoomMin = 750;
        [Header("最远距离")]
        [SerializeField]
        public int MouseZoomMax = 2000;

        [Header("水平旋转速度")]
        [SerializeField]
        private float xSpeed = 150.0f;
        [Header("竖直旋转速度")]
        [SerializeField]
        private float ySpeed = 80.0f;
        [Header("鼠标移动灵敏度")]
        [SerializeField]
        private float mouseMoveSensitivity = 3.0f;

        [Header("角度限制")]
        [SerializeField]
        private int yMinLimit = 0;
        [SerializeField]
        private int yMaxLimit = 89;

        [Header("摄像机初始角度")]
        [SerializeField]
        private float xRot = 0;
        [SerializeField]
        private float yRot = 0;


        [Header("摄像机位置")]
        [SerializeField]
        private Vector3 camPos;//= new Vector3(0, 0, 0);
        public float normalDistance;//初始摄像机距离,无法在面板显示

        public static float x;//= 69f;
        public static float y;// 34.2f;


        private Quaternion rotation;
        public static Vector3 CameraTarget;
        // [HideInInspector]
        public bool isExit;//打开 控制相机
        public bool isShuBiao;//Flase=拉近 状态

        public Transform SelfTransform;
        private void Awake()
        {
            Instance = this;
            SelfTransform = this.transform;
        }
        void Start()
        {
            //初始化
            isExit = true;
            isShuBiao = true;
            x = yRot;
            y = xRot;
            target = targetmodel;
            Vector3 posC = camPos - target.position;
            normalDistance = Mathf.Sqrt(Mathf.Pow(posC.x, 2) + Mathf.Pow(posC.y, 2) + Mathf.Pow(posC.z, 2));

            rotation = Quaternion.Euler(new Vector3(y, x, 0f));

            transform.rotation = rotation;
            float z = target.transform.position.z - normalDistance;
            transform.position = camPos;//rotation * new Vector3(transform.position.x, transform.position.y, z);
            CameraTarget = transform.position + transform.forward.normalized * normalDistance;

            x = transform.localEulerAngles.x;
            y = transform.localEulerAngles.y;

        }
        public void Init()
        {
            isExit = true;
            isShuBiao = true;

            Vector3 posC = camPos - target.position;

            normalDistance = Mathf.Sqrt(Mathf.Pow(posC.x, 2) + Mathf.Pow(posC.y, 2) + Mathf.Pow(posC.z, 2));

            rotation = Quaternion.Euler(new Vector3(90f, 0f, 0f));

            transform.rotation = rotation;

            transform.position = new Vector3(0f, 0f, 0f);
            CameraTarget = transform.position + transform.forward.normalized * normalDistance;

            x = transform.localEulerAngles.x;
            y = transform.localEulerAngles.y;

        }
        public float movespeed = 500;
        void LateUpdate()
        {
            if (IsPointerOverGameObject(Input.mousePosition))
                if (isExit)
                {
                    if (isShuBiao)
                    {
                        // 定义3个值控制移动
                        float xm = 0, zm = 0;

                       
                        if (Input.GetKey(KeyCode.Q)) //上升
                        {
                            if (transform.position.y >= MouseZoomMax)//限制 最大距离
                            {
                                transform.position = new Vector3(transform.position.x, MouseZoomMax, transform.position.z);
                            }
                            else
                            {
                                transform.position = new Vector3(transform.position.x, transform.position.y +movespeed * Time.deltaTime, transform.position.z);
                            }
                        }
                        else if ( Input.GetKey(KeyCode.E))//下降
                        {
                            if (transform.position.y <= MouseZoomMin)//限制 最小距离
                            {
                                transform.position = new Vector3(transform.position.x, MouseZoomMin, transform.position.z);
                            }
                            else
                            {
                                transform.position = new Vector3(transform.position.x, transform.position.y - movespeed * Time.deltaTime, transform.position.z);
                            }
                        }

                        //按键盘W向上移动
                        if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.W))
                        {

                            if (transform.position.y < MouseZoomMin)//限制 最小距离
                            {
                                transform.position = new Vector3(transform.position.x, MouseZoomMin, transform.position.z);
                            }
                            else
                            {
                                this.transform.Translate(Vector3.forward * movespeed * Time.deltaTime);
                            }

                        }
                        else if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S))//按键盘S向下移动
                        {
                            if (transform.position.y > MouseZoomMax)//限制 最大距离
                            {
                                transform.position = new Vector3(transform.position.x, MouseZoomMax, transform.position.z);
                            }
                            else
                            {
                                this.transform.Translate(Vector3.back * movespeed * Time.deltaTime);
                            }

                        }

                        if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.A))//按键盘A向左移动
                        {
                            // xm -= 500 * Time.deltaTime;
                            this.transform.Translate(Vector3.left * movespeed * Time.deltaTime);
                        }
                        else if (Input.GetKey(KeyCode.RightArrow) || Input.GetKey(KeyCode.D))//按键盘D向右移动
                        {
                            //  xm += 500 * Time.deltaTime;
                            this.transform.Translate(Vector3.right * movespeed * Time.deltaTime);
                        }
                        if (Input.GetMouseButton(GlobalVariableManage.GetMouseButtonType))// 1鼠标右键  0鼠标左键
                        {
                            y += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
                            x -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
                            x = ClampAngle(x, yMinLimit, yMaxLimit);
                            var rotation = Quaternion.Euler(x, y, 0);

                            transform.rotation = rotation;
                        }
                        else if (Input.GetAxis("Mouse ScrollWheel") != 0)//鼠标滚轮
                        {
                            //  normalized = (transform.position - CameraTarget).normalized;
                            if (normalDistance >= MouseZoomMin && normalDistance <= MouseZoomMax)
                            {
                                this.transform.position += this.transform.forward * Input.GetAxisRaw("Mouse ScrollWheel") * Time.timeScale * MouseWheelSensitivity;
                                Vector3 p = this.transform.position - CameraTarget;
                                normalDistance = Mathf.Sqrt(Mathf.Pow(p.x, 2) + Mathf.Pow(p.y, 2) + Mathf.Pow(p.z, 2));
                            }
                            if (normalDistance < MouseZoomMin)
                            {
                                normalDistance = MouseZoomMin;
                            }
                            if (normalDistance > MouseZoomMax)
                            {
                                normalDistance = MouseZoomMax;
                            }
                            if (transform.position.y < MouseZoomMin)//限制 最小距离
                            {
                                transform.position = new Vector3(transform.position.x, MouseZoomMin, transform.position.z);
                            }
                            if (transform.position.y > MouseZoomMax)//限制 最大距离
                            {
                                transform.position = new Vector3(transform.position.x, MouseZoomMax, transform.position.z);
                            }
                        }

                    }
                    else
                    {
                        if (transform.position.y > MouseZoomMax)//限制 最小距离
                        {
                            isShuBiao = true;
                        }
                        //缩放
                        if (Input.GetAxis("Mouse ScrollWheel") > 0)
                        {
                            transform.Translate(Vector3.forward * 100f);//速度可调  自行调整
                        }
                        if (Input.GetAxis("Mouse ScrollWheel") < 0)
                        {
                            transform.Translate(Vector3.forward * -100f);//速度可调  自行调整
                        }
                        //旋转 
                        x = transform.localEulerAngles.x;
                        y = transform.localEulerAngles.y;

                    }
                    limitation();
                }
        }

        public GameObject box;
//限制区域

        private void limitation()
        {
            if (box)
            {
                Vector3 boxSize = box.GetComponent<BoxCollider>().size;
                Vector3 boxCenter = box.GetComponent<BoxCollider>().center;
                Vector3 min = box.transform.position + boxCenter - boxSize * 0.5f;
                Vector3 max = box.transform.position + boxCenter + boxSize * 0.5f;

                Vector3 cameraP = transform.position;

                Debug.Log("min.x="+ min.x+ "  max.x="+ max.x);


                if (cameraP.x < min.x)
                {
                    cameraP.x = min.x;
                }
                else if (cameraP.x > max.x)
                {
                    cameraP.x = max.x;
                }

                //if (cameraP.y < min.y)
                //{
                //    cameraP.y = min.y;
                //}
                //else if (cameraP.y > max.y)
                //{
                //    cameraP.y = max.y;
                //}

                if (cameraP.z < min.z)
                {
                    cameraP.z = min.z;
                }
                else if (cameraP.z > max.z)
                {
                    cameraP.z = max.z;
                }

                transform.position = cameraP;
            }

        }





        /// <summary>
        /// 检测是否点击UI
        /// </summary>
        /// <param name="mousePosition">鼠标位置</param>
        /// <returns></returns>
        private bool IsPointerOverGameObject(Vector2 mousePosition)
        {
            //创建一个点击事件
            PointerEventData eventData = new PointerEventData(EventSystem.current);
            eventData.position = mousePosition;
            List<RaycastResult> raycastResults = new List<RaycastResult>();
            //向点击位置发射一条射线,检测是否点击UI
            EventSystem.current.RaycastAll(eventData, raycastResults);
            if (raycastResults.Count > 0)//大于0 说明 有UI
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        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);
        }

        //--------------------围绕的物体并且 相机定位物体-------------------//
        #region
        //public Transform CenObj;//围绕的物体
        //private Vector3 Rotion_Transform;
        //private new Camera camera;

        bool bo;


        //private Transform mainCameraTr;                                               //主摄像机
        //public Transform lookAtTarget;                                          //摄像机看向的目标
        //private float cameraDistance = 50.0F;                                     //摄像机与看向目标的距离
        //private float cameraHeight = 800.0F;                                       //摄像机高度
        //private float cmaeraOffset = 1000.0F;                                       //摄像机的偏移
        //private float mainCameraMoveSpeed = 1F;                                  //主摄像机移动的速度

        //private Vector3 lookAtTargetPosition;                                  //看向目标时的位置
        //private Quaternion lookAtTargetRotation;                               //看向目标,且旋转

        //public bool isLookAtAppointTarget = false;                                //是否看向指定的物体


        //public void SetInit(Transform CenObj_)
        //{
        //    Debug.Log("点击了=" + CenObj_.name);

        //    isShuBiao = true;
        //    CenObj = CenObj_;
        //    Rotion_Transform = CenObj.position;

        //    lookAtTarget = CenObj_;
        //    LookAtAppointTarget();
        //    isShuBiao = false;
        //}
        //void Update()
        //{
        //    //if (!isExit)
        //    //{
        //    //    Ctrl_Cam_Move();
        //    //    Cam_Ctrl_Rotation();
        //    //}
        //}


        / <summary>
        / 摄像机看向指定物体的方法
        / </summary>
        //public void LookAtAppointTarget()
        //{
        //    if (lookAtTarget != null)
        //    {
        //        lookAtTargetPosition = new Vector3(lookAtTarget.transform.position.x + cmaeraOffset,
        //           lookAtTarget.transform.position.y + cameraHeight, lookAtTarget.transform.position.z + cameraDistance);
        //        isLookAtAppointTarget = true;

        //    }
        //    else
        //    {
        //        Debug.LogError(GetType() + "/LookAtAppointTarget()/看向的物体不存在,请检查!!!");
        //    }

        //    if (isLookAtAppointTarget == true)//是否看向物体
        //    {
        //        mainCameraTr.position = Vector3.Lerp(mainCameraTr.position, lookAtTargetPosition, 1 * mainCameraMoveSpeed);
        //        mainCameraTr.LookAt(lookAtTarget);
        //    }
        //    //if (isBack == true)
        //    //{
        //    //    mainCameraTr.position = Vector3.Lerp(mainCameraTr.position, lookAtTargetPosition, 10 * mainCameraMoveSpeed);
        //    //}
        //}
        #endregion
    }
}



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1046540.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

花式打印0~100中3的倍数

列表解析3的倍数负步长切片倒序&#xff0c;iter、zip函数配合实现分行格式打印。 (本笔记适合熟悉python列表解析式的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程…

【开发篇】九、SpringBoot整合ES(ElasticSearch)

文章目录 1、整合2、简单示例3、一点补充4、增删改查索引与文档 1、整合 整合思路都一样&#xff0c;先起步依赖或普通依赖&#xff0c;再配置&#xff0c;再封装的操作对象。先引入依赖&#xff1a; <dependency> <groupId>org.springframework.boot</grou…

电子签章软件怎么安装?选本地私有还是SaaS云?

出于高效便捷、安全防伪&#xff0c;以及跟上数字化转型趋势的考虑&#xff0c;越来越多的企业开始考虑使用电子签章软件。 但是每当企业考虑购买电子签章软件时&#xff0c;往往都会面对本地私有部署和SaaS公有云两种不同的电子签章软件安装部署方式&#xff0c;而不知道到底应…

使用c++实现输出爱心(软件:visual Studio)

#include <iostream> using namespace std;int main() {//爱心曲线方程(x^2y^2-a)^3-x^2*y30double a 0.5;//定义绘图边界double bound 1.3 * sqrt(a);//x,y坐标变化步长double step 0.05;//二维扫描所有点,外层逐层扫描for (double y bound; y > -bound; y - ste…

DeepSpeed4Science:利用先进的AI系统优化技术实现科学发现

本文转载自微软 DeepSpeed 团队官方知乎账号&#xff1a;zhihu.com/people/deepspeed&#xff0c;由微软 DeepSpeed 团队翻译自官方英文博客&#xff1a;Announcing the DeepSpeed4Science Initiative: Enabling large-scale scientific discovery through sophisticated AI sy…

机器学习,深度学习

一 、Numpy 1.1 安装numpy 2.2 Numpy操作数组 jupyter扩展插件&#xff08;用于显示目录&#xff09; 1、pip install jupyter_contrib_nbextensions -i https://pypi.tuna.tsinghua.edu.cn/simple 2、pip install jupyter_nbextensions_configurator -i https://pypi.tuna.t…

26069-2022 硅单晶退火片 思维导图

声明 本文是学习GB-T 26069-2022 硅单晶退火片. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件规定了硅单晶退火片(以下简称退火片)的分类、技术要求、试验方法、检验规则、包装、标志、 运输、贮存、随行文件及订货单内容。 本文件…

如何去开展软件测试工作

1. 软件测试 在一般的项目中&#xff0c;一开始均为手动测试&#xff0c;由于自动化测试前期投入较大&#xff0c;一般要软件项目达到一定的规模&#xff0c;更新频次和质量均有一定要求时才会上自动化测试或软件测试。 1.1. 项目中每个成员的测试职责 软件测试从来不是某一…

windows server 远程桌面服务配置和授权解决方法

适用&#xff1a;win server 2016以上 win server默认的连接数是两个用户。 1.添加远程桌面授权服务 第一步&#xff1a;服务器管理 - 添加角色和功能打开添加角色和功能向导窗口&#xff0c;选择基于角色或给予功能安装 第二步&#xff1a;添加远程桌面会话主机和远程桌面授…

Serlet API详解

目录 一、HttpServlet 1.1 处理doGet请求 1.2 处理doPost请求 二、HttpServletRequest 2.1 核心方法 三、HttpServletRespons 3.1 核心方法 一、HttpServlet 在编写Servlet代码的时候&#xff0c;首先第一步要做的就是继承HttpServlet类&#xff0c;并重写其中的某些方法 核心…

Java-day18(网络编程)

网络编程 1.概述 Java提供跨平台的网络类库&#xff0c;可以实现无痛的网络连接&#xff0c;程序员面对的是一个统一的网络编程环境 网络编程的目的&#xff1a;直接或间接地通过网络协议与其他计算机进行通信 网络编程的两个主要问题&#xff1a; 1.如何准确定位网络上一台…

MybatisPlus自定义SQL用法

1、功能概述&#xff1f; MybatisPlus框架提供了BaseMapper接口供我们使用&#xff0c;大大的方便了我们的基础开发&#xff0c;但是BaseMapper中提供的方法很多情况下不够用&#xff0c;这个时候我们依旧需要自定义SQL,也就是跟mybatis的用法相同&#xff0c;自定义xml映射文…

VS CODE中的筛选器如何打开?

最近更新了vscode1.82版本&#xff0c;发现在git管理界面有一个“筛选器”功能&#xff0c;十分好用&#xff0c;后来关掉了&#xff0c;找了好久都没有找到办法打开这个筛选器功能&#xff0c;今天无意中不知道按到了哪个快捷键&#xff0c;打开了&#xff0c;就是下图这个&am…

矿山无人驾驶的“奇点时刻”

三年前&#xff0c;矿山无人驾驶赛道还处于整个自动驾驶产业“鄙视链的最底端”&#xff1b;但三年后的今天&#xff0c;这个赛道&#xff0c;却成了无人驾驶&#xff08;L4&#xff09;商业化落地难得的亮点——当前&#xff0c;头部的几家矿山无人驾驶公司都已实现去安全员运…

C#WPF通知更改公共类使用实例

本文实例演示C#WPF通知更改公共类使用实例,通过使用公共类简化了代码。其中的代码中也实现了命令的用法。 定义: INotifyPropertyChanged 接口:用于向客户端(通常是执行绑定的客户端)发出某一属性值已更改的通知。 首先创建WPF项目,添加按钮和文本控件 <Window x:C…

05-Zookeeper典型使用场景实战

上一篇&#xff1a;04-Zookeeper集群详解 1. Zookeeper 分布式锁加锁原理 如上实现方式在并发问题比较严重的情况下&#xff0c;性能会下降的比较厉害&#xff0c;主要原因是&#xff0c;所有的连接都在对同一个节点进行监听&#xff0c;当服务器检测到删除事件时&#xff0c…

平面设计cdr和ai有什么区别,哪个好用?2023年全新功能解析

平面设计cdr和ai有什么区别 我们做设计的同学经常会把cdr和ai来做比较。要知道&#xff0c;cdr和ai软件都是可以制作专业的矢量图。二者在功能上各有千秋&#xff0c;在绘图领域中也是平分秋色&#xff0c;绝大多数的效果&#xff0c;谁都能完成。但是对于操作方面&#xff0c;…

vue3 - 使用 xlsx 库将数据导出到 Excel 文件

GitHub Demo 地址 在线预览 xlsx是由SheetJS开发的一个处理excel文件的JavaScript库。它可以读取、编写和操作 Excel 文件 安装xlsx npm install xlsx --save实现一个通过的数据导出工具类 import * as XLSX from xlsx/*** description: 导出excel* param {any} dataList* p…

西域商品详情数据接口

西域平台是西域智慧供应链&#xff08;上海&#xff09;股份公司旗下的MRO工业品B2B电商采购平台。 西域平台成立于2002年&#xff0c;于2009年进入MRO工业品B2B电商行业。经过十多年深耕与探索&#xff0c;西域平台已为包括80%央国企及60%的全球500强企业在内的3万余家国内外…

Qt5开发及实例V2.0-第十章Qt网络与通信

Qt5开发及实例V2.0-第十章Qt网络与通信 第10章 Qt 5网络与通信10.1 获取本机网络信息10.2 基于UDP的网络广播程序10.2.1 UDP协议工作原理10.2.2 UDP 编程模型10.2.3 【实例】&#xff1a;UDP服务器编程10.2.4 【实例】&#xff1a;UDP客户端编程 10.3 基于TCP的网络聊天室程序1…