- Home /
2D Shooting Delay with Animation
Hello, I am creating a 2D game.
When the fire button is pressed the player should shoot. Also the weapon should show a short animation, like charging and then it should fire the bullet. You don't need to hold the fire button for the "charging" animation.
Furthermore there should be a delay for shooting. I created a script which is working fine without the shooting animation. The script is inspired by this Tutorial.
When I add the shooting animation to my script and I press the fire button once, my bullet prefab will be created multiple times. I don't know why it's done multiple times, although I pressed the button once. Moreover I want to play the shooting animation once and then I want to create the bullet prefab. Whats the best way to only play an animation once? I tried to wait for the animation like it's described here. But it has no effect.
My Weapon script:
public class Weapon : MonoBehaviour
{
public Transform firePoint;
public GameObject bulletPrefab;
private Animator animator;
private bool isShooting;
private bool isFacingLeft;
[SerializeField] private float shootDelay = .5f;
private void Start()
{
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (Input.GetButton("Fire1"))
{
if (isShooting) return;
isShooting = true;
animator.Play("Shoot");
Shoot();
Invoke("ResetShoot", shootDelay);
}
}
void ResetShoot()
{
isShooting = false;
animator.Play("Idle");
}
void Shoot()
{
// shooting logic
GameObject bullet = Instantiate(bulletPrefab, firePoint.position,
firePoint.rotation);
bullet.GetComponent<Bullet>().StartShoot();
}
}
My Bullet script:
public class Bullet : MonoBehaviour
{
[SerializeField]
float speed;
[SerializeField]
int damage;
public void StartShoot()
{
GetComponent<Rigidbody2D>().velocity = transform.right * speed;
}
}
Answer by Xleg · Aug 16, 2020 at 10:11 AM
I solved it . The reason why my player fired 2 bullets was, I forgot that I added an animation event to my shoot animation. I draged the event to the animations end. The animation event called my Shoot() function.
This is how my Update() function looks now:
void Update() {
if (Input.GetButton("Fire1")) {
if (isShooting) return;
isShooting = true;
animator.Play("Shoot");
}
}
My Shoot() function:
void Shoot() {
GameObject bullet = Instantiate(bulletPrefab, firePoint.position,
firePoint.rotation);
bullet.GetComponent<Bullet>().StartShoot();
animator.Play("Idle");
Invoke("ResetShoot", shootDelay);
}
My ResetShot() function:
void ResetShoot() {
isShooting = false;
}
Answer by Razor1994 · Aug 11, 2020 at 09:33 PM
There are a few things. First of all, if you click on your animation in unity, is there any loop checkbox checked? It shouldn't be if you only want it to play once.
Another thing with the animation, the "animator.Play("Shoot");" is async, which means that the code will not wait for the animation to finish. The code is too fast when you are holding the mouse down, your animation will not have time to play correctly.
You want to have delay between the shots, correct? I would add delay the following way:
[SerializeField] private float shootDelay = .5f;
void Update()
{
shootDelay -= time.deltaTime;
if (Input.GetButton("Fire1"))
{
if (shootDelay <= 0)
{
animator.Play("Shoot");
Shoot();
// This will set the delay between shots to .5f, you should store this in a variable.
shootDelay = .5f;
}
}
}
I hope i correctly understood what you were trying to do. If not, just let me know and i'll improve this answer.
Thank's for your answer.
You're correct I activated the loop checkbox. The delay is working correct.
As addition: In line 5 time.deltaTime must be Time.deltaTime. But I don't get the expected behavior with this script. When I press the fire button my player should set from the idle animation to the shooting animation. Then the code should wait for the animation until it ends. And then it should create a new bullet prefab. In the end the player should be set into the idle animation again. The shoot delay should prevent the player from shooting again in the next X seconds. The shoot delay is not to wait for the end of the animation.
Currently your script only plays the shoot animation once. It doesn't switch back to the idle. And the first time I press the fire button, the player shoot two times.
Your answer
Follow this Question
Related Questions
delay between shots 1 Answer
2D Animation does not start 1 Answer
Shooting animation playing for longer than a second? 1 Answer
Animator idle minimal delay 0 Answers
Has Exit Time causes between trigger and transition. How can I stop this? 1 Answer