何があったか
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 秒経つと通常の追従に戻る
明確なソースを見つけることができず、いろんな方がそれに言及しているのを見て察することとなった。
参考
どう解決したか
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
}
}
