static int _CreateLTBezierPath(IntPtr L)
	{
		try
		{
			int count = LuaDLL.lua_gettop(L);

			if (count == 0)
			{
				LTBezierPath obj = new LTBezierPath();
				ToLua.PushObject(L, obj);
				return 1;
			}
			else if (count == 1 && TypeChecker.CheckTypes(L, 1, typeof(UnityEngine.Vector3[])))
			{
				UnityEngine.Vector3[] arg0 = ToLua.CheckObjectArray<UnityEngine.Vector3>(L, 1);
				LTBezierPath obj = new LTBezierPath(arg0);
				ToLua.PushObject(L, obj);
				return 1;
			}
			else
			{
				return LuaDLL.luaL_throw(L, "invalid arguments to ctor method: LTBezierPath.New");
			}
		}
		catch(Exception e)
		{
			return LuaDLL.toluaL_exception(L, e);
		}
	}
	// Use this for initialization
	void Start () {
		lt1 = GameObject.Find("LeanTweenAvatar1");
		lt2 = GameObject.Find("LeanTweenAvatar2");

		ltPath1 = new LTBezierPath(editorPath.vec3);
		ltPath2 = new LTBezierPath(editorPath.vec3);
	}
	// Use this for initialization
	void Start () 
	{
		Nuts = new Transform[numNuts];

		// Get the leantween editor path
		path = GetComponent<LeanTweenPath>();

		// Create a bezier path based on the path
		nutPath = new LTBezierPath(path.vec3);

		// Load up the prefab
		itemPrefab = Resources.Load("CrystalNutPrefab", typeof(GameObject)) as GameObject;

		// Fill up the array with nuts
		for (int i=0; i< Nuts.Length; i++)
			Nuts[i] = (Transform) Instantiate(itemPrefab).transform;

		float pct = 0.0f;
		//float portion = 1.0f/Nuts.Length + 0.1f;
		float portion = 1.0f / Nuts.Length;
		//print("portion:" + portion);
		for (int i = 0; i < Nuts.Length; i++)
		{
			//float pct = 0.1f * i * (10 / Nuts.Length);
			//print(pct);
			nutPath.place(Nuts[i], pct);
			pct += portion;

		}
	}
Exemple #4
0
 public static int constructor(IntPtr l)
 {
     try {
         int argc = LuaDLL.lua_gettop(l);
         LTBezierPath o;
         if(argc==1){
             o=new LTBezierPath();
             pushValue(l,true);
             pushValue(l,o);
             return 2;
         }
         else if(argc==2){
             UnityEngine.Vector3[] a1;
             checkType(l,2,out a1);
             o=new LTBezierPath(a1);
             pushValue(l,true);
             pushValue(l,o);
             return 2;
         }
         return error(l,"New object failed.");
     }
     catch(Exception e) {
         return error(l,e);
     }
 }
    void Start()
    {
        if(points.Count != 4)
        {
            Debug.LogError("You need 4 points to animate on a curve");
        }

        LTBezierPath ltPath = new LTBezierPath(new Vector3[]{ points[0].position, points[2].position, points[1].position, points[3].position });
        LeanTween.move(gameObject, ltPath.pts, duration).setEase(easing).setOnComplete(TurnOnCameraFollow);
    }
	void Start () {
		// Create a LTBezierPath from the array of vectors made with the LeanTween Editor
		ltBezierPath = new LTBezierPath( ltPathDefinition.vec3 );

		// Adding Light Posts
		for(int i = 0; i < ltBezierPath.pts.Length; i++){
			// Add a Trigger at each bezier control node (which is every fourth point)
			if(i%4==0){
				GameObject post = GameObject.Instantiate( prefabLightPost );
				post.AddComponent<TriggerPointExample>(); // This component will track the entering and exiting of the car along the path
				post.transform.position = ltBezierPath.pts[ i ];
			}
		}
	}
Exemple #7
0
	/**
	* Set the direction of a tween -1f for backwards 1f for forwards (currently only bezier and spline paths are supported)
	* @method setDirection ()
	* @param {float} direction:float the direction that the tween should run, -1f for backwards 1f for forwards
	* @return {LTDescr} LTDescr an object that distinguishes the tween
	* @example
	* LeanTween.moveSpline(gameObject, new Vector3[]{new Vector3(0f,0f,0f),new Vector3(1f,0f,0f),new Vector3(1f,0f,0f),new Vector3(1f,0f,1f)}, 1.5f).setDirection(-1f);<br>
	*/

	public LTDescr setDirection( float direction )
	{
		if(this.direction!=-1f && this.direction!=1f)
		{
			Debug.LogWarning("You have passed an incorrect direction of '"+direction+"', direction must be -1f or 1f");
			return this;
		}

		if(this.direction!=direction)
		{
			// Debug.Log("reverse path:"+this.path+" spline:"+this.spline);
			if(this.path!=null)
			{
				this.path = new LTBezierPath( LTUtility.reverse( this.path.pts ) );
			}
			else if(this.spline!=null)
			{
				this.spline = new LTSpline( LTUtility.reverse( this.spline.pts ) );
			}
		}

		return this;
	}
	public static LTDescr moveLocal(GameObject gameObject, LTBezierPath to, float time)
	{
		d = options();
		d.path = to;

		return pushNewTween(gameObject, new Vector3(1.0f, 0.0f, 0.0f), time, TweenAction.MOVE_CURVED_LOCAL, d);
	}
 public static LTDescr LTMoveLocal(this Transform self, LTBezierPath to, float time)
 {
     return LeanTween.moveLocal(self.gameObject, to, time);
 }
 void OnEnable()
 {
     cr = new LTBezierPath(new Vector3[] { trans[0].position, trans[2].position, trans[1].position, trans[3].position, trans[3].position, trans[5].position, trans[4].position, trans[6].position });
 }
 public static LTDescr LeanMove <T>(this T component, LTBezierPath to, float time) where T : Component
 {
     return(LeanTween.move(component.gameObject, to, time));
 }
 public static LTDescr LTMove(this LTDescr self, LTBezierPath to, float time)
 {
     return LeanTween.move(self.trans.gameObject, to, time);
 }
Exemple #13
0
	public static LTDescr moveLocal(GameObject gameObject, LTBezierPath to, float time) {
		d = options().setMoveCurvedLocal();
		d.optional.path = to;

		return pushNewTween(gameObject, new Vector3(1.0f, 0.0f, 0.0f), time, d);
	}
Exemple #14
0
 public LTDescr setPath( LTBezierPath path )
 {
     this.path = path;
     return this;
 }
 public static LTDescr LeanMoveLocal(this GameObject gameObject, LTBezierPath to, float time)
 {
     return(LeanTween.moveLocal(gameObject, to, time));
 }
	void Start () {
		Vector3[] v = new Vector3[]{new Vector3(25f,-7.025024f,42.0522f), new Vector3(22.76418f,-7.025024f,54.56692f), new Vector3(24.94595f,-7.025024f,49.29967f), new Vector3(17.67767f,-7.025024f,59.72987f), new Vector3(17.67767f,-7.025024f,59.72987f), new Vector3(7.247467f,-7.025024f,66.99815f), new Vector3(12.51471f,-7.025024f,64.81638f), new Vector3(-1.092785E-06f,-7.025024f,67.0522f), new Vector3(-1.092785E-06f,-7.025024f,67.0522f), new Vector3(-12.51472f,-7.025024f,64.81638f), new Vector3(-7.247468f,-7.025024f,66.99814f), new Vector3(-17.67767f,-7.025024f,59.72987f), new Vector3(-17.67767f,-7.025024f,59.72987f), new Vector3(-24.94594f,-7.025024f,49.29967f), new Vector3(-22.76418f,-7.025024f,54.56691f), new Vector3(-25f,-7.025024f,42.0522f), new Vector3(-25f,-7.025024f,42.0522f), new Vector3(-22.76418f,-7.025024f,29.53749f), new Vector3(-24.94594f,-7.025024f,34.80473f), new Vector3(-17.67767f,-7.025024f,24.37453f), new Vector3(-17.67767f,-7.025024f,24.37453f), new Vector3(-7.247469f,-7.025024f,17.10626f), new Vector3(-12.51471f,-7.025024f,19.28802f), new Vector3(2.98122E-07f,-7.025024f,17.0522f), new Vector3(2.98122E-07f,-7.025024f,17.0522f), new Vector3(12.51472f,-7.025024f,19.28802f), new Vector3(7.24747f,-7.025024f,17.10626f), new Vector3(17.67768f,-7.025024f,24.37454f), new Vector3(17.67768f,-7.025024f,24.37454f), new Vector3(24.94595f,-7.025024f,34.80473f), new Vector3(22.76418f,-7.025024f,29.53749f), new Vector3(25f,-7.025024f,42.0522f)};
		ltBezierPath = new LTBezierPath(v);
	}
 public static LTDescr LeanMove(this Transform transform, LTBezierPath to, float time)
 {
     return(LeanTween.move(transform.gameObject, to, time));
 }
Exemple #18
0
 private void OnEnable()
 {
     // create the path
     cr = new LTBezierPath(new Vector3[] { trans[0].position, trans[2].position, trans[1].position, trans[3].position, trans[3].position, trans[5].position, trans[4].position, trans[6].position });
 }
Exemple #19
0
 public LTDescr setPath(LTBezierPath path)
 {
     this.path = path;
     return(this);
 }
Exemple #20
0
    public static int moveLocal(GameObject gameObject, Vector3[] to, float time, Hashtable optional)
    {
        if(to.Length<4){
        string errorMsg = "LeanTween - When passing values for a vector path, you must pass four or more values!";
        if(throwErrors) Debug.LogError(errorMsg); else Debug.Log(errorMsg);
        return -1;
        }
        if(to.Length%4!=0){
        string errorMsg2 = "LeanTween - When passing values for a vector path, they must be in sets of four: controlPoint1, controlPoint2, endPoint2, controlPoint2, controlPoint2...";
        if(throwErrors) Debug.LogError(errorMsg2); else Debug.Log(errorMsg2);
        return -1;
        }

        init();
        if( optional == null )
        optional = new Hashtable();

        LTBezierPath ltPath = new LTBezierPath( to );
        if(optional["orientToPath"]!=null)
        ltPath.orientToPath = true;
        optional["path"] = ltPath;

        return pushNewTween( gameObject, new Vector3(1.0f,0.0f,0.0f), time, TweenAction.MOVE_CURVED_LOCAL, optional );
    }
 void OnEnable()
 {
     // create the path
     cr = new LTBezierPath( new Vector3[] {trans[0].position, trans[2].position, trans[1].position, trans[3].position, trans[3].position, trans[5].position, trans[4].position, trans[6].position} );
 }
Exemple #22
0
 /**
 * While tweening along a curve, set this property to true, to be perpendicalur to the path it is moving upon
 * @method setOrientToPath
 * @param {bool} doesOrient:bool whether the gameobject will orient to the path it is animating along
 * @return {LTDescr} LTDescr an object that distinguishes the tween
 * @example
 * LeanTween.move( ltLogo, path, 1.0f ).setEase(LeanTweenType.easeOutQuad).setOrientToPath(true).setAxis(Vector3.forward);<br>
 */
 public LTDescr setOrientToPath( bool doesOrient )
 {
     if(this.type==TweenAction.MOVE_CURVED || this.type==TweenAction.MOVE_CURVED_LOCAL){
         if(this.path==null)
             this.path = new LTBezierPath();
         this.path.orientToPath = doesOrient;
     }else{
         this.spline.orientToPath = doesOrient;
     }
     return this;
 }
Exemple #23
0
 /**
 * While tweening along a curve, set this property to true, to be perpendicalur to the path it is moving upon
 * @method setOrientToPath
 * @param {bool} doesOrient:bool whether the gameobject will orient to the path it is animating along
 * @return {LTDescr} LTDescr an object that distinguishes the tween
 * @example
 * LeanTween.move( ltLogo, path, 1.0f ).setEase(LeanTweenType.easeOutQuad).setOrientToPath(true);<br>
 */
 public LTDescr setOrientToPath( bool doesOrient )
 {
     if(this.path==null)
         this.path = new LTBezierPath();
     this.path.orientToPath = doesOrient;
     return this;
 }
Exemple #24
0
 void Start()
 {
     Vector3[] v = new Vector3[] { new Vector3(25f, -7.025024f, 42.0522f), new Vector3(22.76418f, -7.025024f, 54.56692f), new Vector3(24.94595f, -7.025024f, 49.29967f), new Vector3(17.67767f, -7.025024f, 59.72987f), new Vector3(17.67767f, -7.025024f, 59.72987f), new Vector3(7.247467f, -7.025024f, 66.99815f), new Vector3(12.51471f, -7.025024f, 64.81638f), new Vector3(-1.092785E-06f, -7.025024f, 67.0522f), new Vector3(-1.092785E-06f, -7.025024f, 67.0522f), new Vector3(-12.51472f, -7.025024f, 64.81638f), new Vector3(-7.247468f, -7.025024f, 66.99814f), new Vector3(-17.67767f, -7.025024f, 59.72987f), new Vector3(-17.67767f, -7.025024f, 59.72987f), new Vector3(-24.94594f, -7.025024f, 49.29967f), new Vector3(-22.76418f, -7.025024f, 54.56691f), new Vector3(-25f, -7.025024f, 42.0522f), new Vector3(-25f, -7.025024f, 42.0522f), new Vector3(-22.76418f, -7.025024f, 29.53749f), new Vector3(-24.94594f, -7.025024f, 34.80473f), new Vector3(-17.67767f, -7.025024f, 24.37453f), new Vector3(-17.67767f, -7.025024f, 24.37453f), new Vector3(-7.247469f, -7.025024f, 17.10626f), new Vector3(-12.51471f, -7.025024f, 19.28802f), new Vector3(2.98122E-07f, -7.025024f, 17.0522f), new Vector3(2.98122E-07f, -7.025024f, 17.0522f), new Vector3(12.51472f, -7.025024f, 19.28802f), new Vector3(7.24747f, -7.025024f, 17.10626f), new Vector3(17.67768f, -7.025024f, 24.37454f), new Vector3(17.67768f, -7.025024f, 24.37454f), new Vector3(24.94595f, -7.025024f, 34.80473f), new Vector3(22.76418f, -7.025024f, 29.53749f), new Vector3(25f, -7.025024f, 42.0522f) };
     ltBezierPath = new LTBezierPath(v);
 }
Exemple #25
0
        IEnumerator timeBasedTesting()
        {
            yield return(new WaitForEndOfFrame());

            GameObject cubeNormal = cubeNamed("normalTimeScale");

            // float timeElapsedNormal = Time.time;
            LeanTween.moveX(cubeNormal, 12f, 1.5f).setIgnoreTimeScale(false).setOnComplete(() => {
                timeElapsedNormalTimeScale = Time.time;
            });

            LTDescr[] descr = LeanTween.descriptions(cubeNormal);
            LeanTest.expect(descr.Length >= 0 && descr[0].to.x == 12f, "WE CAN RETRIEVE A DESCRIPTION");

            GameObject cubeIgnore = cubeNamed("ignoreTimeScale");

            LeanTween.moveX(cubeIgnore, 5f, 1.5f).setIgnoreTimeScale(true).setOnComplete(() => {
                timeElapsedIgnoreTimeScale = Time.time;
            });

            yield return(new WaitForSeconds(1.5f));

            LeanTest.expect(Mathf.Abs(timeElapsedNormalTimeScale - timeElapsedIgnoreTimeScale) < 0.7f, "START IGNORE TIMING", "timeElapsedIgnoreTimeScale:" + timeElapsedIgnoreTimeScale + " timeElapsedNormalTimeScale:" + timeElapsedNormalTimeScale);

//			yield return new WaitForSeconds(100f);
            Time.timeScale = 4f;

            int pauseCount = 0;

            LeanTween.value(gameObject, 0f, 1f, 1f).setOnUpdate(( float val ) => {
                pauseCount++;
            }).pause();

            // Bezier should end at exact end position not just 99% close to it
            Vector3[]  roundCirc  = new Vector3[] { new Vector3(0f, 0f, 0f), new Vector3(-9.1f, 25.1f, 0f), new Vector3(-1.2f, 15.9f, 0f), new Vector3(-25f, 25f, 0f), new Vector3(-25f, 25f, 0f), new Vector3(-50.1f, 15.9f, 0f), new Vector3(-40.9f, 25.1f, 0f), new Vector3(-50f, 0f, 0f), new Vector3(-50f, 0f, 0f), new Vector3(-40.9f, -25.1f, 0f), new Vector3(-50.1f, -15.9f, 0f), new Vector3(-25f, -25f, 0f), new Vector3(-25f, -25f, 0f), new Vector3(0f, -15.9f, 0f), new Vector3(-9.1f, -25.1f, 0f), new Vector3(0f, 0f, 0f) };
            GameObject cubeRound  = cubeNamed("bRound");
            Vector3    onStartPos = cubeRound.transform.position;

            LeanTween.moveLocal(cubeRound, roundCirc, 0.5f).setOnComplete(() => {
                LeanTest.expect(cubeRound.transform.position == onStartPos, "BEZIER CLOSED LOOP SHOULD END AT START", "onStartPos:" + onStartPos + " onEnd:" + cubeRound.transform.position);
            });

            // should be able to retrieve a point
            LTBezierPath roundCircPath = new LTBezierPath(roundCirc);
            float        ratioPoint    = roundCircPath.ratioAtPoint(new Vector3(-25f, 25f, 0f));

            LeanTest.expect(Mathf.Equals(ratioPoint, 0.25f), "BEZIER RATIO POINT");

            // Spline should end at exact end position not just 99% close to it
            Vector3[]  roundSpline      = new Vector3[] { new Vector3(0f, 0f, 0f), new Vector3(0f, 0f, 0f), new Vector3(2f, 0f, 0f), new Vector3(0.9f, 2f, 0f), new Vector3(0f, 0f, 0f), new Vector3(0f, 0f, 0f) };
            GameObject cubeSpline       = cubeNamed("bSpline");
            Vector3    onStartPosSpline = cubeSpline.transform.position;

            LeanTween.moveSplineLocal(cubeSpline, roundSpline, 0.5f).setOnComplete(() => {
                LeanTest.expect(Vector3.Distance(onStartPosSpline, cubeSpline.transform.position) <= 0.01f, "SPLINE CLOSED LOOP SHOULD END AT START", "onStartPos:" + onStartPosSpline + " onEnd:" + cubeSpline.transform.position + " dist:" + Vector3.Distance(onStartPosSpline, cubeSpline.transform.position));
            });

            // Sequence test, do three tweens and make sure they end at the right points
            GameObject cubeSeq = cubeNamed("cSeq");
            var        seq     = LeanTween.sequence().append(LeanTween.moveX(cubeSeq, 100f, 0.2f));

            seq.append(0.1f).append(LeanTween.scaleX(cubeSeq, 2f, 0.1f));
            seq.append(() => {
                LeanTest.expect(cubeSeq.transform.position.x == 100f, "SEQ MOVE X FINISHED", "move x:" + cubeSeq.transform.position.x);
                LeanTest.expect(cubeSeq.transform.localScale.x == 2f, "SEQ SCALE X FINISHED", "scale x:" + cubeSeq.transform.localScale.x);
            }).setScale(0.2f);

            // Bounds check
            GameObject cubeBounds    = cubeNamed("cBounds");
            bool       didPassBounds = true;
            Vector3    failPoint     = Vector3.zero;

            LeanTween.move(cubeBounds, new Vector3(10, 10, 10), 0.1f).setOnUpdate((float val) => {
//				Debug.LogWarning("cubeBounds x:"+cubeBounds.transform.position.x + " y:"+ cubeBounds.transform.position.y+" z:"+cubeBounds.transform.position.z);
                if (cubeBounds.transform.position.x < 0f || cubeBounds.transform.position.x > 10f || cubeBounds.transform.position.y < 0f || cubeBounds.transform.position.y > 10f || cubeBounds.transform.position.z < 0f || cubeBounds.transform.position.z > 10f)
                {
                    didPassBounds = false;
                    failPoint     = cubeBounds.transform.position;
//					Debug.LogError("OUT OF BOUNDS");
                }
            }).setLoopPingPong().setRepeat(8).setOnComplete(() => {
                LeanTest.expect(didPassBounds, "OUT OF BOUNDS", "pos x:" + failPoint.x + " y:" + failPoint.y + " z:" + failPoint.z);
            });

            // Local scale check
            //GameObject cubeLocal = cubeNamed("cLocal");
            //LeanTween.scale(cubeLocal, new Vector3(0.5f, 0.5f, 0.5f), 0.2f).setOnComplete(() =>
            //{
            //    LeanTest.expect((cubeLocal.transform.localScale.x == 0.5f && cubeLocal.transform.localScale.y == 0.5f && cubeLocal.transform.localScale.z == 0.5f), "SCALE WORKS", "scale x:" + cubeLocal.transform.localScale.x + " y:" + cubeLocal.transform.localScale.y + " z:" + cubeLocal.transform.localScale.z);
            //});

            // Groups of tweens testing
            groupTweens    = new LTDescr[1200];
            groupGOs       = new GameObject[groupTweens.Length];
            groupTweensCnt = 0;
            int descriptionMatchCount = 0;

            for (int i = 0; i < groupTweens.Length; i++)
            {
                GameObject cube = cubeNamed("c" + i);
                cube.transform.position = new Vector3(0, 0, i * 3);

                groupGOs[i] = cube;
            }

            yield return(new WaitForEndOfFrame());

            bool hasGroupTweensCheckStarted = false;
            int  setOnStartNum  = 0;
            int  setPosNum      = 0;
            bool setPosOnUpdate = true;

            for (int i = 0; i < groupTweens.Length; i++)
            {
                Vector3 finalPos = transform.position + Vector3.one * 3f;
                Dictionary <string, object> finalDict = new Dictionary <string, object> {
                    { "final", finalPos }, { "go", groupGOs[i] }
                };
                groupTweens[i] = LeanTween.move(groupGOs[i], finalPos, 3f).setOnStart(() => {
                    setOnStartNum++;
                }).setOnUpdate((Vector3 newPosition) => {
                    if (transform.position.z > newPosition.z)
                    {
                        setPosOnUpdate = false;
                    }
//					Debug.LogWarning("New Position: " + newPosition.ToString());
                }).
                                 setOnCompleteParam(finalDict).
                                 setOnComplete((object param) => {
                    Dictionary <string, object> finalDictRetr = param as Dictionary <string, object>;
                    Vector3 neededPos    = (Vector3)finalDictRetr["final"];
                    GameObject tweenedGo = finalDictRetr["go"] as GameObject;
                    if (neededPos.ToString() == tweenedGo.transform.position.ToString())
                    {
                        setPosNum++;
                    }
                    else
                    {
//						Debug.Log("neededPos:"+neededPos+" tweenedGo.transform.position:"+tweenedGo.transform.position);
                    }
                    if (hasGroupTweensCheckStarted == false)
                    {
                        hasGroupTweensCheckStarted = true;
                        LeanTween.delayedCall(gameObject, 0.1f, () => {
                            LeanTest.expect(setOnStartNum == groupTweens.Length, "SETONSTART CALLS", "expected:" + groupTweens.Length + " was:" + setOnStartNum);
                            LeanTest.expect(groupTweensCnt == groupTweens.Length, "GROUP FINISH", "expected " + groupTweens.Length + " tweens but got " + groupTweensCnt);
                            LeanTest.expect(setPosNum == groupTweens.Length, "GROUP POSITION FINISH", "expected " + groupTweens.Length + " tweens but got " + setPosNum);
                            LeanTest.expect(setPosOnUpdate, "GROUP POSITION ON UPDATE");
                        });
                    }
                    groupTweensCnt++;
                });

                if (LeanTween.description(groupTweens[i].id).trans == groupTweens[i].trans)
                {
                    descriptionMatchCount++;
                }
            }

            while (LeanTween.tweensRunning < groupTweens.Length)
            {
                yield return(null);
            }

            LeanTest.expect(descriptionMatchCount == groupTweens.Length, "GROUP IDS MATCH");
            int expectedSearch = groupTweens.Length + 7;

            LeanTest.expect(LeanTween.maxSearch <= expectedSearch, "MAX SEARCH OPTIMIZED", "maxSearch:" + LeanTween.maxSearch + " should be:" + expectedSearch);
            LeanTest.expect(LeanTween.isTweening() == true, "SOMETHING IS TWEENING");

            // resume item before calling pause should continue item along it's way
            float previousXlt4 = cube4.transform.position.x;

            lt4 = LeanTween.moveX(cube4, 5.0f, 1.1f).setOnComplete(() => {
                LeanTest.expect(cube4 != null && previousXlt4 != cube4.transform.position.x, "RESUME OUT OF ORDER", "cube4:" + cube4 + " previousXlt4:" + previousXlt4 + " cube4.transform.position.x:" + (cube4 != null ? cube4.transform.position.x : 0));
            }).setDestroyOnComplete(true);
            lt4.resume();

            rotateRepeat = rotateRepeatAngle = 0;
            LeanTween.rotateAround(cube3, Vector3.forward, 360f, 0.1f).setRepeat(3).setOnComplete(rotateRepeatFinished).setOnCompleteOnRepeat(true).setDestroyOnComplete(true);
            yield return(new WaitForEndOfFrame());

            LeanTween.delayedCall(0.1f * 8f + 1f, rotateRepeatAllFinished);

            int countBeforeCancel = LeanTween.tweensRunning;

            LeanTween.cancel(lt1Id);
            LeanTest.expect(countBeforeCancel == LeanTween.tweensRunning, "CANCEL AFTER RESET SHOULD FAIL", "expected " + countBeforeCancel + " but got " + LeanTween.tweensRunning);
            LeanTween.cancel(cube2);

            int tweenCount = 0;

            for (int i = 0; i < groupTweens.Length; i++)
            {
                if (LeanTween.isTweening(groupGOs[i]))
                {
                    tweenCount++;
                }
                if (i % 3 == 0)
                {
                    LeanTween.pause(groupGOs[i]);
                }
                else if (i % 3 == 1)
                {
                    groupTweens[i].pause();
                }
                else
                {
                    LeanTween.pause(groupTweens[i].id);
                }
            }
            LeanTest.expect(tweenCount == groupTweens.Length, "GROUP ISTWEENING", "expected " + groupTweens.Length + " tweens but got " + tweenCount);

            yield return(new WaitForEndOfFrame());

            tweenCount = 0;
            for (int i = 0; i < groupTweens.Length; i++)
            {
                if (i % 3 == 0)
                {
                    LeanTween.resume(groupGOs[i]);
                }
                else if (i % 3 == 1)
                {
                    groupTweens[i].resume();
                }
                else
                {
                    LeanTween.resume(groupTweens[i].id);
                }

                if (i % 2 == 0 ? LeanTween.isTweening(groupTweens[i].id) : LeanTween.isTweening(groupGOs[i]))
                {
                    tweenCount++;
                }
            }
            LeanTest.expect(tweenCount == groupTweens.Length, "GROUP RESUME");

            LeanTest.expect(LeanTween.isTweening(cube1) == false, "CANCEL TWEEN LTDESCR");
            LeanTest.expect(LeanTween.isTweening(cube2) == false, "CANCEL TWEEN LEANTWEEN");

            LeanTest.expect(pauseCount == 0, "ON UPDATE NOT CALLED DURING PAUSE", "expect pause count of 0, but got " + pauseCount);


            yield return(new WaitForEndOfFrame());

            Time.timeScale = 0.25f;
            float tweenTime         = 0.2f;
            float expectedTime      = tweenTime * (1f / Time.timeScale);
            float start             = Time.realtimeSinceStartup;
            bool  onUpdateWasCalled = false;

            LeanTween.moveX(cube1, -5f, tweenTime).setOnUpdate((float val) => {
                onUpdateWasCalled = true;
            }).setOnComplete(() => {
                float end  = Time.realtimeSinceStartup;
                float diff = end - start;

                LeanTest.expect(Mathf.Abs(expectedTime - diff) < 0.06f, "SCALED TIMING DIFFERENCE", "expected to complete in roughly " + expectedTime + " but completed in " + diff);
                LeanTest.expect(Mathf.Approximately(cube1.transform.position.x, -5f), "SCALED ENDING POSITION", "expected to end at -5f, but it ended at " + cube1.transform.position.x);
                LeanTest.expect(onUpdateWasCalled, "ON UPDATE FIRED");
            });

            bool didGetCorrectOnUpdate = false;

            LeanTween.value(gameObject, new Vector3(1f, 1f, 1f), new Vector3(10f, 10f, 10f), 1f).setOnUpdate(( Vector3 val ) => {
                didGetCorrectOnUpdate = val.x >= 1f && val.y >= 1f && val.z >= 1f;
            }).setOnComplete(() => {
                LeanTest.expect(didGetCorrectOnUpdate, "VECTOR3 CALLBACK CALLED");
            });

            yield return(new WaitForSeconds(expectedTime));

            Time.timeScale = 1f;

            int ltCount = 0;

            GameObject[] allGos = FindObjectsOfType(typeof(GameObject)) as GameObject[];
            foreach (GameObject go in allGos)
            {
                if (go.name == "~LeanTween")
                {
                    ltCount++;
                }
            }
            LeanTest.expect(ltCount == 1, "RESET CORRECTLY CLEANS UP");

            lotsOfCancels();
        }