Grenade Launcher

Hello people,

Somewhere I am doing a mistake on my grenade launcher , and my brain is not responding me to understand where.

Issue: When we activate grenade launcher, it throws grenade to different location.

Explanation: We loot grenades from the map in order to use grenade launcher. if we have grenade in the slot, then we can launch. Player needs to swap the gun to grenade launcher by pressing either G or 5, and then left click on the mouse should instantiate the grenade. We are able to count slot, and we are able to instantiate the grenade, however it does not throwing grenade to the direction we are aiming to.

Source codes:
GrenadeThrower ( Attached to the gun ):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class GrenadeThrower : MonoBehaviour
{
    [SerializeField] Camera FPCamera;
    [SerializeField] Ammo ammoSlot;
    [SerializeField] AmmoType ammoType;
    [SerializeField] TextMeshProUGUI grenadeText;  
    public GameObject grenpref;  //yes
    [SerializeField] float reloadTime = 2f; //yes
    public Transform grenBarrel; //yes
    private float lastFireTime;
    public float throwforce = 400f;  

    public void DisplayGrenade()
    {
        int currentGrenade = ammoSlot.GetCurrentAmmo(ammoType);
        grenadeText.text = currentGrenade.ToString();
    }
    // Update is called once per frame
    public void Update()
    {      
        DisplayGrenade();      

        if (Input.GetMouseButtonDown(0) && Time.time > lastFireTime + reloadTime)
        {
            if (ammoSlot.GetCurrentAmmo(AmmoType.HPGrenade) > 0)
            {
               GameObject gren = Instantiate(grenpref, grenBarrel.position, transform.rotation);
                //GameObject go = Instantiate(grenpref, grenBarrel.position, Quaternion.LookRotation(grenBarrel.localScale));
                    Rigidbody rb = gren.GetComponent<Rigidbody>();
                    rb.AddForce(transform.position * throwforce); //transform.position.normalized
                Debug.Log(rb.transform.position + " RB Position");
                // Physics.IgnoreCollision(GetComponent<Collider>(), go.GetComponent<Collider>());
                lastFireTime = Time.time;
                FindObjectOfType<Ammo>().ReduceCurrentAmmo(AmmoType.HPGrenade);       
              
            }

        }
    }
    //void ThrowGren()
    //{
    //    GameObject gren = Instantiate(grenpref, transform.localScale, transform.rotation);
    //    Rigidbody rb = gren.GetComponent<Rigidbody>();
    //    rb.AddForce(transform.position * throwforce, ForceMode.VelocityChange);
    //}         
    //    yield return new WaitForSeconds(reloadTime);       
    }

Grenade script( referncing to grenpref object on grenadethrower script):

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


public class Grenade : MonoBehaviour
{

    public float radius = 35f;
    public float delayt = 3f;
    float cntdwn;
    bool hasExploded = false;
    public GameObject explosionEff;

    public float force = 700f;




    [SerializeField] float damage = 100f;

    void Start()
    {
        cntdwn = delayt;


    }


    void Update()
    {
        cntdwn -= Time.deltaTime; // each second cntdwn will decrease 1
        if (cntdwn <= 0f && hasExploded == false)
        {
            Explode();
            hasExploded = true;
        }
    }

    void Explode()
    {

        //EXPLOSION
        Instantiate(explosionEff, transform.position, transform.rotation);
        Collider[] collidersToDestroy = Physics.OverlapSphere(transform.position, radius);

        foreach (Collider nearbyObject in collidersToDestroy)
        {
            Rigidbody rb = nearbyObject.GetComponent<Rigidbody>();
            if (rb != null)
            {
                rb.AddExplosionForce(force, transform.position, radius);
            }
        }
        Destroy(gameObject);
        ////DEALING DAMAGE

        //DEALING DAMAGE TO ZOMBIES
        RaycastHit hit;
        Collider[] objectsInRange = Physics.OverlapSphere(transform.position, radius);
        foreach (Collider col in objectsInRange)
        {
            EnemyHealth enemy = col.GetComponent<EnemyHealth>();
            if (enemy != null)
            {
                enemy.TakeDamage(damage);

                if (Physics.Raycast(transform.position, transform.forward, out hit, radius))
                {
                    EnemyHealth target = hit.transform.GetComponent<EnemyHealth>();

                    if (target == null) return;
                    target.TakeDamage(damage);
                }
                else
                {
                    return;
                }

            }
            //DEALING DAMAGE TO PLAYER
            RaycastHit playerhit;
            Collider[] playerInRange = Physics.OverlapSphere(transform.position, radius);
            foreach (Collider plyr in playerInRange)
            {
                PlayerHealth player = plyr.GetComponent<PlayerHealth>();
                if (player != null)
                {
                    player.TakeDamage(damage);

                    if (Physics.Raycast(transform.position, transform.forward, out playerhit, radius))
                    {
                        PlayerHealth targetMe = playerhit.transform.GetComponent<PlayerHealth>();

                        if (targetMe == null) return;
                        targetMe.TakeDamage(damage);
                    }
                    else
                    {
                        return;
                    }

                }

            }


        }
    }
}

Is there anyone who can help me here please? Thanks in advance

I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run?
  • what are the values of the variables involved? Are they initialized?

Knowing this information will help you reason about the behavior you are seeing.

For instance, I see that your ThrowGren() function is commented out completely.

1 Like

Yes, I did commented out because I have tried to have both scripts in one previously. Then I have commented out because i will not be using it anymore in this script, however i still keep there as it helps me to understand what I’ve done and where I am with my code. You will see //yes and ////GameObject go as well as GameObject gren. It helps me to remember why i changed the code.

in terms of debug, I dont see a way how i can debug this issue. Everything is working as it should except the aim.

Second script(grenade) has absolutely no issue whatsoever, i added because i thought giving more information would be useful to navigate in to solution.

Do you see any issue on:

  if (Input.GetMouseButtonDown(0) && Time.time > lastFireTime + reloadTime)
        {
            if (ammoSlot.GetCurrentAmmo(AmmoType.HPGrenade) > 0)
            {
               GameObject gren = Instantiate(grenpref, grenBarrel.position, transform.rotation);
                //GameObject go = Instantiate(grenpref, grenBarrel.position, Quaternion.LookRotation(grenBarrel.localScale));
                    Rigidbody rb = gren.GetComponent<Rigidbody>();
                    rb.AddForce(transform.position * throwforce); //transform.position.normalized
                Debug.Log(rb.transform.position + " RB Position");
                // Physics.IgnoreCollision(GetComponent<Collider>(), go.GetComponent<Collider>());
                lastFireTime = Time.time;
                FindObjectOfType<Ammo>().ReduceCurrentAmmo(AmmoType.HPGrenade);

this is where I instantiate grenade prefab and throw it through grenbarrel gameobject. As you have said I’ve already done debug in here, but it didn’t help me much to understand the reason of cause.

any recommendations please?

Line 8 above… you are adding a force according to position. That doesn’t make sense.

Don’t you want to calculate the difference between the player’s position and the target position?

Or else use transform.forward (plus obviously some transform.up to help it arc…) for the direction you’re facing.

I have gameobject called grenbarrel on players body, i located this object just next to the launcher. So my idea is grenade launcher should throw the grenade from grenbarrel to whereever we are aiming to. Since it has rigidbody, i used addforce to get some benefit from gravity.

Am i thinking it wrong way, should i bring different approach of coding to my grenade launcher script? would you suggest to change transform.position to transform.forward on line 8?

You’re welcome to look at how I launch my grenades in my MakeGeo project. Full source and project here:

MakeGeo is presently hosted at these locations:

https://bitbucket.org/kurtdekker/makegeo

https://github.com/kurtdekker/makegeo

Look for the TerrainDamager scene: run it, press pause and go looking for the other scripts, I forget what all they are but there’s only a few.

Thanks, I will have a look on your approach tomorrow to see whether I can change anything on my code then