Demigiant / dotween

A Unity C# animation engine. HOTween v2
http://dotween.demigiant.com
Other
2.33k stars 348 forks source link

Move To follow target in DOTweenAnimation component. #565

Open LesserM7md opened 2 years ago

LesserM7md commented 2 years ago

I'm trying to get an object to follow a moving target using the animation component but the DOTweenAnimation only loops between the original position the target object was at. I see here that that was the intended behavior. But do you plan on adding the DOTweenFollow component in the future?

brucezhu99 commented 2 years ago

The DOTweenFollow I think it is necessary, you can add this function pls, thanks!

MuhammedResulBilkil commented 2 years ago

I have the same struggle. It would be so lovely to have something like follow transform at runtime. When the tracked transform's position changes, maybe the tween we set will follow with some offset distance?

otdavies commented 1 year ago

I second this as a major drawback of DOTween. We need something akin to transform.MoveTo(target.transform, 0.5f).

public static void MoveTo(this Transform transform, Transform target, float duration) {
    // Poll the target position each update tick
}

Execution on / off main thread can causes challenges when working with transforms, but this is something that should be possible - even if we have to accept main thread only execution for this scenario.

Voley commented 1 year ago

Same, we need some follow tween.

Anma-wp commented 1 year ago

You can make the object move in the target local space that would be similar to moving toward the target object. Something like that:

public static TweenerCore<Vector3, Vector3, VectorOptions> DOMoveInTargetLocalSpace(this Transform transform, Transform target, Vector3 targetLocalEndPosition, float duration)
        {
            var t = DOTween.To(
                () => transform.position - target.transform.position, // Value getter
                x => transform.position = x + target.transform.position, // Value setter
                targetLocalEndPosition, 
                duration);
            t.SetTarget(transform);
            return t;
        }

You can also try playing with formulas to make the movement even better. All that you need is set the right value in DOSetter. I think you got the idea.

builder-main commented 1 year ago

http://forum.demigiant.com/index.php?topic=225.0 this also

builder-main commented 1 year ago

This works pretty well for me, feel free to adapt. It updates the end position at some defined time. you could reduce steps and nextUpdate initial value. Chunks needs to be large enough or you'll enter the ease out and start having weird speed issues.

                    float GetDistance()
                    {
                        return Vector3.Distance(tmpTarget.transform.position, target.position);
                    }

                    var updateStep = GetDistance() * 0.3f;
                    var nextUpdate = GetDistance() * 0.7f;
                    tween
                        //updating target for taking moving into account
                        //.OnStart(() => { tween.ChangeEndValue(target.position, snapStartValue: true);})
                        .OnUpdate(() =>
                    {

                        if ( GetDistance() < nextUpdate)
                        {
                            DebugGraph.Log("Updated", GetDistance());
                            tween.SetEase(GetOutEaseVersion(tweenSettings.EaseType))
                                .ChangeEndValue(target.position, snapStartValue: true, newDuration: tween.Duration() - tween.Elapsed());
                            nextUpdate -= updateStep;
                        }

                    });

      /// <summary>
        /// Update the ease type to out only when updating the move target to avoid re-easing in.
        /// </summary>
        /// <param name="tweenSettingsEaseType"></param>
        /// <returns></returns>
        private static Ease GetOutEaseVersion(Ease tweenSettingsEaseType)
        {
            switch (tweenSettingsEaseType)
            {
                case Ease.InOutSine: return Ease.OutSine;
                case Ease.InOutFlash: return Ease.OutFlash;
                case Ease.InOutQuad: return Ease.OutQuad;
                case Ease.InOutCubic: return Ease.OutCubic;
                case Ease.InOutQuart: return Ease.OutQuart;
                case Ease.InOutQuint: return Ease.OutQuint;
                case Ease.InOutExpo: return Ease.OutExpo;
                case Ease.InOutCirc: return Ease.OutCirc ;
                case Ease.InOutElastic: return Ease.OutElastic;
                case Ease.InOutBack: return Ease.OutBack;
                case Ease.InOutBounce: return Ease.OutBounce;
                default:
                    return tweenSettingsEaseType;
            }
        }
Dacusx commented 1 year ago

You can make the object move in the target local space that would be similar to moving toward the target object. Something like that:

public static TweenerCore<Vector3, Vector3, VectorOptions> DOMoveInTargetLocalSpace(this Transform transform, Transform target, Vector3 targetLocalEndPosition, float duration)
        {
            var t = DOTween.To(
                () => transform.position - target.transform.position, // Value getter
                x => transform.position = x + target.transform.position, // Value setter
                targetLocalEndPosition, 
                duration);
            t.SetTarget(transform);
            return t;
        }

You can also try playing with formulas to make the movement even better. All that you need is set the right value in DOSetter. I think you got the idea.

Thanks! Works perfectly! In my case targetLocalEndPosition is just Vector3.zero

AvinoamHeroicRealm commented 1 year ago

You can make the object move in the target local space that would be similar to moving toward the target object. Something like that:

public static TweenerCore<Vector3, Vector3, VectorOptions> DOMoveInTargetLocalSpace(this Transform transform, Transform target, Vector3 targetLocalEndPosition, float duration)
        {
            var t = DOTween.To(
                () => transform.position - target.transform.position, // Value getter
                x => transform.position = x + target.transform.position, // Value setter
                targetLocalEndPosition, 
                duration);
            t.SetTarget(transform);
            return t;
        }

You can also try playing with formulas to make the movement even better. All that you need is set the right value in DOSetter. I think you got the idea.

Works wonderfully! As if it was part of the library