Abstract Motions

I recently had to do a pretty large refactor, due to the fact that each motion had a lot of redundant copy-paste code, so I decided to create a few abstract motions to provide easier coding for custom motions. They are very similar to the value-based ones, and their abstractisations. They are based on fundamental data structures common in Unity, such as float, Vector3, Quaternion, and others. 

public abstract class AbstractValueMotion<TItem, TValue> : AbstractTweenMotion<TItem>
    where TItem : class
    where TValue : struct
{
    protected AbstractValueMotion(TItem item, TValue value) : base(item)
    {
        this.value = value;
        lerpFunction = LerpFunction;
    }

    protected AbstractValueMotion(TItem item, TValue? from, TValue to) : base(item)
    {
        hasFrom = from != null;
        if (hasFrom)
        {
            this.from = from.Value;
        }
        hasTo = true;
        this.to = to;
        lerpFunction = LerpFunction;
    }

    private readonly bool hasFrom;
    private readonly bool hasTo;
    private readonly TValue value;
    private TValue from;
    private TValue to;
    private readonly Func<TValue, TValue, float, TValue> lerpFunction;
    protected abstract Func<TValue, TValue, float, TValue> LerpFunction { get; }
    protected abstract TValue GetFrom();
    protected abstract TValue GetTo(TValue from, TValue value);
    protected abstract void SetValue(TValue value);

    public override void OnStart()
    {
        if (!hasFrom)
        {
            from = GetFrom();
        }
        if (!hasTo)
        {
            to = GetTo(from, value);
        }
    }

    public override void OnUpdate(float t)
    {
        SetValue(lerpFunction(from, to, t));
    }
}

Now any of the said structures, you can create your own if you will, would have to implement this class. I can show you some examples.

public abstract class AbstractFloatMotion<TItem> : AbstractValueMotion<TItem, float>
    where TItem : class
{
    protected AbstractFloatMotion(TItem item, float value) : base(item, value)
    {
    }

    protected AbstractFloatMotion(TItem item, float? from, float to) : base(item, from, to)
    {
    }

    protected override Func<float, float, float, float> LerpFunction => Mathf.LerpUnclamped;
    protected override float GetTo(float from, float value) => from + value;
}
public abstract class AbstractVector3Motion<TItem> : AbstractValueMotion<TItem, Vector3>
    where TItem : class
{
    protected AbstractVector3Motion(TItem item, Vector3 value) : base(item, value)
    {
    }

    protected AbstractVector3Motion(TItem item, Vector3? from, Vector3 to) : base(item, from, to)
    {
    }

    protected override Func<Vector3, Vector3, float, Vector3> LerpFunction => Vector3.LerpUnclamped;
    protected override Vector3 GetTo(Vector3 from, Vector3 value) => from + value;
}
public abstract class AbstractColorMotion<TItem> : AbstractValueMotion<TItem, Color>
    where TItem : class
{
    protected AbstractColorMotion(TItem item, Color value) : base(item, value)
    {
    }

    protected AbstractColorMotion(TItem item, Color? from, Color to) : base(item, from, to)
    {
    }

    protected override Func<Color, Color, float, Color> LerpFunction => Color.LerpUnclamped;
    protected override Color GetTo(Color from, Color value) => from + value;
}

Any of these abstract motions can be used to create you own. Or you can write yours from scratch.

Comments

Popular Posts