-1

I am creating a first person shooter script. In order to get the bullet to travel straight at the cross-hair, I calculate the ray hit and shoot the bullet in that direction. The problem is if there is nothing within the range, it won't shoot at all, which isn't how a gun works. The script I have right now checks if there was a hit, and if there wasn't, it defaults to shooting straight out of the gun. Like so:

void Update () {

    if(Input.GetButtonDown("Fire1"))
    {
        Ray ray = Camera.main.ScreenPointToRay(crossHair.transform.position);

        GameObject bullet = Instantiate(bullet_prefab, bullet_spawn.transform.position, bullet_spawn.transform.rotation) as GameObject;
        Rigidbody bulletRigidbody = bullet.GetComponent<Rigidbody>();

        if (Physics.Raycast(ray, out rayHit, 100000.0f))
        {
            Debug.DrawLine(bullet_spawn.transform.position, rayHit.point, Color.red);

            bulletRigidbody.AddForce((rayHit.point - bullet_spawn.transform.position).normalized * bulletImpulse, ForceMode.Impulse);
        }
        else
        {
            bulletRigidbody.AddForce(bullet_spawn.transform.position * bulletImpulse, ForceMode.Impulse);
        }

        EmitShotParticles();
    }

}

The problem with this is that it seems it would be unfair. The player can have the cross-hair directly beside a target and still hit them. I need a way to constantly shoot at a direct ray to the cross-hair from the gun, rather than two separate calculations for the bullets path.

Olivier Moindrot
  • 27,908
  • 11
  • 92
  • 91
Kyle Jensen
  • 419
  • 9
  • 27
  • Are you saying you have a crosshair that stays in the centre of the screen or that moves around the screen? Also, what do you mean by "range"? Range of what? – Tom Oct 08 '15 at 15:16

3 Answers3

0

Why do you even need the Raycast(...) ??

if(Input.GetButtonDown("Fire1"))
{
    Ray ray = Camera.main.ScreenPointToRay(crossHair.transform.position);

    GameObject bullet = Instantiate(bullet_prefab, bullet_spawn.transform.position, bullet_spawn.transform.rotation) as GameObject;
    Rigidbody bulletRigidbody = bullet.GetComponent<Rigidbody>();

    Vector3 direction = (ray.GetPoint(100000.0f) - bullet.transform.position).normalized;

    bulletRigidbody.AddForce(direction * bulletImpulse, ForceMode.Impulse);

    EmitShotParticles();
}
maraaaaaaaa
  • 7,749
  • 2
  • 22
  • 37
  • I need a raycast because otherwise the bullet will not be travelling towards the crosshairs... – Kyle Jensen Oct 08 '15 at 19:25
  • why do you think that? – maraaaaaaaa Oct 08 '15 at 19:25
  • If I dont have a raycast there is no telling where to put the crosshairs, as it would change by distance – Kyle Jensen Oct 08 '15 at 19:26
  • I dont think that I know that :P I've tried it which lead me to the Raycast solution – Kyle Jensen Oct 08 '15 at 19:26
  • 1
    All a `Raycast` does is look for a collision by a `Ray` and return the result of that collision. You do not need a `Raycast`. You already know where the crosshairs are, they are at the `crossHair.transform.position`, and your `Raycast` has no effect on the location of them. – maraaaaaaaa Oct 08 '15 at 19:27
  • This is a perfect example of an `XY Problem` http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem . Hence, you are asking about a solution to your attempted *solution* rather than your actual *problem*. – maraaaaaaaa Oct 08 '15 at 19:31
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/91786/discussion-between-kyle-jensen-and-lolslowsti). – Kyle Jensen Oct 08 '15 at 19:40
0

You need to shoot the bullet without a raycast and emit the particles on hit or when the raycast succeeds.

Horothenic
  • 680
  • 6
  • 12
-1

There's a good first person shooter tutorial here.

Which contains shooting code (below). All you need is a rocket (or bullet) prefab and a shoot script attached to (for example) your gun.

public GameObject rocketPrefab;

void Update () {
    // left mouse clicked?
    if (Input.GetMouseButtonDown(0)) {

        GameObject g = (GameObject)Instantiate(rocketPrefab, transform.position, transform.parent.rotation);

        // make the rocket fly forward by simply calling the rigidbody's
        // AddForce method
        // (requires the rocket to have a rigidbody attached to it)
        float force = g.GetComponent<Rocket>().speed;
        g.rigidbody.AddForce(g.transform.forward * force);
    }
}
Tom
  • 2,372
  • 4
  • 25
  • 45