How to make an in-game slider control?

Hi,

I want to make a slider-control to work in-game (like you often see for in-game audio controls etc). You click on the slider knob and move it with the mouse, and then the position is used to change another object’s property. I’m still learning Blender and am not sure where to begin.

I’m sure this has been explained in a tutorial somewhere. I even think I saw such a tutorial but can’t find it again now I need it! Can anybody point me in the direction of such a tutorial please (or give a brief explanation of how to do it)?

Thanks!

There would be lots of ways to do it and lots ways to present a slider to the user. The slider could be a control on a panel and the panel could be an overlay. Or the slider could be 3D object in the scene. And would you want to be able to drag the slider or click and hold on up/down buttons or both? Or you can simulate an overlay by parenting buttons and sliders up close to the camera. These are very good exercises for a beginner.

A basic exercise could be to place two cubes on the X axis about 10 units apart. Are you able to click or click and hold on one cube and have the other cube move along the axis? If you can do that you know how to change another objects property and get it to do something as it’s property changes.

To click on an object and drag it is trickier. You can do it in a similar way that the “mouselook” scripts rotate a camera, except that instead of applying torque you would apply force or displacement along the sliding objects axis. Understand the mouselook script and you will find it gives you all kinds of ideas.

You click on a slider activating the script and have the mouse “freeze”. As you move the mouse the mouse pointer jerks around but returns to the frozen spot. Within the script, which resembles a mouselook script, the vertical jiggles of the mouse pointer can be applied as a force to the slider.

To make it look nice you can vanish the mouse pointer as you click on a slider. The slider could be highlit pink. When you’re done click again. The pointer reappears and the slider unhighlights.

PS I’ve checked out some of you’re other posts. You’re a relatively advanced user so maybe you can tell me whether my method of dragging an object is worth considering.

Firstly, many thanks for your reply. All we need sometimes if for somebody to open the door! I’ll try out your method. Secondly, you’re very kind, but I’m far from being an advanced user. There is SO much I don’t know (like how to do sliders :D)

Well, I promised to report back and here is the result.

It is really quite simple. At first I tried using sensors to parent the slider to a custom cursor when clicked, which works but you can move the slider anywhere and not just side to side. Clamping to a track didn’t work but using position constraints wired to an always sensor did. However, the sensor then flashed madly every time you grabbed it, which looked completely pants. So, I quickly realised that I needed a splash of Python!

I didn’t need (or want) a full mouse-look set up. So, first I learnt about getting a mouse pointer set up with this very easy tutorial. When I had my cursor set up (and named “cursor”), I did the following:

  • I added a Boolean property to my slider (I called it ‘sliding’).
  • I then added two sensors to the slider: a mouse over and left-mouse-button. I passed these through an AND gate to a property actuator which assigned the value ‘True’ to the sliding property.
  • I then added a NAND gate connected to the same two mouse sensors and attached that to another property actuator which assigned the value ‘False’ to the sliding property.
  • I then added a property sensor to the slider to detect when the sliding property was true and hooked that up to a Python script.
    My script is nothing fancy and is as follows:
def moveSlider():
    '''Moves the slider relative to the cursor'''
    cont = bge.logic.getCurrentController()
    slider = cont.owner
    cursor = bge.logic.getCurrentScene().objects["cursor"]
    newX = cursor.worldPosition[0]
    if (newX >= -2.5) and (newX <= 2.5):
        y = slider.worldPosition[1]
        z = slider.worldPosition[2]
        slider.worldPosition = ([newX,y,z])

Obviously, if you have a vertical slider (assuming a top-down camera on your control screen) you need to edit the second half of the code to something like this:

    newY = cursor.worldPosition[1]
    if (newY >= -2.5) and (newY <= 2.5):
        x = slider.worldPosition[0]
        z = slider.worldPosition[2]
        slider.worldPosition = ([x,newY,z])

You could make this a bit more generic for multiple sliders in a scene instead of the hard coded x-limits. These limits are also only relevant to the size of my test slider. A variable proportional to the length of the slider body detected from the object properties seems the way to go. This is what I intend to do for my next step, so I can have a few sliders in the scene together.

If anybody has a better/more elegant/more sophisticated way of doing this, your comments are VERY welcome.

1 Like

Cool. I haven’t done much blending lately. Maybe check back in a few days, I’ll try your method and maybe a few others and post a blend.