- Home /
How to fire projectile in direction character is facing?
Hi all,
I have this script that successfully shoots projectiles by instantiating it and deleting it 3 seconds later to keep the game running smoothly.
However, the projectiles will only shoot in one direction (Z axis). If I turn left, the projectile will still be fired in the Z axis.
Script below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FireExtingControls : MonoBehaviour
{
// Script should be attached to spawn point of foam rather than foam itself!!
public GameObject foam;
public float speed = 10f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Mouse0))
{
GameObject instFoam = Instantiate(foam, transform.position, Quaternion.identity);
Rigidbody instFoamRB = instFoam.GetComponent<Rigidbody>();
instFoamRB.AddForce(Vector3.forward * speed);
Destroy(instFoam, 3f);
}
}
}
What I want is that the projectile will shoot in the direction the player is looking, be it left, right, up or down.
Thanks in advance :)
Answer by RetroGeek46 · Aug 19, 2019 at 06:55 AM
On line 25 instead of instFoamRB.AddForce(Vector3.forward * speed);
you should write instFoamRB.AddForce(gameObject.transform.forward * speed);
Vector3.forward is simply (0,0,1) whereas gameObject.transform.forward is the vector that you want.
Answer by dbchest · Aug 18, 2019 at 11:14 PM
Update:
attach this script to any game object that is capable of triggering projectiles:
using UnityEngine;
/// <summary>
/// The class definition for a projectile's trigger
/// </summary>
/// <remarks>
/// Attach this script as a component to any object capable of triggering projectiles
/// The spawn transform should represent the position where the projectile is to appear, i.e. gun barrel end
/// </remarks>
public class ProjectileTrigger : MonoBehaviour
{
/// <summary>
/// Public fields
/// </summary>
public GameObject m_Projectile; // this is a reference to your projectile prefab
public Transform m_SpawnTransform; // this is a reference to the transform where the prefab will spawn
/// <summary>
/// Message that is called once per frame
/// </summary>
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Instantiate(m_Projectile, m_SpawnTransform.position, m_SpawnTransform.rotation);
}
}
}
attach this script to any prefab that represents a projectile:
using UnityEngine;
/// <summary>
/// The class definition for a projectile
/// </summary>
[RequireComponent(typeof(Rigidbody))]
public class Projectile : MonoBehaviour
{
/// <summary>
/// Public fields
/// </summary>
public float m_Speed = 10f; // this is the projectile's speed
public float m_Lifespan = 3f; // this is the projectile's lifespan (in seconds)
/// <summary>
/// Private fields
/// </summary>
private Rigidbody m_Rigidbody;
/// <summary>
/// Message that is called when the script instance is being loaded
/// </summary>
void Awake()
{
m_Rigidbody = GetComponent<Rigidbody>();
}
/// <summary>
/// Message that is called before the first frame update
/// </summary>
void Start()
{
m_Rigidbody.AddForce(m_Rigidbody.transform.forward * m_Speed);
Destroy(gameObject, m_Lifespan);
}
}
I changed this in the code and it doesn't seem to be working. It continues to fire in the Z axis.
Should I attach my script to another object? I've tried attaching it to FPSController, FirstPersonCharacter and the object the projectile would be fired from, but it continues to shoot in the Z axis.
Not sure what else I could do?
Cheers, this works beautifully. One small problem is that it will stop instantiating new projectiles after the original one has been deleted (as done in line 34 of second script). Any workaround?
so retro geek pointed out what I happened to miss in the initial code and so he gets an up-vote from me! his response should get you up and running if you'd like to go back to how you were doing things initially! that being said, the code I wrote for you is slightly more robust and has the added advantage of unlimited reusability with any number of objects you might design moving forward with your project and so I still recommend going with something like that in the end.
I'm not experiencing the same problem that you are; I wrote my code in a new project and it works without any issue for me, but it is worth noting that the input detection I used is designed to detect trigger inputs, in that you have to repeatedly press the space bar to instantiate new projectiles. by default, my code will not repeatedly instantiate projectiles if you are utilizing a fire rate system and holding down the trigger button, so I have to ask if you are holding down the trigger button or does repeatedly pressing the the trigger key not work?
I tried using your code with the two scripts, but my projectile doesn't move. It just stays where it was spawned.
Thanks so much for this. This set me off on the right track. After fiddling with it... This worked for me:
public class BulletMovement : MonoBehaviour { public float bulletSpeed = 10f; public float bulletLifeSpan = 3f;
private Rigidbody rbBullet;
// Start is called before the first frame update
void Start()
{
rbBullet = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
**rbBullet.AddForce(rbBullet.transform.right * bulletSpeed);**
Destroy(gameObject, bulletLifeSpan);
}
}
For some reason, calling ".right" was the only thing that would allow the bullets to emerge in the right direction while rotating in a full circle. Does anyone know why that is? I'm glad it worked, but I'm curious now. Thanks again!
Answer by AlharbiSunds · Aug 03, 2020 at 01:08 PM
m_Rigidbody.AddForce(transform.forward * m_Speed);
Working by only change this line.
Thank you