Today we’re going to be looking at how to make a slider (good for stuff like volume controls) for UDK Mobile. This tutorial uses the Canvas rather than Scaleform, but if you’ve moved on to Scaleform you still may find the math behind it useful. As a side note, at least for now I still consider Canvas superior to Flash on mobile devices because of its efficiency and simplicity.
Without further ado here’s the code: Download Here
Before we jump into the code, let’s take a look at what it should actually produce:
An important thing to note is that the class doesn’t actually draw the slider bar, just the nub. This is because for most applications the slider bar will remain stationary relative to its background, so…why not just make it part of the background? One of my common practices is actually to flatten all static objects like icons into the background plate to reduce draw calls.
When adding a slider to a scene, keep in mind the following values:
- Left, Top, Width, Height: Defines the red box above.
- NubWidth, NubHeight: Defines the green box above. Both of these values are relative to Height. Setting both to 1.0 will make a square nub exactly the height of the enclosing box.
- SliderMin, SliderMax: Values for each end of the slider. They can be anything you want, as long as SliderMin is less than SliderMax. The class will automatically take care of conversions for you.
- bIncremental: If true, the slider snaps to integer values along the range SliderMin and SliderMax.
Now it’s time to look at the code itself. Most of the code is actually quite self-explanatory — for example CheckHitNub() and CheckBounds() test whether the player touched within the green and red boxes respectively, and CheckSwipe() determines whether the ongoing touch has moved enough to be a swipe. Simple, right?
The most difficult concept to grasp about the slider is that there are three values we must keep track of at any one time:
- NubLeft, which is a float on the range 0.0 to 1.0 holding the current position of the nub’s left side along the slider. You can see it in the picture above.
- The “virtual” value of the nub, along the range SliderMin to SliderMax.
- The physical location of the nub, in pixels.
Most of the functions at the top handle converting from one to another. You may wonder why this is necessary…and the answer is, because this allows the slider to be used on all supported resolutions without having to change anything. No matter the device, NubLeft is handled the exact same way. When we do need to render the slider, that’s when we determine the location in pixels.
bHasCancel is a neat option that is used at the end of the OnTouch() function. Whenever the user touches the slider, the initial location is saved. If bHasCancel is true, when the player swipes out of bounds (outside the red box), the slider position is reset to this initial location. In effect this is a “cancel”.
What about TouchOffset? Well, that’s just me being anal about my algorithms. Originally I had the nub snap to the center of the user’s initial touch, but that looked weird when someone touched within the nub itself (suddenly it would jump to align itself, centered, with the player’s finger). In the event that someone does touch the nub, this keeps track of the touch’s offset from nub center for the duration of the slider. Trust me, it looks better.
I tried to make this class as general as possible, but obviously there’s lots of room for extension and creativity! I also tried my best to document the code and make it as neat and error-free as possible, but if you have questions or spot an error please let me know. As always, happy gaming!