protected override void Execute(int execID, EntityID entity, ref VelocityComponent velo, ref TransformComponent trans) { if (velo.Velocity == Vector3.zero) { return; } Vector3 newPos = trans.Matrix.Position + velo.Velocity * deltaTime.Value; Vector3 dir = FastNormalize(velo.Velocity); trans.Matrix = Float3x4.FromPositionAndForward(newPos, dir); }
private void FireProjectile(ref ProjectileSpawnerComponent spawner, ref TransformComponent turretTrans) { const float INVERSE_PROJECTILE_SPEED = 1f / 100f; Vector3 turretPos = turretTrans.Matrix.Position; Vector3 targetPos = context.GetComponent <TransformComponent>(spawner.Target.Value).Matrix.Position; Vector3 targetVelo = context.GetComponent <VelocityComponent>(spawner.Target.Value).Velocity; float distanceEst = ManhattanDistance(targetPos - turretPos); float flightTime = distanceEst * INVERSE_PROJECTILE_SPEED; if (flightTime <= 0f) { return; } //Aim ahead of the target to compensation for its movement Vector3 aimTarget = targetPos + targetVelo * flightTime; //Gather info about the trajectory from the turret to the aim-target Vector3 toAimTarget = aimTarget - turretPos; float toAimTargetSqrDist = toAimTarget.sqrMagnitude; float toAimTargetDist = Mathf.Sqrt(toAimTargetSqrDist); //TODO: See if we can get rid of the SquareRoot usage here Vector3 toAimTargetDir = toAimTarget * FastInvSqrRoot(toAimTargetSqrDist); //Create normalized vector aiming to toward the aim target //Speed that the projectile will be traveling at. (NOTE: Its not the same as the configured projectile speed we used //to estimate the flighttime, thats because the estimate did not compensate for the target velocity yet) float trajectorySpeed = toAimTargetDist / flightTime; //Calculate how much gravity we will encounter in the journey float gravity = ApplyGravitySystem.GRAVITY * flightTime; //Calculate the 'final' projectileVelocity and include the gravity compensation Vector3 projectileVelocity = toAimTargetDir * trajectorySpeed + Vector3.down * (gravity * .5f); //This is used to 'point' the turret, if we want to be cheap we could use the 'toAimTargetDir' but thats not //really accurate because it doesn't include the gravity compensation yet Vector3 velocityDir = FastNormalize(projectileVelocity); //Spawn the projectile entity var entity = context.CreateEntity(); context.SetComponent(entity, new TransformComponent(Float3x4.FromPosition(turretPos))); context.SetComponent(entity, new VelocityComponent(velocity: projectileVelocity)); context.SetComponent(entity, new GraphicComponent(graphicID: 2)); context.SetComponent(entity, new AgeComponent()); context.SetComponent(entity, new LifetimeComponent(totalLifetime: 3f)); context.SetTag <ProjectileTag>(entity); context.SetTag <ApplyGravityTag>(entity); //Update the turret to face the target turretTrans.Matrix = Float3x4.FromPositionAndForward(turretTrans.Matrix.Position, velocityDir); }