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

Posted avi9111

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UnityEditor编辑器扩展自己实现了一遍SceneView的镜头移动相关的知识,希望对你有一定的参考价值。

基本实现

由于最近一个星期都比较魔怔《天际线》,突然开始要工作了,用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吧

以上是关于UnityEditor编辑器扩展自己实现了一遍SceneView的镜头移动的主要内容,如果未能解决你的问题,请参考以下文章

UnityEditor编辑器扩展代码实现Project搜索的实现功能和切换Component等

UnityEditor编辑器扩展开发build Settings中build和build and run各自的实现代码

UnityEditor编辑器扩展开发-自定义Shader入门

UnityEditor编辑器扩展开发-自定义Shader入门

UnityEditor编辑器扩展-判断文件类型

UnityEditor编辑器扩展-表格功能