Firing a projectile in 2D

I am creating a game where I am firing a projectile to move in a parabolic motion in 2D. My player can move left and right and with a mouseclick, fire a grapple (i used a capsule for now). However, it is moving in 3 dimensions. How can I make the grapple only move in 2 (x-axis and y-axis)?

here is my code for the player:

var playerSpeed : int;

var playerDist : float;

var playerHealth: int;

var mySlider : float = 1.0;

var sliderMaxValue : int = 90;

var timepart : float;

var grapple : Rigidbody;

var speed = 150;

function Update () {

amtToMove = (playerSpeed * Input.GetAxis("Horizontal")) * Time.deltaTime;

transform.Translate(Vector3.right * amtToMove);

if(transform.position.x < -6.17){
transform.position.x = -6.17;
}

if(transform.position.x > 6.17){
transform.position.x = 6.17;
}

if(transform.position.x < 0){							//Calculates the distance between the player and the castle
playerDist = 6.17 + Mathf.Abs(transform.position.x);
}

if(transform.position.x == 0){
playerDist = 6.17;
}

if(transform.position.x > 0){
playerDist = 6.17 - transform.position.x;
}

if(Input.GetMouseButtonDown(0)){
var instantiatedProjectile : Rigidbody = Instantiate (grapple, transform.position, transform.rotation);

instantiatedProjectile.velocity = transform.TransformDirection(Vector3 (0, 0, speed));
}
}

function OnGUI () {
	mySlider = LabelSlider (Rect (10, 100, 100, 20), mySlider, 90.0, "Angle:" + mySlider);
	GUI.Label(Rect(10,150,200,50), "Player Distance:" + playerDist);
	GUI.Label(Rect(10,130,200,50), "Timepart:" + timepart);

}

function LabelSlider (screenRect : Rect, sliderValue : int, sliderMaxValue : int, labelText : String) : float {
	GUI.Label (screenRect, labelText);
	screenRect.x += screenRect.width; // <- Push the Slider to the end of the Label
	sliderValue = GUI.HorizontalSlider (screenRect, sliderValue, 0.0, sliderMaxValue);
	return sliderValue;
}

function timepartChanger(){
timepart = (playerDist)/(playerSpeed + 60);
}

and here is my code for the grapple

var grappleSpeed : int;

function Update () {

amtToMove = Time.deltaTime;

transform.Translate(Vector3.up + Vector3.right * grappleSpeed * amtToMove); //Moves bullet up 
}

This line is probably one causing your problem:

if(Input.GetMouseButtonDown(0)){
     var instantiatedProjectile : Rigidbody = Instantiate (grapple, transform.position, transform.rotation);    
     instantiatedProjectile.velocity = transform.TransformDirection(Vector3 (0, 0, speed));
}

There are still a number of issues that you could be having:

  1. Your grappling hook is colliding with the player and that is knocking it off course.
  2. Your player isn’t facing directly on the x axis causing the projectile to shoot off at a slight angle.

So what can you do to solve your problem.

  1. Add an ignore collision call that will prevent the object from hitting the character. Note that this depends heavily on the type of collider your character uses.

  2. Create a custom velocity. locked on the xy plane. I’m going to show you the easiest solution.

     if ( Input.GetMouseButtonDown(0) ) {
         var instantiatedProjectile : Rigidbody = Instantiate (grapple, transform.position, transform.rotation);    
         Physics.IgnoreCollison(instantiatedProjectile.collider, GetComponent.<CharacterController>() );
    
            var velocity = transform.forward;
            velocity.z = 0;
            velocity *= speed;
            instantiatedProjectile.velocity = velocity;
    }
    

now I am getting a “MissingComponentException: There is no ‘CharacterController’ attached to the player object, but a script is trying to access it.”