Unity (macOS) でマウスをワープさせたら 0.25 秒カーソルが固定される話 

何があったか

Unityにおいて、マウスカーソルと、Objectのアニメーションの移動が関係する箇所の手触りを良くするために、Mouse.WarpCursorPosition でワープさせていた。

すると、Macでのみ、Warpから短時間、マウスカーソルが移動しなくなる現象に出会った。

何が起きていたか

macOS の仕様を調べると、CGWarpMouseCursorPosition 周りで複数の言及を発見できた。

  •  UnityのMouse.WarpCursorPosition は、macOS では内部で CGWarpMouseCursorPosition を呼んでいるような挙動をする
  •  CGWarpMouseCursorPosition は なにかしらの都合で CGAssociateMouseAndMouseCursorPosition(false) を呼んでいる可能性がある
    • (Trueにして解決したため、というだけの推測)
    • これにより、OS カーソル位置が Warp 最終実行時の位置に固定され、約 0.25 秒間 は物理マウスを動かしても OS 位置が更新されない(delta は来る) 
      • 0.25秒は手元で動画を取っての実測値
      • CGEventSourceSetLocalEventsSuppressionInterval のデフォルト秒数などと一致しているのでなんか関係ありそう
  • 0.25 秒経つと通常の追従に戻る

明確なソースを見つけることができず、いろんな方がそれに言及しているのを見て察することとなった。

参考

https://github.com/wine-mirror/wine/blob/504683b22d3717e6ed073ed362c75c59a2e9d9c7/dlls/winemac.drv/cocoa_app.m#L1158-L1171

どう解決したか

  public class HogeInputManager : MonoBehaviour                                                                                                                           
  {                                                               
  #if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
      const string CoreGraphics =        "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/CoreGraphics";                                                                                 
      [DllImport(CoreGraphics)]                                   
      static extern int CGAssociateMouseAndMouseCursorPosition(bool connected);                                                                                 
  #endif
      void WarpCursorPosition(Vector2 position)                                                                                                                 
      {                                                           
          Mouse.current.WarpCursorPosition(position);
  #if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX                                                                                                                  
          CGAssociateMouseAndMouseCursorPosition(true);
  #endif                                                                                                                                                        
      }                                                           
  }       

コメントを残す

メールアドレスが公開されることはありません。必須項目には印がついています *