Rotate GameObject With GUI Slider

For context, I am trying to move the flap on an airplane wing using a GUI Slider in Unity 2017.3.0f3. Ideally I'm going to have the slider start in the middle, and you can drag the dot left for "down" a certain amount of degrees, and right for "up" a certain amount of degrees. So far I have hit walls in all of my attempts of just proof of concept for scripting this. My setup I have in the scene is:

  • a slider named “LeftFlap_Slider”,

  • a C# script titled “MoveFlaps.cs”,

  • GameObject titled “LeftWingFlap_Pivot” that the C# script is attached to.

I first found a post from 2015 posing a very similar question, and the solution given(variables changed to my context):

public GameObject LeftFlap;
public void RotateFlap()
    {
        float sliderValue = GetComponent<Slider>().value;
        LeftFlap.transform.rotation = Quaternion.Euler(sliderValue * 360, 0, 90);
    }

While this doesn’t show any errors in the editor, when I move the slider in Unity I get the error ArgumentException: GetComponent requires that the requested component 'Slider' derives from MonoBehaviour or Component or is an interface.

And further down it directly calls out the line that float sliderValue = GetComponent<Slider>().value; is on. So I’m assuming that it’s something to do with <Slider>?

I have also gone down the route of Transforms and Vector3 eulerAngles. Specifically:

public void LeftFlapSlider(float  newValue)
    {
        Vector3 pos = LeftFlap.transform.eulerAngles;
        pos.y = newValue;
        LeftFlap.transform.position = pos;
    }

When I connect it to the slider (and select the Dynamic float version of LeftFlapSlider), the LeftWingFlap_Pivot GameObject teleports to a different location the moment the slider begins to update. A note on its teleport location, this is not world center or GameObject center, as those are both located in front of the airplane, and this is teleporting somewhere above and behind the airplane. The slider does move the GameObject pos and neg when I go left and right, but it’s on an axis, and I want to rotate it on an axis. So this was my final attempt:

public float speed;
    public void AdjustSpeed(float newSpeed)
    {   
        transform.Rotate(speed, 0, 0);
        speed = newSpeed;
    }

This has the GameObject spin, only while the slider is moving, and it spins faster or slower depending on where I am currently moving the slider. But it’s rotating it, which is better than a linear movement on an axis.

So that’s where I am at now and am at a loss. It would seem that my first example would be the best bet, as that thread stated that it worked just great for what they were using it for, and that’s near identical to what I’m doing, but of course it doesn’t work.

When using Unity’s UI elements, there’s usually an event listener you can use instead of manually checking for changed values or assigning rotations each frame regardless of change. This script assumes that your slider goes from 0 to 1 and that you want to extend that to 0 to 360, as you had in your question.

using UnityEngine;
using UnityEngine.UI;

public class RotateWithSlider : MonoBehaviour
{
	// Assign in the inspector
	public GameObject objectToRotate;
	public Slider slider;

	// Preserve the original and current orientation
	private float previousValue;

	void Awake ()
	{
		// Assign a callback for when this slider changes
		this.slider.onValueChanged.AddListener (this.OnSliderChanged);

		// And current value
		this.previousValue = this.slider.value;
	}

	void OnSliderChanged (float value)
	{
		// How much we've changed
		float delta = value - this.previousValue;
		this.objectToRotate.transform.Rotate (Vector3.right * delta * 360);

		// Set our previous value for the next change
		this.previousValue = value;
	}
}

Which will look like:

alt text

It’s a bit easier in Unity 2021.1:

Create the slider(s) in the editor and assign the following function to its OnValueChanged:

public Slider xSlider, ySlider, zSlider; //set in editor
public GameObject objectToRotate; //set in editor
private readonly float rotationLimit = 180f;

public void RotateObject() {
    objectToRotate.transform.localEulerAngles = new Vector3(
        xSlider.value * rotationLimit,
        ySlider.value * rotationLimit,
        zSlider.value * rotationLimit //y-up, switch ySlider & zSlider for z-up
    );
}

I also set the sliders’ min value to -1 and max value to 1, so the handle starts in the middle and you can rotate left and right (for a full rotation combined). To only go right change the values to 0 and 1 and set the limit to 360. If you only want to rotate the object in a single direction with a single slider, use e.g.:

objectToRotate.transform.localEulerAngles = Vector3.right * xSlider.value * rotationLimit;