Hello Unity forums!
This is my first unity project that I’ve undertaken all on my own, and I’m extremely new to Unity, its systems, and C# as a whole. I’ve been researching things I’ve wanted to do and ways to do them, but I’ve found almost nothing helpful that fits what I want to do.
I’m trying to make a 2D dual-stick shooter using Unity 6 and its new Input System Package(which is incredibly complicated to me as a new developer + I hate it). I have movement sorted and working right now, but shooting is where my problem begins. I’ve been struggling with trying to figure out how to continuously spawn bullets after a delay while a key is held. This sounds simple enough to me, but I’ve spent around a week or two testing things and trying to get this to work.
Here’s my code for the player’s shooting:
using UnityEngine;
using UnityEngine.InputSystem;
using System.Collections;
public class PlayerShooting : MonoBehaviour
{
[SerializeField] private GameObject bulletPrefab;
[SerializeField] private bool buttonHeld; // for only shooting when button held
private Quaternion bulletRotation; // rotation bullet will face
private PlayerMovement movementScript; // for playerPos variable from PlayerMovement.cs
private bool shootBool; // to disable shooting for shot delay or otherwise
private float shootDelay = 0.5f; // delay in sec between bullets
void Awake()
{
movementScript = GetComponent<PlayerMovement>();
shootBool = true; // allows player to shoot on game start
}
void Update()
{
Shoot(bulletRotation); // tries to spawn bullet every frame, only works when buttonHeld true
}
public void OnFireUp(InputAction.CallbackContext context)
{
if (context.performed && !buttonHeld) // if only up arrow key pressed
{
bulletRotation = Quaternion.Euler(0, 0, 0); // bullet faces up
buttonHeld = true;
}
if (context.canceled) // buttonHeld false when key released
{
buttonHeld = false;
}
}
public void OnFireRight(InputAction.CallbackContext context)
{
if (context.performed && !buttonHeld) // if only right arrow key pressed
{
bulletRotation = Quaternion.Euler(0, 0, 270); // bullet faces right
buttonHeld = true;
}
if (context.canceled) // buttonHeld false when key released
{
buttonHeld = false;
}
}
public void OnFireDown(InputAction.CallbackContext context)
{
if (context.performed && !buttonHeld) // if only down arrow key pressed
{
bulletRotation = Quaternion.Euler(0, 0, 180); // bullet faces down
buttonHeld = true;
}
if (context.canceled) // buttonHeld false when key released
{
buttonHeld = false;
}
}
public void OnFireLeft(InputAction.CallbackContext context)
{
if (context.performed && !buttonHeld) // if only left arrow key pressed
{
bulletRotation = Quaternion.Euler(0, 0, 90); // bullet faces left
buttonHeld = true;
}
if (context.canceled) // buttonHeld false when key released
{
buttonHeld = false;
}
}
private void Shoot(Quaternion rotation)
{
if (shootBool && buttonHeld)
{
Instantiate(bulletPrefab, movementScript.playerPos.position, rotation); // spawns bullet with rotation
StartCoroutine(ShootDelay()); // delays next shot by shootDelay seconds
}
}
private IEnumerator ShootDelay() // for delaying shots
{
shootBool = false;
yield return new WaitForSeconds(shootDelay);
shootBool = true;
}
}
I have the Shoot() method in the Update() method and I’m only changing the variables that that method relies on in the action methods. The buttonHeld boolean is what the Shoot() method relies on, as well as the shootBool boolean, but that variable is managed within the ShootDelay() coroutine. The buttonHeld boolean is managed within the action methods(OnFireUp, Down, etc), where it is set to true when the action is performed, and set to false when the action is cancelled. The problem, though, is that this behavior only happens when firing up, and the first bullet spawns after the 0.5 second delay. Firing left, down, or right by pressing the arrow keys doesn’t set buttonHeld to false when releasing the key.
I tried explaining my problem and expectations clearly here, but if any information is needed to help me solve my problem, I will happily provide. My brain is a bit fried from trying to work on this even just to find the problems to report here. I’m trying to just get as much as I can down in order to explain what I need to but I just want to be done for now.
Thank you in advance.