Arrow projectile WILL NOT come out right.


Here is where the arrow launches from.


Here is the prefab for the arrow that is shot.


Here is the image of how the arrows come out. Ignore how close together they are. I can change that at any moment.

This is the code I used for my projectile launcher aka my crossbow. I followed a tutorial on youtube and have very very little experience with coding, but have a game do for my class next Tuesday. For some reason the projectiles that come out of my crossbow are my arrow, but no matter what I do to the prefab, the arrow comes out vertical instead of the horizontal rotation you’d expect. The arrows also come out quite higher than they should. I am not sure what is causing this. If it is something to do with the coding please try to slightly less jargin as I am very new to all of this.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ProjectileGunTutorial : MonoBehaviour
{
public GameObject bullet;

public float shootForce, upwardForce;

public float timeBetweenShooting, spread, reloadTime, timeBetweenShots;
public int magazineSize, bulletsPerTap;
public bool allowButtonHold;

int bulletsLeft, bulletsShot;

bool shooting, readyToShoot, reloading;

public Camera fpsCam;
public Transform attackPoint;

public bool allowInvoke = true;

private void Awake()
{
bulletsLeft = magazineSize;
readyToShoot = true;

}

private void Update()
{
MyInput();
}

private void MyInput()
{
if (allowButtonHold) shooting = Input.GetKey(KeyCode.Mouse0);
else shooting = Input.GetKeyDown(KeyCode.Mouse0);

if (readyToShoot && shooting && !reloading && bulletsLeft > 0)
{
bulletsShot = 0;
Shoot();
}

if (Input.GetKeyDown(KeyCode.R) && bulletsLeft < magazineSize && !reloading) Reload();

if (readyToShoot && shooting && !reloading && bulletsLeft <= 0) Reload();
}

private void Shoot()
{
readyToShoot = false;

Ray ray = fpsCam.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0));
RaycastHit hit;

Vector3 targetPoint;
if (Physics.Raycast(ray, out hit))
targetPoint = hit.point;
else
targetPoint = ray.GetPoint(75);

Vector3 directionWithoutSpread = targetPoint - attackPoint.position;

float x = Random.Range(-spread, spread);
float y = Random.Range(-spread, spread);

Vector3 directionWithSpread = directionWithoutSpread + new Vector3(x, y, 0);

GameObject currentBullet = Instantiate(bullet, attackPoint.position, Quaternion.identity);

currentBullet.transform.forward = directionWithSpread.normalized;

currentBullet.GetComponent().AddForce(directionWithSpread.normalized * shootForce, ForceMode.Impulse);
currentBullet.GetComponent().AddForce(fpsCam.transform.up * upwardForce, ForceMode.Impulse);

bulletsLeft–;
bulletsShot++;

if (allowInvoke)
{
Invoke(“ResetShot”, timeBetweenShooting);
allowInvoke = false;
}
}

private void ResetShot()
{
readyToShoot = true;
allowInvoke = true;
}

private void Reload()
{
reloading = true;
Invoke(“ReloadFinished”, reloadTime);
}

private void ReloadFinished()
{
bulletsLeft = magazineSize;
reloading = false;
}
}

The best way is to just change the initial rotation by 90 degrees when you instantiate the gameobject

but since you’re a beginner the easier way is in your editor with the ShootingArrow mesh, find whats actually drawing the arrow mesh, its either Circle or Cube. it will have a MeshRenderer component there
make position 0,0,0 and experiment with the rotation eg 90,0,0, scale = 1,1,1

There’s a lot of possibilities:

  1. Verify the pivot point position of the arrow (bullet) is correct. It should be at the center of the arrow, or maybe one of the ends.

  2. Verify the local blue axis (forward) of the arrow actually aligns with the arrow.

  3. Verify the attackPoint position is correct. It should always close to the end of the bow.

  4. Make sure fpsCam is the actual camera being rendered.

  5. Verify the targetPoint is correct:
    You can use Debug.DrawLine to draw a line starting from attackPoint, going to targetPoint

Debug.DrawLine (attackPoint.position, targetPoint, Color.blue, 1f);
  1. Verify the directionWithSpread is correct:
    You can use Debug.DrawRay to draw a line starting from attackPoint, going in the desired direction of the arrow
Debug.DrawRay (attackPoint.position, directionWithSpread.normalized * 200.0f, Color.red, 1f);
1 Like

Extra parenting to sort out troublesome assets:

ALSO: Check your pivot/center and global/local buttons in the Scene window in the editor.

Shortcut keys are Z and X to toggle those.