[SOLVED] AddVoidPersistentListener to Slider via script

Okay, originally posted that in questions, but when it gets approved its so far down the line no one can see it, and I’ve noticed going through this section thats its not uncommon to post code problems here, so…

All I’m trying to do is add a onValueChanged() event to a slider in the inspector in editor mode.

The ultimate go is to allow quick rigging of sliders to gameobjects, associated scripts and fucntions. on a permanent basis that can be saved. ie save scene, reload scene and all the sliders are rigged already.

I’ve tried monobehavoior and Editor, in Editor folder and in script folder attached to a game object. I can get the debug.log to spit out when its supposed to, and its showing me my values are there, but no change.

using UnityEngine;
using System.Collections;
using UnityEditor;
using UnityEngine.UI;
[ExecuteInEditMode]
public class theRack : Editor {

    Slider Overall;
    GameObject girl;
    BoneMorpher3 bm;
    float x;

    // Use this for initialization
    public void attach() {
    x = 1f;
        Overall = GameObject.FindGameObjectWithTag ("OverallSlider").GetComponent<Slider>();
    girl = GameObject.Find ("female_wip1");
        bm = girl.GetComponent<BoneMorpher3>();
        Overall.onValueChanged.AddListener(delegate {girl.GetComponent<BoneMorpher3>().XIn(Overall.value);});
        Debug.Log("is this kicking off or what?");
        Debug.Log (girl.name);
        Debug.Log (Overall.name);
    }

 
}

when it prints in console, the gameobjects girl and overall are working, but its not adding.

Ive linked it to a custom menu item that calls on the function so I can test it, but nothing. Any suggestions?!

Okay, Now I can get the sliders to work in Editor and Run mode, but as soon as you switch, it stops working and you have to click it again, and its STILL not showing in the inspector

using UnityEngine;
using System.Collections;
using UnityEditor;
using UnityEngine.UI;

public class theRack : Editor {

    Slider Overall;
    GameObject girl;
    BoneMorpher3 bm;
    float x;

    // Use this for initialization
    public void attach() {
    x = 1f;
        Overall = GameObject.FindGameObjectWithTag ("OverallSlider").GetComponent<Slider>();
    girl = GameObject.Find ("female_wip1");
        bm = girl.GetComponent<BoneMorpher3>();
        Overall.onValueChanged.AddListener(delegate {girl.GetComponent<BoneMorpher3>().XIn(Overall.value);});
        Overall.onValueChanged.AddListener(delegate {girl.GetComponent<BoneMorpher3>().YIn(Overall.value);});
        Overall.onValueChanged.AddListener(delegate {girl.GetComponent<BoneMorpher3>().ZIn(Overall.value);});
        Debug.Log("is this kicking off or what?");
        Debug.Log (girl.name);
        Debug.Log (Overall.name);
    }


}

No one wants to take a blind stab at this?! lol! Is it that bleak?! O_O

Okay, last bump, if this doesn’t work, I will accept…NOTHING, I ACCEPT NOTHING!!! THERE MUST BE A WAY!!!

†falls to knees dramatically, and starts shaking fist in the air, full on Calculon style†

WHY, UNITY, WHY!!! WHY DO YOU HATE ME!!! WHY!!! FADE TO END SCENE

Yea, didn’t figure that would help, but, last bump and all, I felt I really owed it to any that bothered looking again some kind of brilliant show or dramatic presentation, even if it a touch on the brief side. :wink:

What is it exactly you’re trying to do. Not the how you’re accomplishing it.

But what?

You want to programmatically link the OnValueChanged event of a Slider to a scene object? Do you want it to result in as if you dragged a GameObject onto the event in the inspector? If so, the ‘AddListener’ method doesn’t do that. It deals with non-persistent listeners… e.g. the documentation:

By non-persistent, they mean a listener that is not maintained when serialized.

See UnityEventTools for adding persistent listeners:

1 Like

Thats exactly what I’m trying to do, and thats a damned good lead into what I needed. Thats what I was missing.

I want it to be just like I dragged and dropped it. The reason I’m trying to do it this way is I have near 50 sliders that have to be set to various bones, and if I could automate the process, it wouldn’t be so painful when we change out models

Lord, You rock. Just. Just ROCK! ROFL!!! You have no idea how happy I am, its the only thing this little tool was missing. :slight_smile:

Okay, Alot closer,but I’m still messing something up >_<

So from above, I added it to the main file I was working in, and it would indeed add a link to the inspector,only it wasn’t linking the file I asked, it was putting itself in. So I put it in the file that was actually being linked, which did result in most ofit being corrected, but this →
2420538--165634--inspector shot.png
All that is right except its supposed to be BoneMorpher3.XIn() (or Y, Z)
and even stranger, when its initially done it works, but as soon as I change the run state (I’f I press play, or if I did it in play and press stop) it won’t work after that…

TheRack

using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using UnityEditor;
using UnityEditor.Events;
using UnityEditor.UI;
using UnityEngine.UI;
using UnityEngine.Serialization;

public class theRack : Editor {

    Slider Overall;
    GameObject girl;
    BoneMorpher3 bm;
    string[] sliders;
    string[] bones;
    bool[] x;
    bool[] y;
    bool[] z;
    Animator anim;

    // Use this for initialization
    public void attach() {

        Overall = GameObject.FindGameObjectWithTag ("OverallSlider").GetComponent<Slider>();
        girl = GameObject.Find ("female_wip1");
        bm = girl.GetComponent<BoneMorpher3>();
        Overall.onValueChanged.AddListener(delegate {girl.GetComponent<BoneMorpher3>().XIn(Overall.value);});
        Overall.onValueChanged.AddListener(delegate {girl.GetComponent<BoneMorpher3>().YIn(Overall.value);});
        Overall.onValueChanged.AddListener(delegate {girl.GetComponent<BoneMorpher3>().ZIn(Overall.value);});
        bm.Linkit ();
        if (girl.GetComponent<BoneMorpher3>() == null) {
            girl.AddComponent<BoneMorpher3> ();
        }
    }
    public void bind(){
        if (girl.GetComponent<BoneMorpher3>() == null) {
            girl.AddComponent<BoneMorpher3> ();
        }

    }


   
    // Update is called once per frame

}

BoneMorpher3

using UnityEngine;
using UnityEngine.Events;
using System.Collections;
using UnityEditor;
using UnityEditor.Events;
using UnityEngine.UI;
using UnityEngine.Serialization;

public class BoneMorpher3 : MonoBehaviour {
    public float x;
    public float y;
    public float z;
    Slider Overall;
    // Use this for initialization
    void Start () {
        x = 1f;
        y = 1f;
        z = 1f;
    }
    public void UniversalIn(float all){
        x = all;
        y = all;
        z = all;
        Change ();
    }
    public void AntiUniversalIn(float all){
        x = 1f/all;
        y = 1f/all;
        z = 1f/all;
        Change ();
    }
    public void YIn(float yin){
        y = yin;
        Change ();
    }
    public void XIn(float xin){
        x = xin; 
        Change ();
    }
    public void ZIn(float zin){
        z = zin;
        Change ();
    }
    public void Change(){                
        transform.localScale = new Vector3 (y, z, x);
    }
    public void Linkit(){

        Overall = GameObject.FindGameObjectWithTag ("OverallSlider").GetComponent<Slider>();
        UnityEventTools.AddVoidPersistentListener (Overall.onValueChanged, () => XIn(Overall.value));
        UnityEventTools.AddVoidPersistentListener (Overall.onValueChanged, () => YIn(Overall.value));
        UnityEventTools.AddVoidPersistentListener (Overall.onValueChanged, () => ZIn(Overall.value));
    }


}

Odder still, if you notice I have the connection in two places. It only works at all if I have both now. >_<

What am I messing up?! I know its in the UnityEventTools.AddVoidPersistentListener declaration,I’m just not sure what. I’ve been through the documentation.

And lastly, I’m getting no errors when it no longer works.

Okay, side note, it was never working, oh the inspector part is,as much as the above picture shows which for whatever reason is adding m__0, m__1 etc and doing nothing.

I only thought the slider was working because I left the addlisteners, which is non persistent, so of course it wasn’t working after the change in runstate, I had it work a few times, I’m guessing that was more of a glitch then anything

so, yea, thats where I’m at, and I"ve tried ever way to define them I can think of, even changing the Xin(float xin) and its two brothers from public void, to public floats, with and without an input value, nothing. >_<

EVIL!!! >_<!!!

AND SOLVED!!!

UnityEventTools.AddVoidPersistentListener (Overall.onValueChanged, XIn);

where Overall is a slider, and XIn is the function. I kept putting () at the end of the function out of habit, and apparently it doesn’t at all want those. And thats fine, because it works, and its perfect, and yay. lol,

Thank you, and Goodnight
Sincerely,
Raven

And that didn’t take any arguments, which would have had me making a registry file for the bonemorphers to know what slider they should listen to, so I kept looking:

public void ExampleFunction(float x){...}

have to make the right kind of UnityAction per argument type:

public UnityAction<float> testaction; 
public Slider Overall;

then define testaction

testaction = new UnityAction<float>(ExampleFunction); 
UnityEventTools.AddPersistentListener (Overall.onValueChanged, testActionx);

Noticed for agruments the addvoidpersistent didn’t work. Hope that helps someone :wink:

Sincerely,
Raven

2 Likes

This was very similar to a problem I had. Thanks to you I solved it!
I am however, stuck at removing the previous listeners that were added. I am using
UnityEventTools.RemovePersistentListener for this but Unity Documentation doesn’t provide much help.
Have you used it?

I did, unfortunately I had a computer crash cries

I had to replace it, and I haven’t gotten around to getting my code off the hard drive, but if I recall I did find a way to clear it…
I’ll try to get an adapter this weekend (other code I need off there to anyways) so if you haven’t gotten it by then, I’ll post it on here. (provided nothing else goes awry >_<)

With all that said, I think it had something to do with removing all listeners. <_<