Change Value Of UI Light Slider to Read At Specific Points Of Slider Value

Wow that was a bit of a mouthful for a question title, sorry but I could not think of a better way to word it.
Anyways @Soraphis,
Here is a new question based on the last updated script.

  1. Is there a way to have the light UI slider only trigger the audio clips wen it hits a certain pint of the slider like in my attached image?
  2. Is it possible to make it so that if the LDR sensor was deliberately played with i.e. someone waving their hand repeatedly over the sensor that I could trigger audio responses from a 3rd array of audio clips.

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.IO.Ports;
using System.Threading;


public class Sending : MonoBehaviour {

	//int sysHour = System.DateTime.Now.Hour;
	
	//Random Clips
	//public AudioClip[] darknessDetectedVoices;
	//public AudioClip[] brightnessDetectedVoices;

	public AudioClip[] BrightnessAudioClips;
	public AudioClip[] DarknessAudioClips;

	//DTMF Tones
	public AudioClip DTMFtone01;
	public AudioClip DTMFtone02;
	public AudioClip DTMFtone06;
	public AudioClip DTMFtone08;
	public AudioSource source;

	//UI Text Reference
	//public Text MessageCentreText;

	//_isPlayingSound is true when a sound is currently playing - just as the name suggests.
	private bool _isPlayingSound;

	public GameObject LightSlider;
	public Slider slider;
	Slider lightSlider;
	public static Sending sending;

    //public static SerialPort sp = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
	public static SerialPort sp = new SerialPort("/dev/cu.wchusbserial1420", 115200); //115200

	public string message2;

	//Button States
	bool button01State = false;


	void Awake () {
		if (sending == null) {
			DontDestroyOnLoad (gameObject);
			sending = this;
		} else if (sending != this) {
			Destroy (gameObject);
		}
}


	float timePassed = 0.0f;
	// Use this for initialization
	void Start () {
		OpenConnection();
		lightSlider = GetComponent<Slider> ();
		if(slider == null) slider = GetComponent<Slider>(); // search slider in this object if its not set in unity inspector
		if(source == null) source = GetComponent<AudioSource>(); // search audiosource in this object if its not set in unity inspector

		}
	
	// Update is called once per frame
	void Update () {

			//print("BytesToRead" +sp.BytesToRead);
			message2 = sp.ReadLine();
			
		string message = sp.ReadLine(); //get the message...
		if(message == "") return; //if its empty stop right here
		// parse the input to a float and normalize it (range 0..1) (we could do this already in the Arduino)
		// I dont know if a higher value means darker, if so add a "1 - " right after the "="

		float input =  1 -  float.Parse (message) / 100f;
		// set the slider to the value
		slider.value = input;
		// after the slider is updated, we can check for the other things for example play sounds:

		if (source.isPlaying) return; // if we are playing a sound stop here

		// else check if we need to play a sound and do it
		if (slider.value > 0.8f)
			source.PlayOneShot (BrightnessAudioClips [Random.Range (0, BrightnessAudioClips.Length)]);
		else if (slider.value < 0.2f)
			source.PlayOneShot (DarknessAudioClips [Random.Range (0, DarknessAudioClips.Length)]);
		

	}

	public void OpenConnection() 
    {
       if (sp != null) 
       {
         if (sp.IsOpen) 
         {
          sp.Close();
          print("Closing port, because it was already open!");
         }
         else 
         {
          sp.Open();  // opens the connection
          sp.ReadTimeout = 16;  // sets the timeout value before reporting error
          print("Port Opened!");
		//		message = "Port Opened!";
         }
       }
       else 
       {
         if (sp.IsOpen)
         {
          print("Port is already open");
         }
         else 
         {
          print("Port == null");
         }
       }
    }

    void OnApplicationQuit() 
    {
       sp.Close();
    }


}

as i mentioned in the other question:

         float input =  1 -  float.Parse (message) / 100f;
         // set the slider to the value
         float oldValue = slider.value;  ////////////// -------- this is new
         slider.value = input;
         // after the slider is updated, we can check for the other things for example play sounds:
 
         if (source.isPlaying) return; // if we are playing a sound stop here
 
         // else check if we need to play a sound and do it
         if (slider.value > 0.8f && oldValue <= 0.8f) ////////////// -------- this has changed
             source.PlayOneShot (BrightnessAudioClips [Random.Range (0, BrightnessAudioClips.Length)]);
         else if (slider.value < 0.2f  && oldValue >= 0.2f) ////////////// -------- this has changed
             source.PlayOneShot (DarknessAudioClips [Random.Range (0, DarknessAudioClips.Length)]);

should solve your first problem


problem #2

first, i’ll quote myself from the other question:

(1) keep track of the time, that has passed since the last message was send, and the average value change (delta). if the time gets to low and the average-delta to high, then you know there’s someone manipulating (e.g. waving his hand in front of the sensor).

But its a bit tricky to find the right values and needs much testing. (2) instead of playing an “annoyed audio clip” you could try to “fade” to the new value, someone waving his hands to fast would be “smoothed away” (dont know how to express myself, sry :/).

Note: one can always manipulate your light sensor with his hands, you just can make it harder to do so.

####(2)

ok the 2nd point is easier so adding two new variables:

const float sliderChangeVelocity = 0.5f;
private float desired sliderValue;

sliderChangeVelocity says how much the slider can change per second. So lets change a bit in the Update() method

string message = sp.ReadLine();
float oldValue = slider.value;
slider.value = Mathf.Min(Mathf.abs(desiredValue - slider.value), sliderChangeVelocity*Time.deltaTime) 
               * Mathf.Sign(desiredValue - slider.value);
if(message == "") return;
float input =  1 -  float.Parse (message) / 100f;
desiredValue = input;

note: I’m writing this all out of my head in this text-field not in my IDE so there might be some errors.

Explaining the third line: first we want the absolute value of how much we want to change (desiredValue - slider.value) we compare it to the amount we are allowed to change in the current timestep (sliderChangeVelocity * Time.deltaTime) and keeping the lower value (Mathf.Min()). But now we have the absolute value which is always positive, but its possible that we want to decrement, so we multiply it by the Sign of (desiredValue - slider.value) which is 1 if its positive (0 counts as positive), and -1 if its negative.

####(1)

the first point is way more complicated and i cant say if the solution im my brain is correct.

i need to think more about it, it would be something like summing up the (absolute value of) changes of desired value in a new variable, divide it each time step with Time.deltaTime (which should be nearly always be less then 1, so the new variable will get greater), and if this variable gets to hight (maybe higher then 2, which would mean it went from pitch black to full bright in less then a half second) play your sound.

but i think there are some flaws in this … i’ll need to test this myself a bit … maybe when i get some time for myself. but this would be the direction i’d go to solve this