private void FireBullet(RigidBody body, Transform transform, Vector2 localPos, float localAngle) { ShipBlueprint blueprint = this.blueprint.Res; if (blueprint.BulletType == null) { return; } Bullet bullet = blueprint.BulletType.Res.CreateBullet(); Vector2 recoilImpulse; Vector2 worldPos = transform.GetWorldPoint(localPos); bullet.Fire(this.owner, body.LinearVelocity, worldPos, transform.Angle + localAngle, out recoilImpulse); body.ApplyWorldImpulse(recoilImpulse); Scene.Current.AddObject(bullet.GameObj); SoundInstance inst = null; if (Player.AlivePlayers.Count() > 1) { inst = DualityApp.Sound.PlaySound3D(this.owner.WeaponSound, new Vector3(worldPos)); } else { inst = DualityApp.Sound.PlaySound(this.owner.WeaponSound); } inst.Volume = MathF.Rnd.NextFloat(0.6f, 1.0f); inst.Pitch = MathF.Rnd.NextFloat(0.9f, 1.11f); }
void ICmpCollisionListener.OnCollisionSolve(Component sender, CollisionEventArgs args) { RigidBodyCollisionEventArgs bodyArgs = args as RigidBodyCollisionEventArgs; if (bodyArgs == null) { return; } if (bodyArgs.OtherShape.IsSensor) { return; } Transform myTransform = this.GameObj.Transform; RigidBody otherBody = bodyArgs.OtherShape.Parent; // Apply an impulse at the (world-space) position of the collision Vector2 impulseDirection = bodyArgs.CollisionData.Normal; Vector2 applyWorldPos = bodyArgs.CollisionData.Pos; otherBody.ApplyWorldImpulse( impulseDirection * 100.0f, applyWorldPos); // Display a log to note that we did so VisualLogs.Default .DrawVector(new Vector3(applyWorldPos), impulseDirection * 15.0f) .KeepAlive(1000.0f); }
void ICmpCollisionListener.OnCollisionBegin(Component sender, CollisionEventArgs args) { RigidBodyCollisionEventArgs bodyArgs = args as RigidBodyCollisionEventArgs; if (bodyArgs == null) { return; } if (bodyArgs.OtherShape.IsSensor) { return; } // Did we collide with a ship? If it's the same that fired the bullet, ignore this Ship otherShip = args.CollideWith.GetComponent <Ship>(); if (otherShip != null && otherShip.Owner == this.owner) { return; } // Get all the objet references we'll need RigidBody otherBody = args.CollideWith.RigidBody; Transform transform = this.GameObj.Transform; RigidBody body = this.GameObj.RigidBody; BulletBlueprint blueprint = this.blueprint.Res; // Okay, let's determine where *exactly* our bullet hit RayCastData firstHit; bool hitAnything = RigidBody.RayCast(transform.Pos.Xy - body.LinearVelocity * 2, transform.Pos.Xy + body.LinearVelocity * 2, data => { if (data.Shape.IsSensor) { return(-1.0f); } return(data.Fraction); }, out firstHit); Vector3 hitPos; float hitAngle; if (hitAnything) { hitPos = new Vector3(firstHit.Pos, 0.0f); hitAngle = (-firstHit.Normal).Angle; } else { // Note that it is possible for the raycast to not hit anything, // because it is essentially a line, while our bullet is wider than zero. hitPos = transform.Pos; hitAngle = transform.Angle; } // Push around whatever we've just hit and do damage, if it was a ship otherBody.ApplyWorldImpulse(body.LinearVelocity * MathF.Min(otherBody.Mass, blueprint.ImpactMass), transform.Pos.Xy); if (otherShip != null) { otherShip.DoDamage(blueprint.Damage); } // If we hit a part of the world, spawn the world hit effect if (otherShip == null && blueprint.HitWorldEffect != null) { GameObject effectObj = blueprint.HitWorldEffect.Res.Instantiate(hitPos, hitAngle); Scene.Current.AddObject(effectObj); } // Also spawn a generic hit effect in the color of the bullet if (blueprint.HitEffect != null) { GameObject effectObj = blueprint.HitEffect.Res.Instantiate(hitPos, hitAngle); ParticleEffect effect = effectObj.GetComponent <ParticleEffect>(); if (effect != null && this.owner != null) { ColorHsva color = this.owner.Color.ToHsva(); foreach (ParticleEmitter emitter in effect.Emitters) { emitter.MaxColor = emitter.MaxColor.WithSaturation(color.S).WithHue(color.H); emitter.MinColor = emitter.MinColor.WithSaturation(color.S).WithHue(color.H); } } Scene.Current.AddObject(effectObj); } // Play hit sounds if (blueprint.HitSound != null) { SoundInstance inst = DualityApp.Sound.PlaySound3D(blueprint.HitSound, hitPos); inst.Pitch = MathF.Rnd.NextFloat(0.95f, 1.05f); } HitSoundController otherHitSound = otherBody.GameObj.GetComponent <HitSoundController>(); if (otherHitSound != null) { otherHitSound.NotifyHit(MathF.Rnd.NextFloat(0.75f, 1.0f)); } // Delete the bullet this.GameObj.DisposeLater(); }