Converge To Transform Motion
Today I want to present a different type of motion. I just wrote a post about the new animation type FlowEnt has introduced, Echo, and I want to talk about the animation mentioned there.
The animation is pretty basic, some coins pop up and then they all converge to a collection point. I always thought that animation can be done with a simple particle system, and we try to implement that in my workplace, but we faced many issues and the code was sloppy, none of us liked how it turned out. So, during the end of year break, I decided to do it and it turned out great.
Here's how it looks:
And here comes the code:
particles.Echo()
.SetDelay(1.3f)
.ConvergeTo(target, 8f, SpeedType.Gravity)
.Start();
The vector based version:
particles.Echo()
.SetDelay(1.3f)
.ConvergeTo(Vector3.up * 5f, 8f, SpeedType.Gravity)
.Start();
And the motion code:
public class ConvergeToTransformMotion : ConvergeToVectorMotion
{
[Serializable]
public new class Builder : AbstractFloatSpeedTypeBuilder
{
[SerializeField]
private Transform target;
public override IEchoMotion Build()
=> new ConvergeToTransformMotion(item, target, speed, speedType);
}
public ConvergeToTransformMotion(ParticleSystem item, Transform target, float speed = DefaultSpeed, SpeedType speedType = DefaultSpeedType) : base(item, target.position, speed, speedType)
{
this.target = target;
}
private new readonly Transform target;
public override void OnUpdate(float deltaTime)
{
base.target = target.position;
base.OnUpdate(deltaTime);
}
}
public class ConvergeToVectorMotion : AbstractFloatSpeedTypeMotion<ParticleSystem>
{
[Serializable]
public class Builder : AbstractFloatSpeedTypeBuilder
{
[SerializeField]
private Vector3 target;
public override IEchoMotion Build()
=> new ConvergeToVectorMotion(item, target, speed, speedType);
}
public ConvergeToVectorMotion(ParticleSystem item, Vector3 target, float speed = DefaultSpeed, SpeedType speedType = DefaultSpeedType) : base(item, speed, speedType)
{
this.target = target;
}
protected Vector3 target;
protected Particle[] particles = new Particle[0];
public override void OnUpdate(float deltaTime)
{
if (particles.Length < item.main.maxParticles)
{
particles = new Particle[item.main.maxParticles];
}
int activeCount = item.GetParticles(particles);
for (int i = 0; i < activeCount; i++)
{
Particle particle = particles[i];
particles[i].position = Vector3.MoveTowards(particle.position, target, deltaTime * GetSpeed(Vector3.Distance(particle.position, target)));
}
item.SetParticles(particles, activeCount);
}
}
Looks great keep with the good work!
ReplyDelete