I am trying to make an animation system that affects different types so I thought I would use generics.
I have an animation controller that gets all animation objects into a collection (or at least that was the plan) then then run the animation on all the animation objects.
The problem is I can't do it this way in C# as it does not allow polymorphic collections for different types on generics.
Here is the code structure involved for different animations:
public abstract class Animation<T> {
protected T TargetValue {protected set; get;} // could be int/float/vector2 etc etc
protected T StartValue {protected set; get;}
public T CurrentValue {protected set; get;}
public Action OnUpdate;
public virtual T Animate(float deltaTime) => OnUpdate?.Invoke();
}
public class Fade : Animation<float> { // lerp between two floats
public override float Animate(float deltaTime) {
CurrentValue = float.Lerp(StartValue,TargetValue,deltaTime);
base.Animate(deltaTime);
}
}
public class Translation : Animation<Vector2> { // move to target Vector2
public override Vector2 Animate(float deltaTime) {
CurrentValue = Vector2.Lerp(StartValue,TargetValue,deltaTime);
base.Animate(deltaTime);
}
}
Now my animation controller class is supposed to get all animations an run animations on them:
public class AnimationController {
private List<Animation<???>> _animations = new List<Animation<???>>();
void Init() => _animations = GetAllComponents<Animation>(); // get all animations as collection
public void Animation(float deltaTime)
for(int i = 0; i < _animations.Count; i++)
_animations[i].Animate(deltaTime);
}
}
However, this is not an option for me as I cannot have collections of generics with different types for the generic T
.
So what would be a better design for this system because I do not know a good solution ???
Animate()
methods have different return types. It doesn't look like you're actually using the return values though ... can you remove it or make the return type consistent and haveAnimate<T>
implement an interface?