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;
   
        }

是不是就是这么简单?

扫描二维码关注公众号,回复: 14694581 查看本文章

写代码肯定就没这么简单

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

二次迭代

========== 如果你要的仅仅只是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吧

猜你喜欢

转载自blog.csdn.net/avi9111/article/details/129076638