johnatm / itween

Automatically exported from code.google.com/p/itween
1 stars 2 forks source link

onupdateparams in ValueTo are not included in back call. #62

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
Please can you check ValueTo iTween

iTween.ValueTo(go, iTween.Hash(
"from", floatFrom.Value,
"to", floatTo.Value,
"time", time,
"delay", delay,
"easetype", easeType,
"looptype", loopType,
"oncomplete", "iTweenOnComplete",
"oncompleteparams", itweenID,
"onstart", "iTweenOnStart",
"onstartparams", itweenID,
"onupdate", "iTweenFloatUpdate",
"onupdateparams", itweenID
));

The problem is, when I try to get : "onupdateparams", itweenID in your
call back function I always get :

Calling function iTweenFloatUpdate with 1 parameter but the function
requires 2.

The function is defined as :

void iTweenFloatUpdate(float aFloat, int aniTweenID){
}

Original issue reported on code.google.com by ledvin...@gmail.com on 13 Mar 2011 at 6:35

GoogleCodeExporter commented 8 years ago
Having the same issue here as well, currently using a fifo queue implementation 
and making my ValueTo operations synchronous (popping stack and using shared 
state variable to identify object which is active) - this may work as well for 
others waiting on a fix to this problem.

Original comment by lyph...@gmail.com on 28 Mar 2011 at 6:25

GoogleCodeExporter commented 8 years ago
Sending a delegate to iTween as your callback function would be the best and 
fastest solution. 

Original comment by ledvin...@gmail.com on 28 Mar 2011 at 6:44

GoogleCodeExporter commented 8 years ago
Excellent idea, would you mind posting a small snippet of code to show how that 
would be done?  

Original comment by lyph...@gmail.com on 28 Mar 2011 at 1:33

GoogleCodeExporter commented 8 years ago
This is also an issue for me as well.  It is difficult when you have worked a 
large majority of your code around the callbacks in iTween when a random one 
doesn't work.  If this is not going to be in the next fix, is there anyway to 
alter the class myself to fix this?

Original comment by chuckjoh...@gmail.com on 22 Dec 2011 at 3:00

GoogleCodeExporter commented 8 years ago
I tried to build the use of delegates into the callback invocation and it 
turnde out to be quite easy. In the file iTween.cs (V 2.0.45) i changed the 
method Callback() (Line 7039 ff) to be as follows:

    void CallBack(string callbackType){
        if (tweenArguments.Contains(callbackType) && !tweenArguments.Contains("ischild")) {
            //establish target:
            GameObject target;
            if (tweenArguments.Contains(callbackType+"target")) {
                target=(GameObject)tweenArguments[callbackType+"target"];
            }else{
                target=gameObject;  
            }

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            if (tweenArguments[callbackType] is Action<object>)
            {
                ((Action<object>)tweenArguments[callbackType]).Invoke((object)tweenArguments[callbackType + "params"]);
            }
            else
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            //throw an error if a string wasn't passed for callback:
            if (tweenArguments[callbackType].GetType() == typeof(System.String)) {
                target.SendMessage((string)tweenArguments[callbackType],(object)tweenArguments[callbackType+"params"],SendMessageOptions.DontRequireReceiver);
            }else{
                Debug.LogError("iTween Error: Callback method references must be passed as a String!");
                Destroy (this);
            }
        }
    }

What you can do now when using ValueTo is:

            iTween.ValueTo(go, iTween.Hash(
                "from", _component.X,
                "to", x,
                "onUpdate", (Action<object>) (newX => _component.X = (float) newX)
            ));

This is still not perfect because you have to cast your lambda expression to 
Action<object> and then cast the value back to what you expect it to be. In 
this case (float) newX.

But it works really nice and it should even be faster then sending messages 
around.

Maybe someone can use it or maybe it will even get worked into iTween.

Cheers
kjg

Original comment by karsten....@googlemail.com on 3 Jan 2012 at 6:37

GoogleCodeExporter commented 8 years ago
Man, this is really sweet! Would love to see this in the next official release!

For instance, I use it like this:

iTween.LookTo(monoAgent.gameObject, iTween.Hash(
    "lookTarget", GameObject.FindWithTag("Nick"),
    "time", 4,
    "onComplete", (Action<object>)((x) =>  { facingOpponent = false; }) 
));

There are plenty of occasions where I only set a single variable or call two 
other methods. Implementing a callback method for each tween and distinguishing 
them is unnecessary work. Maybe the solution can still be improved to get rid 
of the casts etc.

Original comment by sebast...@lurado.de on 9 Mar 2012 at 6:16

GoogleCodeExporter commented 8 years ago
@kjg: Looks fantastic but unfortunately it throw me an error:

error CS0246: The type or namespace name `Action`1' could not be found. Are you 
missing a using directive or an assembly reference?

Could you please tell me what I am doing wrong?
Thank you in advance and I hope it will be included into next official release.

Original comment by ZHUR...@gmail.com on 10 Mar 2012 at 4:13

GoogleCodeExporter commented 8 years ago
Make sure you have a "using System" at the top

Original comment by sebast...@lurado.de on 10 Mar 2012 at 8:57

GoogleCodeExporter commented 8 years ago
omg shame on me - it's so basic mistake I made. Thank you very much for help :)

Original comment by ZHUR...@gmail.com on 10 Mar 2012 at 9:26

GoogleCodeExporter commented 8 years ago
Just to point out a problem that I encountered with the Action solution. I get 
a namespace clash with "using System;" for Random because it's defined in both 
UnityEngine and System. By using the Action class directly via System.Action 
this problem can be avoided.

Original comment by andg...@googlemail.com on 28 Mar 2012 at 2:41

GoogleCodeExporter commented 8 years ago
Alternatively you can add "using Random = UnityEngine.Random;" to your using 
declarations.

Original comment by sebast...@lurado.de on 28 Mar 2012 at 8:41

GoogleCodeExporter commented 8 years ago
I expanded slightly on karsten's solution:

    object callback;
    object parameter;

    Type callbackDataType;
    Type parameterType;

...

            callback = tweenArguments[callbackType];
            parameter = tweenArguments[callbackType + "params"];

            callbackDataType = callback.GetType();
            parameterType = parameter.GetType();

            if (callbackDataType == typeof(System.String))
            {
                target.SendMessage((string)callback, (object)parameter, SendMessageOptions.DontRequireReceiver);
            }
            else if (callbackDataType == typeof(Action<object>))
            {
                ((Action<object>)callback)((object)parameter);
            }
            else if (TryDelegateCallbackCall<Color>(ref callbackType));
            else if (TryDelegateCallbackCall<Rect>(ref callbackType));
            else if (TryDelegateCallbackCall<Vector3>(ref callbackType));
            else if (TryDelegateCallbackCall<Vector2>(ref callbackType));
            else if (TryDelegateCallbackCallAssignable<float>(ref callbackType)) ;
            else
            {
                Debug.LogError("iTween Error: Callback method references must be passed as a String!");
                Destroy(this);
            }
        }
    }

    bool TryDelegateCallbackCall<T>(ref string callbackType)
    {
        if (callbackDataType == typeof(Action<T>) && parameterType != typeof(T))
        {
            ((Action<T>)callback)((T)parameter);
            return true;
        }
        return false;
    }

    bool TryDelegateCallbackCallAssignable<T>(ref string callbackType)
    {
        if (callbackDataType == typeof(Action<T>) && parameter is T)
        {
            ((Action<T>)callback)((T)parameter);
            return true;
        }
        return false;
    }

I moved the types and values to the variables to assist readability, and 
because this solution can greatly increase the number of times that you access 
the HashTable of arguments.

Basically this allows you to get around the casting issue, if you wish.

The Generic function allows you to easily set the order that you would like 
evaluated, if you so please.

Original comment by AdamLevi...@gmail.com on 6 Aug 2012 at 12:29

GoogleCodeExporter commented 8 years ago
I made my own delegate handling system so that I don't have to cast anything 
and it works nicely for any Action or Action<> delegate.

I believe it'd be a nice addition to iTween ;)

void CallBack(string callbackType){
        if (tweenArguments.Contains(callbackType) && !tweenArguments.Contains("ischild")) {
            //establish target:
            GameObject target;
            if (tweenArguments.Contains(callbackType+"target")) {
                target=(GameObject)tweenArguments[callbackType+"target"];
            }else{
                target=gameObject;  
            }

            //throw an error if a string wasn't passed for callback:
            if (tweenArguments[callbackType].GetType() == typeof(System.String))
            {
                target.SendMessage((string) tweenArguments[callbackType], (object) tweenArguments[callbackType + "params"], SendMessageOptions.DontRequireReceiver);
            }else if(tweenArguments[callbackType].GetType().FullName.StartsWith("System.Action")){
                ((MulticastDelegate) tweenArguments[callbackType]).DynamicInvoke((object) tweenArguments[callbackType + "params"]);
            }else{
                Debug.LogError("iTween Error: Callback method references must be passed as a String!");
                Destroy (this);
            }
        }
    }

Original comment by webmaste...@gtempaccount.com on 2 Sep 2012 at 11:39

GoogleCodeExporter commented 8 years ago
Hey Indiefreak, could you give an usage example?

Original comment by sebast...@lurado.de on 3 Sep 2012 at 7:22