Firing not working

Hello I am having trouble with the firing mechanic in the game. I have looked at a similar solution to my issue in this forum but it didn’t resolve the issue for me.

I have made sure to place the prefabs in the inspector and have rigidbodies on the projectile.

When I enter play mode I press the button to fire the laser in my case it is the space bar or LMB both of which don’t work. I have also placed a Debug.Log on the firing code which also doesn’t show in the console when used.

Here is the code I am using. If you have any suggestions as to why it’s not working please let me know.

Thank you.

PLAYER.CS

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

public class Player : MonoBehaviour
{
[SerializeField] float moveSpeed = 5f;
[SerializeField] float paddingLeft = 5f;
[SerializeField] float paddingRight = 5f;
[SerializeField] float paddingTop = 5f;
[SerializeField] float paddingBottom = 5f;

Vector2 minBounds;
Vector2 maxBounds;

Vector2 rawInput;

Shooter shooter;

void Awake()
{
    shooter = GetComponent<Shooter>();
}

void Start()
{
    InitBounds();
}


void Update()
{
    Move();
}

void InitBounds()
{
    Camera mainCamera = Camera.main;
    minBounds = mainCamera.ViewportToWorldPoint(new Vector2(0, 0));
    maxBounds = mainCamera.ViewportToWorldPoint(new Vector2(1, 1));
}

void Move()
{
    Vector2 delta = rawInput * moveSpeed * Time.deltaTime;
    Vector2 newPos = new Vector2();
    newPos.x = Mathf.Clamp(transform.position.x + delta.x, minBounds.x + paddingLeft, maxBounds.x - paddingRight);
    newPos.y = Mathf.Clamp(transform.position.y + delta.y, minBounds.y + paddingBottom, maxBounds.y - paddingTop);
    transform.position = newPos;
}

void OnMove(InputValue value)
{
    rawInput = value.Get<Vector2>();
}

public void OnShoot(InputValue value)
{
    if(shooter != null)
    {
        Debug.Log("Projectile fired.");
        shooter.isFiring = value.isPressed;
    }
}

}

SHOOTER.CS

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

public class Shooter : MonoBehaviour
{
[SerializeField] GameObject projectilePrefab;
[SerializeField] float projectileSpeed = 15f;
[SerializeField] float projectileLifeTime = 5f;
[SerializeField] float firingRate = 0.3f;

public bool isFiring;

Coroutine firingCoroutine;

void Start()
{

}
void Update()
{
    Fire();
}

void Fire()
{
    if (isFiring && firingCoroutine == null)
    {
        firingCoroutine = StartCoroutine(FireCountinuously());
    }
    else if(!isFiring && firingCoroutine != null)
    {
        StopCoroutine(firingCoroutine);
        firingCoroutine = null;
    }
}

IEnumerator FireCountinuously()
{
    while (true)
    {
        GameObject instance = Instantiate(projectilePrefab, transform.position, Quaternion.identity);
        Rigidbody2D rb = instance.GetComponent<Rigidbody2D>();
        if(rb != null)
        {
            rb.velocity = transform.up * projectileSpeed;
        }
        Destroy(instance, projectileLifeTime);
        yield return new  WaitForSeconds(firingRate);
    }
}

}

My bet would be your input isn’t set up correctly.

Yup, I was going to say that.

@aJadedGamer Perhaps move the Debug.Log out of the if statement. If the input isn’t working, it will still not show up. If it does print in the console, then it means you have no shooter on the player

public void OnShoot(InputValue value)
{
    Debug.Log("Projectile fired.");
    if(shooter != null)
    {
        shooter.isFiring = value.isPressed;
    }
}

Thank you for your suggestions I had a look at the player prefab and ensured the scripts where attached and that the input was also set up correctly, however it still doesn’t shoot when I press the button.

I tried moving the Debug.Log above the if statement and it is definitely not logging when the input is called. So that would seem to be where the issue is stemming from but I am unable to see what the issue is.

I have also made sure that it isn’t a layering issue in both sorting layer and collisions.

I have also noticed when I tick the ‘Is Firing’ box in the inspector prior to running the game it functions correctly but in an automatic way that can’t be stopped with inputs.

Here is the code as it is now. I only moved the Debug.Log however.

PLAYER.CS

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

public class Player : MonoBehaviour
{
[SerializeField] float moveSpeed = 5f;
[SerializeField] float paddingLeft = 5f;
[SerializeField] float paddingRight = 5f;
[SerializeField] float paddingTop = 5f;
[SerializeField] float paddingBottom = 5f;

Vector2 minBounds;
Vector2 maxBounds;

Vector2 rawInput;

Shooter shooter;

void Awake()
{
    shooter = GetComponent<Shooter>();
}

void Start()
{
    InitBounds();
}


void Update()
{
    Move();
}

void InitBounds()
{
    Camera mainCamera = Camera.main;
    minBounds = mainCamera.ViewportToWorldPoint(new Vector2(0, 0));
    maxBounds = mainCamera.ViewportToWorldPoint(new Vector2(1, 1));
}

void Move()
{
    Vector2 delta = rawInput * moveSpeed * Time.deltaTime;
    Vector2 newPos = new Vector2();
    newPos.x = Mathf.Clamp(transform.position.x + delta.x, minBounds.x + paddingLeft, maxBounds.x - paddingRight);
    newPos.y = Mathf.Clamp(transform.position.y + delta.y, minBounds.y + paddingBottom, maxBounds.y - paddingTop);
    transform.position = newPos;
}

void OnMove(InputValue value)
{
    rawInput = value.Get<Vector2>();
}

public void OnShoot(InputValue value)
{
    Debug.Log("Projectile fired.");
    if (shooter != null)
    {
        shooter.isFiring = value.isPressed;
    }
}

}

SHOOTER.CS

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

public class Shooter : MonoBehaviour
{
[SerializeField] GameObject projectilePrefab;
[SerializeField] float projectileSpeed = 15f;
[SerializeField] float projectileLifeTime = 5f;
[SerializeField] float firingRate = 0.3f;

public bool isFiring;

Coroutine firingCoroutine;

void Start()
{

}
void Update()
{
    Fire();
}

void Fire()
{
    if (isFiring && firingCoroutine == null)
    {
        firingCoroutine = StartCoroutine(FireCountinuously());
    }
    else if(!isFiring && firingCoroutine != null)
    {
        StopCoroutine(firingCoroutine);
        firingCoroutine = null;
    }
}

IEnumerator FireCountinuously()
{
    while (true)
    {
        GameObject instance = Instantiate(projectilePrefab, transform.position, Quaternion.identity);
        Rigidbody2D rb = instance.GetComponent<Rigidbody2D>();
        if(rb != null)
        {
            rb.velocity = transform.up * projectileSpeed;
        }
        Destroy(instance, projectileLifeTime);
        yield return new  WaitForSeconds(firingRate);
    }
}

}

If the debug isn’t firing off…
Input isn’t set up correctly.
It isn’t calling OnShoot

1 Like

I found the solution to my problem I had incorrectly named one of my function as OnShoot() I renamed it to OnFire() and now it works.

I’m still not 100% sure why this solved the issue for me. But it is working correctly now.

Thank you to everyone who helped me.

1 Like

That worked because the OnFire() method is called by the New Input System. You name the methods in that menu, since OnShoot doesn’t exist (because you didn’t write that) in the Input System it wasn’t called at all, that’s why the debug log never printed in the console.

Try rewatching lectures 113 ‘Unity Input System’ to see how the Input is setup, and lecture 122 ‘Player Shooting’ where Gary explains right at the start why you need to write OnFire() for things to work correctly.

2 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms