Search Unity

pan in editor with Macbook touchpad?

Discussion in 'Editor & General Support' started by tomatohorse, Aug 6, 2019.

  1. tomatohorse

    tomatohorse

    Joined:
    Oct 26, 2013
    Posts:
    13
    As a Mac user, it feels so unnatural to hold Alt in order to pan around the editor scene view. Most programs on Mac allow two-finger swipes to pan (or scroll) around.

    Pinch-to-zoom would then be used to zoom in and out.

    These two changes would feel so much better and more natural. Can we please get this functionality?
     
  2. tomatohorse

    tomatohorse

    Joined:
    Oct 26, 2013
    Posts:
    13
  3. TreyK-47

    TreyK-47

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    1,820
    Thanks for the suggestion, @tomatohorse! We'll be sure to pass it along for you!
     
    chriseborn and ModLunar like this.
  4. melihaksoy

    melihaksoy

    Joined:
    Nov 17, 2017
    Posts:
    1
    Bump ! This would be great, tbh it's a pain to use trackpad with Unity, as someone who favors trackpad over mouse when the editor this would make my day !
     
    ShadowUser19 likes this.
  5. JPBA1984

    JPBA1984

    Joined:
    Jan 23, 2014
    Posts:
    6
    Same here, please add...
     
    ShadowUser19 likes this.
  6. ShadowUser19

    ShadowUser19

    Joined:
    Apr 7, 2018
    Posts:
    6
    It would be really awesome if trackpad support in Unity is fixed the right way instead of treating it as a zooming device.

    Since I also prefer to use trackpad over mouse, I wrote an editor tool to get the same behavior as Blender.
    The idea is that you only zoom in/out when [CTRL] or [CMD] key is pressed, move the view when [SHIFT] is pressed and pan around when only a two finger gesture is detected.
    Its not perfect however since it doesn't get activated by default & also gets deactivated when another editor tool is triggered (which I work around by setting up a shortcut [G] to switch between back if necessary).

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEditor.EditorTools;
    5. using UnityEngine;
    6.  
    7. namespace Editor
    8. {
    9.     [EditorTool("Scene Navigator")]
    10.     public class SceneNavigator : EditorTool
    11.     {
    12.         private float _lastCameraSize = 1;
    13.         private Vector2? _lastMousePosition = null;
    14.         public override void OnToolGUI(EditorWindow window)
    15.         {
    16.             var currentEvent = Event.current;
    17.             _lastMousePosition = _lastMousePosition ?? currentEvent.mousePosition;
    18.             if (!IsSwipeEvent(currentEvent))
    19.             {
    20.                 base.OnToolGUI(window);
    21.                 _lastCameraSize = SceneView.lastActiveSceneView.size;
    22.                 _lastMousePosition = currentEvent.mousePosition;
    23.             }
    24.             else
    25.             {
    26.                 SceneView.lastActiveSceneView.size = _lastCameraSize;
    27.                 HandleMouse();
    28.             }
    29.         }
    30.  
    31.         private bool IsSwipeEvent(Event currentEvent)
    32.         {
    33.             if (currentEvent.command) return false;
    34.             if (currentEvent.control) return false;
    35.             if (currentEvent.isMouse) return false;
    36.            
    37.             return currentEvent.mousePosition == _lastMousePosition;
    38.         }
    39.  
    40.         private void HandleMouse()
    41.         {
    42.             var currentEvent = Event.current;
    43.             var currentEventDelta = currentEvent.delta;
    44.             if(Math.Abs(currentEventDelta.x) < 1f && Math.Abs(currentEventDelta.y) < 1f) return;
    45.  
    46.            
    47.             if (currentEvent.shift)
    48.             {
    49.                 ApplyPivotLocation(GetNewPivotPointByEventDelta(currentEventDelta));
    50.             }
    51.             else
    52.             {
    53.                 var newRotation = SceneView.lastActiveSceneView.rotation.eulerAngles;
    54.                 newRotation.x += currentEventDelta.y;
    55.                 newRotation.y += currentEventDelta.x;
    56.  
    57.                 ApplyRotation(Quaternion.Euler(newRotation));
    58.             }
    59.         }
    60.  
    61.         private static Vector3 GetNewPivotPointByEventDelta(Vector2 currentEventDelta)
    62.         {
    63.             var sceneCameraTransform = SceneView.lastActiveSceneView.camera.transform;
    64.             var cameraRight = sceneCameraTransform.TransformDirection(Vector3.right) / 10f;
    65.             var cameraDown = sceneCameraTransform.TransformDirection(Vector3.down) / 10f;
    66.             var newPivotPoint = SceneView.lastActiveSceneView.pivot;
    67.             var newCameraOffset = default(Vector3);
    68.             newCameraOffset += cameraRight * currentEventDelta.x;
    69.             newCameraOffset += cameraDown * currentEventDelta.y;
    70.             newPivotPoint += newCameraOffset;
    71.             return newPivotPoint;
    72.         }
    73.  
    74.         private static void ApplyPivotLocation(Vector3 newPivotPoint)
    75.         {
    76.             SceneView.lastActiveSceneView.pivot = newPivotPoint;
    77.         }
    78.  
    79.         private static Vector2? GetRotationOffsetFromKeyboardInput(Event currentEvent)
    80.         {
    81.             if (!currentEvent.isMouse) return null;
    82.            
    83.             var rotationOffset = new Vector2(0, 0); //currentEvent.delta;
    84.             var isLeftPressed = currentEvent.keyCode == KeyCode.LeftArrow;
    85.             var isRightPressed = currentEvent.keyCode == KeyCode.RightArrow;
    86.             rotationOffset.x += isLeftPressed ? 2f : 0;
    87.             rotationOffset.x -= isRightPressed ? 2f : 0;
    88.             var isUpPressed = currentEvent.keyCode == KeyCode.UpArrow;
    89.             var isDownPressed = currentEvent.keyCode == KeyCode.DownArrow;
    90.             rotationOffset.y += isUpPressed ? 2f : 0;
    91.             rotationOffset.y -= isDownPressed ? 2f : 0;
    92.             return rotationOffset;
    93.         }
    94.         private void OnDrawGizmos()
    95.         {
    96.             // Your gizmo drawing thing goes here if required...
    97. #if UNITY_EDITOR
    98.             // Ensure continuous Update calls.
    99.             if (!Application.isPlaying)
    100.             {
    101.                 UnityEditor.EditorApplication.QueuePlayerLoopUpdate();
    102.                 UnityEditor.SceneView.RepaintAll();
    103.             }
    104. #endif
    105.         }
    106.  
    107.         /// <summary>
    108.         /// The rotation to restore when going back to perspective view. If we don't have anything,
    109.         /// default to the 'Front' view. This avoids the problem of an invalid rotation locking out
    110.         /// any further mouse rotation
    111.         /// </summary>
    112.         static Quaternion sPerspectiveRotation = Quaternion.Euler(0, 0, 0);
    113.  
    114.         /// <summary>
    115.         /// Whether the camera should tween between views or snap directly to them
    116.         /// </summary>
    117.         static bool sShouldTween = false;
    118.  
    119.         /// <summary>
    120.         /// When switching from a perspective view to an orthographic view, record the rotation so
    121.         /// we can restore it later
    122.         /// </summary>
    123.         static private void StorePerspective()
    124.         {
    125.             if (SceneView.lastActiveSceneView.orthographic == false)
    126.             {
    127.                 sPerspectiveRotation = SceneView.lastActiveSceneView.rotation;
    128.             }
    129.         }
    130.  
    131.         static private void ApplyRotation(Quaternion newRotation)
    132.         {
    133.             var shouldApplyPerspectiveRotation = !(SceneView.lastActiveSceneView.orthographic);
    134.             ApplyOrthoRotation(newRotation);
    135.             if(shouldApplyPerspectiveRotation)
    136.             {
    137.                 PerspCamera();
    138.             }      
    139.             var appliedRotation = SceneView.lastActiveSceneView.rotation.eulerAngles;
    140.             //Debug.Log($"rotationx has been reset to: {appliedRotation.x}");
    141.         }
    142.  
    143.         /// <summary>
    144.         /// Apply an orthographic view to the scene views camera. This stores the previously active
    145.         /// perspective rotation if required
    146.         /// </summary>
    147.         /// <param name="newRotation">The new rotation for the orthographic camera</param>
    148.         static private void ApplyOrthoRotation(Quaternion newRotation)
    149.         {
    150.             StorePerspective();
    151.  
    152.             SceneView.lastActiveSceneView.orthographic = true;
    153.  
    154.             if (sShouldTween)
    155.             {
    156.                 SceneView.lastActiveSceneView.LookAt(SceneView.lastActiveSceneView.pivot, newRotation);
    157.             }
    158.             else
    159.             {
    160.                 SceneView.lastActiveSceneView.LookAtDirect(SceneView.lastActiveSceneView.pivot, newRotation);
    161.             }
    162.  
    163.             SceneView.lastActiveSceneView.Repaint();
    164.         }
    165.  
    166.         [MenuItem("Camera/MoveToUp _8")]
    167.         static void MoveToUpCamera()
    168.         {
    169.             var newRotation = SceneView.lastActiveSceneView.rotation.eulerAngles;
    170.             newRotation.x += 10;
    171.             ApplyRotation(Quaternion.Euler(newRotation));
    172.         }
    173.  
    174.         [MenuItem("Camera/Top _7")]
    175.         static void TopCamera()
    176.         {
    177.             ApplyRotation(Quaternion.Euler(90, 0, 0));
    178.         }
    179.  
    180.         [MenuItem("Camera/MoveToDown _2")]
    181.         static void MoveToDownCamera()
    182.         {
    183.             var newRotation = SceneView.lastActiveSceneView.rotation.eulerAngles;
    184.             newRotation.x -= 10;
    185.             ApplyRotation(Quaternion.Euler(newRotation));
    186.         }
    187.  
    188.         [MenuItem("Camera/Bottom #7")]
    189.         static void BottomCamera()
    190.         {
    191.             ApplyRotation(Quaternion.Euler(-90, 0, 0));
    192.         }
    193.  
    194.  
    195.         [MenuItem("Camera/Left #3")]
    196.         static void LeftCamera()
    197.         {
    198.             ApplyRotation(Quaternion.Euler(0, 90, 0));
    199.         }
    200.  
    201.  
    202.         [MenuItem("Camera/Right _3")]
    203.         static void RightCamera()
    204.         {
    205.             ApplyRotation(Quaternion.Euler(0, -90, 0));
    206.         }
    207.  
    208.  
    209.         [MenuItem("Camera/Front _1")]
    210.         static void FrontCamera()
    211.         {
    212.             ApplyRotation(Quaternion.Euler(0, 180, 0));
    213.         }
    214.  
    215.         [MenuItem("Camera/MoveToRight _6")]
    216.         static void MoveToRightCamera()
    217.         {
    218.             var newRotation = SceneView.lastActiveSceneView.rotation.eulerAngles;
    219.             newRotation.y -= 10;
    220.             ApplyRotation(Quaternion.Euler(newRotation));
    221.         }
    222.  
    223.         [MenuItem("Camera/MoveToLeft _4")]
    224.         static void MoveToLeftCamera()
    225.         {
    226.             var newRotation = SceneView.lastActiveSceneView.rotation.eulerAngles;
    227.             newRotation.y += 10;
    228.             ApplyRotation(Quaternion.Euler(newRotation));
    229.         }
    230.  
    231.         [MenuItem("Camera/Back #1")]
    232.         static void BackCamera()
    233.         {
    234.             ApplyRotation(Quaternion.Euler(0, 0, 0));
    235.         }
    236.  
    237.  
    238.         [MenuItem("Camera/Persp Camera _5")]
    239.         static void PerspCamera()
    240.         {
    241.             var isOrthographic = SceneView.lastActiveSceneView.orthographic;
    242.             SceneView.lastActiveSceneView.orthographic = !isOrthographic;
    243.             SceneView.lastActiveSceneView.Repaint();
    244.         }
    245.  
    246.         private static Tool _previousToolMode;
    247.         [MenuItem("Edit/Toggle custom tool _G", false, 5)]
    248.         static void ToggleCustomTool()
    249.         {
    250.             Debug.Log($"Current tool mode: {Tools.current}");
    251.             if (Tools.current != Tool.Custom)
    252.             {
    253.                 _previousToolMode = Tools.current;
    254.                 Tools.current = Tool.Custom;
    255.             }
    256.             else
    257.             {
    258.                 Tools.current = _previousToolMode;
    259.             }
    260.         }
    261.     }
    262. }
     
    ModLunar and Jae_Kong like this.
  7. nickwing

    nickwing

    Joined:
    May 20, 2017
    Posts:
    2
    any updated ??
     
  8. ModLunar

    ModLunar

    Joined:
    Oct 16, 2016
    Posts:
    374
    This would make life a lot easier in Unity when I don't have a mouse available for my laptop!
    Bump! :)
     
  9. lukasynthetic

    lukasynthetic

    Joined:
    May 20, 2020
    Posts:
    30
    Please add...
     
  10. benthroop

    benthroop

    Joined:
    Jan 5, 2007
    Posts:
    262
    I love this idea.
     
  11. Jae_Kong

    Jae_Kong

    Joined:
    Dec 31, 2021
    Posts:
    1
    +1. Blender really nails the trackpad control on macOS. I hope we could get something like this in Unity by default.
     
    WindReiter and ModLunar like this.
  12. Francoimora

    Francoimora

    Joined:
    Aug 1, 2013
    Posts:
    68
    +1. All the softwares we use have the behaviour described in the first post, except Unity. It makes navigation a pain when I'm not at home.
     
  13. Fulcrum_Games

    Fulcrum_Games

    Joined:
    Oct 21, 2020
    Posts:
    3
    Has this still not been implemented yet? Bump. Need better navigation with trackpad.
     
  14. virtualgarage

    virtualgarage

    Joined:
    Dec 19, 2020
    Posts:
    1
  15. khushalkhan

    khushalkhan

    Joined:
    Aug 6, 2016
    Posts:
    177
    Seems like unity does not care, waiting for years just to add simple basic hardware support.
     
  16. lukasynthetic

    lukasynthetic

    Joined:
    May 20, 2020
    Posts:
    30
    Unity, please listen to us! You've made an effort to develop a separate version of editor to use on silicon Mac's, while ignoring the most fundamental aspect of working on Mac machines!!!
    Please.
     
  17. shivaprasad_unity

    shivaprasad_unity

    Joined:
    Mar 30, 2021
    Posts:
    19
  18. gavrilyuc

    gavrilyuc

    Joined:
    May 29, 2022
    Posts:
    1
  19. grokmann

    grokmann

    Joined:
    May 20, 2019
    Posts:
    1
    @TreyK-47: Is this being tracked as an issue in a backlog? Is it in progress? Thanks.
     
    ModLunar likes this.
  20. martinrg

    martinrg

    Joined:
    Nov 30, 2022
    Posts:
    1
  21. dtuluu

    dtuluu

    Joined:
    Aug 27, 2022
    Posts:
    1
    +1000
     
  22. LevonVH

    LevonVH

    Joined:
    Dec 16, 2016
    Posts:
    19
    So after 3 years, there's still no update on this feature? This is ridiculous.
     
    Unifikation likes this.
  23. chairmaker

    chairmaker

    Joined:
    Apr 19, 2018
    Posts:
    3
    2023, still need this. When switching back and forth between Blender and Unity it's clear Unity's trackpad control scheme lacks in responsiveness, speed, precision and overall usability.

    In Blender, which uses more universal and modern gestures for basic actions, i can easily work half a day without feeling a strong need to use a mouse. Then i'd switch to avoid wrist strain, but it's still shockingly usable in comparison.
     
    Last edited: Mar 29, 2023
  24. fabiojscosta1583

    fabiojscosta1583

    Joined:
    May 3, 2021
    Posts:
    4
  25. Shrandon

    Shrandon

    Joined:
    Nov 13, 2012
    Posts:
    5
  26. martinharris2706

    martinharris2706

    Joined:
    Apr 12, 2023
    Posts:
    1
    I understand that using the Alt key to pan in the editor scene view may feel unnatural for Mac users, and I appreciate your feedback on this. As an AI language model, I don't have control over the development of software applications. However, I can suggest a few things that might help:

    1. Check if the editor application you're using has customizable key bindings. If it does, you may be able to change the key binding for panning to something that feels more natural for you.

    2. Consider using a third-party tool like BetterTouchTool or MagicPrefs, which can customize touchpad gestures on a Mac. You may be able to set up a two-finger swipe gesture for panning in your editor application using one of these tools.

    3. Contact the developer of the editor application and request the addition of two-finger swipe gestures for panning and pinch-to-zoom functionality. Developers often welcome user feedback and suggestions, so your input could be valuable in improving the user experience of the application.
     
  27. JakeT

    JakeT

    Joined:
    Nov 14, 2010
    Posts:
    34
  28. FourSevenEnt

    FourSevenEnt

    Joined:
    Apr 20, 2023
    Posts:
    1
    Still unity hasnt done anything about this.. ive spent like 4 hours on google "how to navigate like blender in unity " "how to move around in unity like blender with touchpad"..i did run across some TouchScript library that seemed pretty F***ing legit but its from 2017 and outdated so didnt bother... CMON UNITY WHAT GIVES... show some love to trackpad folks here .. smh
     
    Unifikation likes this.
  29. Unifikation

    Unifikation

    Joined:
    Jan 4, 2023
    Posts:
    1,086
    Why not do it the smart way... have 3 different new control schemes for view/scene navigation:

    3ds Max mode
    Maya Mode
    Blender Mode
    Unity Legacy Mode (the current pickle)
     
  30. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,433
    Laptops are damned limited. Pretty much any 3D software (Blender, Unity, Maya, CAD programs, etc.) will be greatly enhanced by going out and getting a real mouse with real right and middle mouse buttons. You don't have to go way out and get some sort of "space mouse" or 6dof controller, but really, limping along on a laptop keyboard with no numpad, a bunch of everyday keys behind a Fn modifier, and a wimpy trackpad is just such a confining situation. Yeah, I get it, a laptop is portable and does 90% of what you want a desktop to do... but those 10% aren't insignificant.
     
  31. Unifikation

    Unifikation

    Joined:
    Jan 4, 2023
    Posts:
    1,086
    You're describing a windows trackpad.

    Macs have significantly superior trackpads.
     
  32. lborreroluz

    lborreroluz

    Joined:
    Oct 24, 2015
    Posts:
    1
    Click on the lock in the gizmo and it will allow you to pan in the XY plane:
    Screen Shot 2023-11-18 at 3.03.20 PM.png