- Home /
bullet's flight adjusts position according to a parent object ??
Scenraio: A captain on a pirate ship fires a shot from a pistol .. the shot flies through the air towards the target. if the ship were to roll heavily, the bullet may pass through the deck of the ship... ( its a really slow flying bullet ;)
So I need to have the bullet move on the same transform as the ship. How can I achieve this ?
I have tried the obvious ... simply placing a transform constraint on the bullet & the ship... but this did not work :(
any ideas how to achieve this would be greatly appreciated.
Edit : here the script attached to the missile "seeker"
[RequireComponent(typeof(Projectile))]
[RequireComponent(typeof(SmoothLookAtConstraint))]
public class DemoSeeker : MonoBehaviour
{
public float maxVelocity = 500;
public float acceleration = 75;
// Private Cache...
private Transform xform;
private Rigidbody rbd;
private SmoothLookAtConstraint lookConstraint;
private Projectile projectile;
private float minDrag = 10;
private float drag = 40;
private void Awake()
{
this.xform = this.transform;
this.rbd = this.rigidbody;
this.lookConstraint = this.GetComponent<SmoothLookAtConstraint>();
this.projectile = this.GetComponent<Projectile>();
this.projectile.AddOnLaunchedDelegate(this.OnLaunched);
this.projectile.AddOnLaunchedUpdateDelegate(this.OnLaunchedUpdate);
this.projectile.AddOnDetonationDelegate(this.OnDetonateProjectile);
}
/// <summary>
/// Runs when launched.
/// </summary>
private void OnLaunched()
{
// Reset the rigidbody state when launced. This is only needed when pooling.
this.rbd.drag = this.drag;
// This is a great place to start a fire trail effect. Try a UnityConstraint
// Transform constraint to attach it by making this.transform its target.
}
/// <summary>
/// Runs each frame while the projectile is live
/// </summary>
private void OnLaunchedUpdate()
{
// If the target is active, fly to it, otherwise, continue straight
// The constraint should be set to do nothing when there is no target
// If there is no target, hit anything in the target layers.
if (!this.projectile.target.isSpawned) // Despawned
{
this.lookConstraint.target = null;
this.projectile.detonationMode = Projectile.DETONATION_MODES.HitLayers;
}
else
{
this.lookConstraint.target = this.projectile.target.transform;
this.projectile.detonationMode = Projectile.DETONATION_MODES.TargetOnly;
}
// Simulate acceleration by starting with a high drag and reducing it
// until it reaches the target drag. Init drag in start().
if (this.rbd.drag > this.minDrag)
this.rbd.drag -= (this.acceleration * 0.01f);
// Fly straight, constraint will handle rotation
this.rbd.AddForce(this.xform.forward * this.maxVelocity);
}
/// <summary>
/// A delegate run by the projectile component when this projectile detonates
/// </summary>
private void OnDetonateProjectile(TargetList targets)
{
// A great place for an explosion effect to be triggered!
}
}
How is the bullet moved: Rigidbody/Add force or Transform? So if the bullet is shot across the ship and the ship rolls, you want the bullet to rise up like it is connected to the ship?
Not much clearer. The object has a Rigidbody. Are you moving it by changing the position using Transform.position, or are you using Rigidbody.AddForce() to move the bullet?
And for the second question, what do you want to happen? If the ship rolls during the bullet flight, do you want the bullet to rise in flight like it is connected to the ship in some way, or are you looking for another bahavior?
Posting the code you have so far along with a clearer description of what you are seeking would be very helpful.
it should not be 'this.xform = Ship.transform'. If it has a chance of working it would be
this.xform.parent = Ship.transform;
You might also disable OnLaunchdUpdate() by putting a return in the top of the function and adding this line to OnLaunched().
this.rbd.AddForce(this.xform.forward * 1000.0);
I'm in the dark here about the actual problem you are trying to solve. It may be that ins$$anonymous$$d of trying to move the projectile with the rotation of the ship you should be adding logic to to the SmoothLookAtConstraint code so that the projectile avoids collision with the launch ship.
Add force upward based upward based on the distance to the surface of the ship is a great idea. I'd replace line 66 in the missile script with the following (untested) code:
Vector3 v3ForceDirection = this.xform.forward;
RaycastHit hit;
if (Physics.Raycast (transform.position, Vector3.down, out hit, max_dist) && hit.collider.name == "Ship") {
v3ForceDirection = v3ForceDirection + Vector3.up * (max_dist - hit.distance) * factor;
v3ForceDirection.Normalize();
}
this.rbd.AddForce(v3ForceDirection * this.maxVelocity);
Notes:
Replace "Ship" with whatever you've named your ship. Or if you have multiple ships firing, you can use collider.tag and tag them all the same.
max_dist is the maximum distance you want to detect. I'd start with the distance the gun is off the surface of the ship.
Factor scales how much force will be applied. It is a value you will need to either define or hard code. The calculation is linear based on the distance of the hit from the missile. That is, the closer the missile is to the ship, the more force will be applied. You may need a more complex calculation, or you may need to increase the distance so that force is applied eariler.