Defining and Organizing Custom Cursors

August 20, 2020




Cursory loads a predefined set of custom hardware cursors on game start, so it is important to understand the file types, formats, and procedures that need to be followed in order for a cursor to be loaded. These cursors can be defined in the Cursors section of the Project Settings.

Accepted Cursor Types

Cursory supports all common cursor types supported by Unreal Engine 4, subject to limitations imposed by the target platform. Cursors are loaded based on the following priority:

  • Windows - .ani, .cur, .png
  • Mac - .tiff, .png
  • Linux - .png

For example, if both Cool.ani and Cool.png exist in the same folder, only Cool.ani will be loaded.

Cursor Locations, .Uassets, and Cooking

Cursory will look for cursors in the path that you specify in Project Settings, but that path must be within your game's Content directory. In addition, there are a few caveats to keep in mind.

First, when writing out the path to the cursor, do not specify the file extension. As noted above, the system will look through the relevant folder for the first cursor that matches the priority list.

// WRONG: Slate/Cursors/Cool.png

Second, note that unlike for many assets, the hardware cursor system does not depend on .uasset files. Instead, it looks for the raw cursor file (.ani, .cur, etc.). Accordingly, having a .uasset can unnecessarily clutter your Content folder. For this reason, it is a good idea to place your raw cursor files in the Content/Slate/~ subfolder, which does not automatically create .uasset files out of raw assets placed within.

Third, and on a related note, raw cursors are not automatically cooked because they are not .uasset files. Instead, you need to manually indicate in Project Settings that you want your cursor folder to be cooked. However, we can skip this by placing cursors in the Content/Slate/~ subfolder, which is always cooked.

Organize Cursors Using GameplayTags

Cursory gives you the power to organize your hardware cursors in arbitrary ways using GameplayTags. For consistency, we recommend using Cursor.{Type} as the base tag for all cursor definitions. For example, if you had a game with an ice breaker game, you could have three cursors for specific situations:

  • Hovering above ice - Cursor.Ice.Hover
  • Breaking ice - Cursor.Ice.Breaking
  • Hovering over broken ice - Cursor.Ice.HoverBroken

Or maybe you would structure it a different way. Ultimately, Cursory places no limits on your imagination!

© 2021 Mustafa Moiz.