Projectile not firing right - simple angle and velocity problem?

Hi guys

I am having some trouble getting a projectile to fire how I am after.
What I have is a crosshair that remains stationary in the center of the screen where the projectile will fire through (firePosition).
By using the mouse, they can drag to an x,y point in the screen with a z position about 3 behind the crosshair (handPosition).
Then when they fire, the projectile will go from the mouse position and through the crosshair using the 2 different positions to work out the angle of the shot.

using UnityEngine;
using System.Collections;

public class ProjectileFire : MonoBehaviour {

public float shootForce;
public Transform target;
Vector3 firePosition;
Vector3 handPosition;
public GameObject projectilePrefab;
// Use this for initialization
void Start () {

	firePosition = new Vector3(0,3,0);
}

// Update is called once per frame
void Update () {

	transform.LookAt(target);
	
	if (Input.GetMouseButtonDown(0))
	{
		
	}
	
	if (Input.GetMouseButtonUp(0))
	{
			handPosition = Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x,Input.mousePosition.y,3.0f));
		Instantiate (projectilePrefab,handPosition,Quaternion.identity);
		projectilePrefab.rigidbody.AddForce(transform.forward * shootForce);
	}
}

}

Any suggestions?
Thanks

There are some errors in the logic. You must get firePosition using ViewportToWorldPoint with (0.5, 0.5, hand distance + 3), and handPosition with (mouse pos X, mouse pos Y, hand distance), where hand distance is the distance from camera to hand (variable distFromCam added to the code to define this distance).

While the mouse button is pressed, calculate both, handPosition and firePosition, and when the mouse is released create and shoot the projectile - you must calculate the rotation to create the projectile in the shooting direction. Get a reference to the projectile instantiated and use it to add the shooting force in its forward direction:

...
public GameObject projectilePrefab;
public float distFromCam = 2.0f; // distance from camera to hand

void Update () {

    transform.LookAt(target);
    if (Input.GetMouseButton(0)) // aim while the mouse button is down
    {
         firePosition = Camera.main.ViewportToWorldPoint (new Vector3(0.5f, 0.5f, distFromCam+3.0f)); // 3D point at screen center, 3 units ahead hand
         handPosition = Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, distFromCam));
         // draw a debug line just to see what's happening (click Gizmos to see the line)
         Debug.DrawLine(handPosition, firePosition, Color.green);
    }
    if (Input.GetMouseButtonUp(0)) // shoot in last aimed direction when button released
    { 
       Vector3 projDir = firePosition - handPosition; // calculate the projectile direction
       // calculate rotation to turn projectile's forward direction to the shooting direction
       Quaternion rot = Quaternion.FromToRotation(Vector3.forward, projDir);
       // create the projectile in a variable to access its rigidbody...
       GameObject projectile = Instantiate (projectilePrefab, handPosition, rot);
       // then add force in the projectile's forward direction
       projectile.rigidbody.AddForce(projectile.transform.forward * shootForce);
       Destroy(projectile, 10); // destroy projectile after 10 seconds
    }
}

EDITED: I think you can recycle the projectile forever: create the projectile only once, then bring it to the shooting position when firing again - but you must make the rigidbody forget about the past, or it will continue doing whatever it was doing before (rotating, moving to the old direction, etc.) I suppose it can be done by zeroing the rigidbody velocities.

This is the ecologically correct version of the script above - the projectile is created once and recycled each time you shoot:

...
public GameObject projectilePrefab;
public float distFromCam = 2.0f; // distance from camera to hand
private GameObject projectile;   // current projectile

void Update () {

    transform.LookAt(target);
    if (Input.GetMouseButton(0)) // aim while the mouse button is down
    {
         firePosition = Camera.main.ViewportToWorldPoint (new Vector3(0.5f, 0.5f, distFromCam+3.0f)); // 3D point at screen center, 3 units ahead hand
         handPosition = Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, distFromCam));
         // draw a debug line just to see what's happening (click Gizmos to see the line)
         Debug.DrawLine(handPosition, firePosition, Color.green);
    }
    if (Input.GetMouseButtonUp(0)) // shoot in last aimed direction when button released
    { 
       Vector3 projDir = firePosition - handPosition; // calculate the projectile direction
       // calculate rotation to turn projectile's forward direction to the shooting direction
       Quaternion rot = Quaternion.FromToRotation(Vector3.forward, projDir);
       // if projectile doesn't still exist, create it
       if (!projectile) projectile = Instantiate(projectilePrefab);
       // make sure the projectile is active:
       projectile.SetActiveRecursively(true);
       // bring it to the handPosition and set its rotation
       projectile.transform.position = handPosition;
       projectile.transform.rotation = rot;
       // make rigidbody forget the past by zeroing its velocities
       projectile.rigidbody.velocity = Vector3.zero;
       projectile.rigidbody.angularVelocity = Vector3.zero;       
       // then add force in the shooting direction
       projectile.rigidbody.AddForce(projDir * shootForce);
    }
}

The projectile script usually have code to destroy the projectile when it hits something - for instance:

void OnCollisionEnter(Collision col){
    // do the usual projectile stuff - check what was hit, apply damage etc.
    // and finally destroy the projectile:
    Destroy(gameObject);
}

But if you are recycling the projectile, you must change the code to deactivate it instead:

void OnCollisionEnter(Collision col){
    // do the projectile stuff...
    // and deactivate the projectile:
    gameObject.SetActiveRecursively(false);
}

Thanks for the quick response, I had a feeling my logic was off but didnt know howso. ha.

I tried your script but the projectile is still not firing at the angle that the debug line is showing. It comes out of the point of the line (hand position) but does not take into consideration the angle I think.
I have tried moving a lot of things around but its still not working as it should.
Just so Im clear on things, the script should be attached to an empty gameObject?
or should it be on the camera?
on those, my empty GO projectile is at 0, 2.5, 0 and camera at 0, 3.2, -8.5 if that helps.