private void SetGameObjectForRef(GameObject root, Ref childRef, float time)
        {
            TimelineKey key = childRef.Referenced;

            if (time < 0)
            {
                time = key.Time;
            }

            TimelineKey lastKey;

            lastKeyframeCache.TryGetValue(key.Timeline, out lastKey);

            //Get the relative path based on the current hierarchy
            var relativePath = childRef.RelativePath;

            //If this is the root, skip it
            if (string.IsNullOrEmpty(relativePath))
            {
                Debug.Log("Skipping root node in SetGameObjectForRef (SHOULD NEVER HAPPEN)");
                return;
            }


            //Find the gameObject based on relative path
            var transform = root.transform.Find(relativePath);

            if (transform == null)
            {
                Debug.LogError("ERROR: Unable to find GameObject at relative path " + relativePath);
                return;
            }

            var gameObject = transform.gameObject;

            gameObject.SetActive(true);

            //Get transform data from ref
            Vector3 localPosition;
            Vector3 localScale;
            Vector3 localEulerAngles;

            childRef.BakeTransforms(out localPosition, out localEulerAngles, out localScale);

            //Set the current GameObject's transform data
            transform.localPosition = localPosition;
            transform.localScale    = localScale;

            //Spin the object in the correct direction
            var oldEulerAngles = transform.localEulerAngles;

            if (oldEulerAngles.z - localEulerAngles.z > 180)
            {
                localEulerAngles.z += 360;
            }
            else if (localEulerAngles.z - oldEulerAngles.z > 180)
            {
                localEulerAngles.z -= 360;
            }

            /*
             * switch(childRef.Unmapped.Spin)
             * {
             *  case SpinDirection.Clockwise:
             *      while (oldEulerAngles.z > localEulerAngles.z) localEulerAngles.z += 360;
             *      break;
             *  case SpinDirection.CounterClockwise:
             *      while (oldEulerAngles.z < localEulerAngles.z) localEulerAngles.z -= 360;
             *      break;
             * }*/
            transform.localEulerAngles = localEulerAngles;

            int zIndex    = -1;
            var spriteKey = key as SpriteTimelineKey;

            if (spriteKey != null)
            {
                zIndex = ((ObjectRef)childRef).ZIndex;
                //transform.GetComponent<SpriteRenderer>().sortingOrder = zIndex;
            }

            acb.SetCurve(root.transform, transform, time, lastKey, zIndex);


            //Get last-used game object for this Timeline - needed to clean up reparenting
            GameObject lastGameObject;

            if (lastGameObjectCache.TryGetValue(key.Timeline, out lastGameObject) && gameObject != lastGameObject)
            {
                //Let Unity handle the global->local position cruft for us
                lastGameObject.transform.position    = transform.position;
                lastGameObject.transform.eulerAngles = transform.eulerAngles;

                //TODO: Also need to do something about scale - this is a little more tricky
                lastGameObject.transform.localScale = localScale;

                //Deactivate the old object
                lastGameObject.SetActive(false);

                acb.SetCurve(root.transform, lastGameObject.transform, time, lastKey);
            }

            //Set cached value for last keyframe
            lastKeyframeCache[key.Timeline] = key;
        }