UnityEditor编辑器扩展自己实现了一遍SceneView的镜头移动

news2024/9/21 19:31:38

基本实现

由于最近一个星期都比较魔怔《天际线》,突然开始要工作了,用Editor好像突然没了按键反而不习惯

就是要实现一个点击AWSD,能方便编辑地图的功能

其实大可不必自己写代码

  • 本身Unity自带的,飞跃模式已经包含(按鼠标右键)AWSD

就是如下图,摄像机要有一点角度,肯定不是直角的移动

图片来自CSDN某小哥的贴图

protected virtual void OnScene(SceneView obj)
{
    Event e =        Event.current;
    if (e.type == EventType.KeyDown)
    {
         if (e.keyCode == KeyCode.A || e.keyCode == KeyCode.S || e.keyCode == KeyCode.D ||
                        e.keyCode == KeyCode.W)
         {
            // obj     is SceneView
            float h = 0;
            float v = 0;
            if (e.keyCode == KeyCode.A)
                   h = -1;
            else if (e.keyCode == KeyCode.D)
                   h = 1;
            else if (e.keyCode == KeyCode.W)
                   v = 1;
            else if (e.keyCode == KeyCode.S)
                    v = -1; 
            Vector3 targetDirection = new Vector3(h, 0, v);
            float y = obj.camera.transform.rotation.eulerAngles.y;
            targetDirection = Quaternion.Euler(0, y, 0) * targetDirection;
                        //     //TODO:按Shift加速(e.control && e.keyCode == KeyCode.Z)
                        //     //obj.camera.transform.Translate(targetDirection );//直接改camera 这句代码没用
                        //
            obj.pivot += targetDirection * Time.deltaTime * 3;
        }
    }
}
        
//打开EditorWindow扩展时,需调用       
 protected virtual void OnEnable()
        {
          
            SceneView.duringSceneGui += OnScene;

        }

    
        protected virtual void OnDisable()
        {
        
            SceneView.duringSceneGui -= OnScene;
   
        }

是不是就是这么简单?

写代码肯定就没这么简单

结果后来我又调试了两个小时

二次迭代

========== 如果你要的仅仅只是Hello World 代码 ======

上面代码够了,下面代码很乱不要看

原因就是

keyDown只能在GUI用,第一下和第二下还有延迟,为了更顺滑的响应,只能用上。Update了

        protected virtual void OnEnable()
        {
            onRefreshWindow -= Refresh;
            onRefreshWindow += Refresh;
            SceneView.duringSceneGui += OnScene;
            EditorApplication.update += OnSceneUpdate;
        }

    
        protected virtual void OnDisable()
        {
            onRefreshWindow -= Refresh;
            BlockClicks(false);
            SceneView.duringSceneGui -= OnScene;
            EditorApplication.update -= OnSceneUpdate;
        }
    private int longPressCount;
        private SceneView view;
        private float longPressH = 0;
        private float longPressV = 0;
        private float longPressY = 0;//camera y Angle
        private int longPressCountDown = 0;//允许多个按键AWSD多按 ,可以省几个变量了,不改了,睡觉
        private void OnSceneUpdate()
        {
            if (view == null) return;
            if (longPressCount > 0)
            {
                var targetDirection = new Vector3(longPressH, 0, longPressV);

                //    //xxxx判斷長按,跳過第一下按下xxxx
             //    //MD,第一下不能跳过,又需要马上有反应,。。。。。。。。longPressCount>0 逻辑就是为了这个
             //    //  if (longPressCount == 1) return;
             // //   Debug.LogError("ffff key=" + e.keyCode + " pos>" + view.camera.transform.position);
             //    Vector3 targetDirection = new Vector3(longPressH, 0, longPressV);
             //  //  float y = view.camera.transform.rotation.eulerAngles.y;
                    targetDirection = Quaternion.Euler(0, longPressY, 0) * targetDirection;
             //    //TODO:按Shift加速(e.control && e.keyCode == KeyCode.Z)
             
                view.pivot += targetDirection * Time.deltaTime * 3;
            }

        }
    
        protected virtual void OnScene(SceneView obj)
        {
             Event e = Event.current;
            if (e.type == EventType.KeyDown)
            {
       
                if (e.keyCode == KeyCode.A || e.keyCode == KeyCode.S || e.keyCode == KeyCode.D ||
                    e.keyCode == KeyCode.W)
                {
                    
                    if (e.keyCode == KeyCode.A)
                        longPressCountDown  |= 1 << 1;
                    else if (e.keyCode == KeyCode.W)
                        longPressCountDown |= 1 << 2;
                    else if (e.keyCode == KeyCode.S)
                        longPressCountDown |= 1 << 3;
                    else if (e.keyCode == KeyCode.D)
                        longPressCountDown |= 1 << 4;
                    Debug.LogError("longPressCount=" + longPressCountDown);
                    longPressCount++;
                    if (view == null)
                        view = obj;
                    
                    longPressY = obj.camera.transform.rotation.eulerAngles.y;
                    longPressH = 0;
                    longPressV = 0;
                    if (e.keyCode == KeyCode.A)//注意,为了第一下,这下面几个逻辑也是改过的
                        longPressH = -1;
                    
                    if (e.keyCode == KeyCode.D)
                        longPressH = 1;
                    if (e.keyCode == KeyCode.W)
                        longPressV = 1;
                    if (e.keyCode == KeyCode.S)
                        longPressV = -1;
                }

            }
            else if (e.type == EventType.KeyUp)
            {
                if (e.keyCode == KeyCode.A)
                    longPressCountDown  &= ~(1 << 1);
                else if (e.keyCode == KeyCode.W)
                    longPressCountDown &= ~(1 << 2);
                else if (e.keyCode == KeyCode.S)
                    longPressCountDown &= ~(1 << 3);
                else if (e.keyCode == KeyCode.D)
                    longPressCountDown &= ~(1 << 4);
                
                if(longPressCountDown==0)
                    //判斷長按,跳過第一下按下
                    longPressCount = 0;
            }
            
   

        }
    }

最终结果

好了,谢谢阅读,下一篇会说下,SceneView的笔刷Brush吧

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

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

相关文章

抽象工厂模式(Abstract Factory Pattern)

1.抽象工厂模式定义: 抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口&#xff0c;无需指定它们具体的类 2.抽象工厂模式适用场景: 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量…

ONLYOFFICE中的chatGPT是怎样提升工作效率的

几乎一夜之间chatGPT火遍国内外网络&#xff0c;作为一个总是努力提高工作效率并在一天内完成更多工作的人&#xff0c;我很高兴发现 ONLYOFFICE添加了ChatGPT — 一个人工智能驱动的聊天机器人&#xff0c;可以帮助您管理时间、设定目标并改善您的个人和职业生活。 ONLOYOFFIC…

Allegro172版本无法低亮颜色的原因和解决办法

Allegro172版本无法低亮颜色的原因和解决办法 用Allegro版本做PCB设计的时候,高亮是使用非常频繁的功能,低亮已经高亮的对象也是使用较为频繁的。 在用172版本时会出现无法低亮的情况,如下图 使用Dehilight命令无法低亮器件,如何解决,具体操作步骤如下 点击Display选择De…

Python:每日一题之剪邮票(BFS全排列)

如【图1.jpg】, 有12张连在一起的12生肖的邮票。 现在你要从中剪下 5 张来&#xff0c;要求必须是连着的。 &#xff08;仅仅连接一个角不算相连&#xff09; 比如&#xff0c;【图2.jpg】&#xff0c;【图3.jpg】中&#xff0c;粉红色所示部分就是合格的剪取。 请你计算&…

redis的安装步骤及前台,后台redis服务启动

redis的安装步骤1. 官网下载安装包2. 使用Xftp将安装包传输到Linux的opt目录下3. 使用Xshell连接Linux主机进行redis的安装安装目录说明4. redis 服务启动的两种方式4.1 前台启动4.2 后台启动1. 官网下载安装包 首先&#xff0c;我们进入到redis的官网: https://redis.io/down…

代码随想录算法训练营第三十一天 | 贪心专题-理论基础,455.分发饼干,376. 摆动序列,53. 最大子序和

一、参考资料理论基础https://programmercarl.com/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 分发饼干https://programmercarl.com/0455.%E5%88%86%E5%8F%91%E9%A5%BC%E5%B9%B2.html 摆动序列https://programmercarl.com/0376.%E6%91%86…

数据库存储

RAID DSL &#xff1a; Domain Spesic Language 专用领域语言 单机存储 一切皆Key-Value 本地文件系统 一切皆文件 Ceph - 分布式存储 关系型数据库通用组件 Query Engine &#xff1a;解析query&#xff0c;生成查询计划Txn Manager &#xff1a;事务并发管理Lock Man…

知识汇总:Python办公自动化应该学习哪些内容

当前python自动化越来越受到欢迎&#xff0c;python一度成为了加班族的福音。还有大部分人想利用python自动化来简化工作&#xff0c;不知道从何处下手&#xff0c;所以&#xff0c;这里整理了一下python自动化过程中的各种办公场景以及需要用到的python知识点。 Excel办公自动…

【C++】类和对象(第二篇)

文章目录1. 类的6个默认成员函数2. 构造函数2.1 构造函数的引出2.2 构造函数的特性3. 析构函数3.1 析构函数的引出3.2 析构函数的特性4. 拷贝构造函数4.1 概念4.2 特性5.赋值运算符重载5.1 运算符重载概念注意练习5.2 赋值重载实现赋值重载的特性6. const成员函数7. 取地址及co…

传统图机器学习的特征工程

视频资料同济子豪兄中文精讲视频&#xff1a;节点特征工程&#xff1a;https://www.bilibili.com/video/BV1HK411175s连接特征工程&#xff1a;https://www.bilibili.com/video/BV1r3411m7sD全图特征工程&#xff1a;https://www.bilibili.com/video/BV14W4y1V7gg斯坦福原版视频…

spring的事物控制

1.调用这个方法的对象是否是spring的代理对象&#xff08;$CGLIB结尾的&#xff09; 2.这个方法是否是加了Transactional注释 都符合才可以被事物控制 如果调用方法的对象没有被事物控制&#xff0c;那么被调用的方法即便是加了Transactional也是没用的 一个非事务方法调同类…

13.hadoop系列之MapReduce排序实践

本文我们学习MapReduce的全排序、二次排序以及区内排序 1.MapReduce概述 MapTask和ReduceTask均会对数据按照key进行排序。该操作属于hadoop的默认行为。任何应用程序中的数据均会被排序&#xff0c;而不管逻辑上是否需要默认排序是按照字典顺序排序&#xff0c;通过快速排序…

【蓝桥杯嵌入式】第十三届蓝桥杯嵌入式国赛程序设计试题以及详细题解

文章目录原题展示原题分析详细题解LED模块按键模块串口LCD模块模拟电压读取(ADC)脉冲输入输出文章福利原题展示 原题分析 本届国赛试题主要包含LCD、LED、按键、EEPROM、串口、模拟电压输入、脉冲输入输出七大部分&#xff0c;其中前面三个部分是蓝桥杯嵌入式的“亲儿子”(必考…

SpringBoot 集成 Kafka

SpringBoot 集成 Kafka1 安装 Kafka2 创建 Topic3 Java 创建 Topic4 SpringBoot 项目4.1 pom.xml4.2 application.yml4.3 KafkaApplication.java4.4 CustomizePartitioner.java4.5 KafkaInitialConfig.java4.6 SendMessageController.java5 测试1 安装 Kafka Docker 安装 Kafk…

数据库原理及应用期末复习汇总(附某高校期末真题试卷)

文章目录《数据库原理及应用》试题1一、选择题&#xff08;共35分&#xff09;二、填空&#xff08;每空1分&#xff0c;共20分&#xff09;三、T-SQL综合题(共35分)四、综合应用题(共10分)《数据库原理及应用》试题2一、选择题&#xff08;共35分&#xff09;二、填空&#xf…

handler解析(5)常见面试题

目录 1.请大致讲下handler的工作原理 2.handler.postDelay原理 3.一个线程有几个Looper?几个Handler&#xff1f; 4. Handler内存泄漏原因&#xff1f;以及解决方案 5.为何主线程可以new Handler如果想要在子线程中new Handler要做些什么准备&#xff1f; 6.消息退出是调…

R语言广义可加模型在空气环境污染方面的应用(1)

粉丝私信我希望复制一篇文章的图片&#xff0c;图片来源于文章&#xff1a;Wu C, Yan Y, Chen X, Gong J, Guo Y, Zhao Y, Yang N, Dai J, Zhang F, Xiang H. Short-term exposure to ambient air pollution and type 2 diabetes mortality: A population-based time series st…

中频采样和IQ采样的比较和转换

一、什么是中频采样&#xff0c;什么是IQ采样 射频接收系统通常使用数字信号处理算法进行信号解调和分析&#xff0c;因此需要使用ADC对信号进行采样。根据采样频率的不同&#xff0c;可以分为射频直接采样、中频采样、IQ采样。射频采样和中频采样只需要一路ADC&#xff0c;采…

搜索引擎ES相关问题

一、什么是倒排索引&#xff1f;有什么好处&#xff1f;索引&#xff1a; 从ID到内容。倒排索引&#xff1a; 从内容到ID。好处&#xff1a; 比较适合做关键字检索。 可以控制数据的总量。提高查询效率。搜索引擎为什么比MySQL查询快&#xff1f; lucence文章 -》 term ->排…

element-ui中el-table点击其他自定义按钮展开table中某一行

element-ui中el-table点击其他自定义按钮展开table中某一行 在日常开发中&#xff0c;我们遇见了会有点击某些按钮&#xff0c;使得表格行展开的需求&#xff0c;这时候去查看文档 element-ui&#xff08;table&#xff09; 这里官方提供了示例为在行最左侧有一个展开合并ico…