So I thought I’d create an animation event for the firing so that I could choose when to instantiate the bullet (in my case, I wanted to instantiate the bullet at the last frame of the firing animation). So I created the event, and had the function called doneFiring() as you can see in my animation events window:
And of course, I also made sure to include this in my PlayerMovement.cs script, which is attached to the Isekai Protag game object (which is the player and of course, this is also the one that has the animator for the player as one of its components as well as the PlayerMovement.cs script)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMovement : MonoBehaviour
{
Vector2 moveInput;
Rigidbody2D myRigidbody;
Animator myAnimator;
CapsuleCollider2D myBodyCollider;
BoxCollider2D myFeetCollider;
SpriteRenderer playerColor;
[SerializeField] ParticleSystem bloodSplatter;
[SerializeField] AudioClip deathState;
Color color;
float playerGravityAtStart;
[SerializeField] float runSpeed = 10f;
[SerializeField] float jumpSpeed = 5f;
[SerializeField] float climbSpeed = 5f;
[SerializeField] float climbAnimationSpeed = 1f;
[SerializeField] GameObject arrow;
[SerializeField] Transform bow;
bool isAlive = true;
void Start()
{
bloodSplatter = GetComponent<ParticleSystem>();
playerColor = GetComponent<SpriteRenderer>();
myRigidbody = GetComponent<Rigidbody2D>();
myAnimator = GetComponent<Animator>();
myBodyCollider = GetComponent<CapsuleCollider2D>();
myFeetCollider = GetComponent<BoxCollider2D>();
myAnimator.SetBool("isRunning",false);
playerGravityAtStart = myRigidbody.gravityScale;
color[0] = 0.64f;
color[1] = 0.2f;
color[2] = 0.2f;
color[3] = 1;
}
void Update()
{
if(!isAlive)
{
return;
}
Run();
FlipSprite();
ClimbLadder();
Die();
//Jump();
}
void OnMove(InputValue value)
{
if(!isAlive)
{
return;
}
moveInput = value.Get<Vector2>();
}
void OnFire(InputValue value)
{
if(!isAlive)
{
return;
}
if(value.isPressed)
{
myAnimator.SetBool("isFiring",true);
//Instantiate(arrow, bow.position, transform.rotation);
}
}
public void doneFiring()
{
Instantiate(arrow, bow.position, transform.rotation);
myAnimator.SetBool("isFiring",false);
}
void Jump()
{
bool playerHasVSpeed = Mathf.Abs(myRigidbody.velocity.y) > Mathf.Epsilon;
if(!myBodyCollider.IsTouchingLayers(LayerMask.GetMask("Ground")) && moveInput.y > 0)
{
myAnimator.SetBool("isJumping",false);
}
else
{
myAnimator.SetBool("isJumping",playerHasVSpeed);
}
}
void OnJump(InputValue value)
{
if(!isAlive)
{
return;
}
if (!myFeetCollider.IsTouchingLayers(LayerMask.GetMask("Ground")))
{
return;
}
if(value.isPressed)
{
//myAnimator.SetBool("isJumping",true);
myRigidbody.velocity += new Vector2 (0f, jumpSpeed);
}
}
void Run()
{
Vector2 playerVelocity = new Vector2 (moveInput.x * runSpeed, myRigidbody.velocity.y);
myRigidbody.velocity = playerVelocity;
bool playerHasVSpeed = Mathf.Abs(myRigidbody.velocity.y) > Mathf.Epsilon;
bool playerHasHorizontalSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon;
if(myAnimator.GetBool("isJumping"))
{
myAnimator.SetBool("isRunning",false);
}
else
{
myAnimator.SetBool("isRunning",playerHasHorizontalSpeed);
}
}
void FlipSprite()
{
bool playerHasHorizontalSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon;
if (playerHasHorizontalSpeed)
{
transform.localScale = new Vector2 (Mathf.Sign(myRigidbody.velocity.x),1f);
}
}
void ClimbLadder()
{
bool playerHasVSpeed = Mathf.Abs(myRigidbody.velocity.y) > Mathf.Epsilon;
if(myFeetCollider.IsTouchingLayers(LayerMask.GetMask("Climbing")))
{
Vector2 climbVelocity = new Vector2 (myRigidbody.velocity.x , moveInput.y * climbSpeed);
myRigidbody.velocity = climbVelocity;
myRigidbody.gravityScale = 0;
if(playerHasVSpeed)
{
myAnimator.SetBool("isClimbing",playerHasVSpeed);
myAnimator.SetFloat("climbingSpeed",climbAnimationSpeed);
}
if(!playerHasVSpeed)
{
myAnimator.SetFloat("climbingSpeed",0);
}
}
else
{
myRigidbody.gravityScale = playerGravityAtStart;
myAnimator.SetBool("isClimbing",false);
}
}
void Die()
{
if (myBodyCollider.IsTouchingLayers(LayerMask.GetMask("Enemies", "Hazards")))
{
isAlive = false;
myRigidbody.velocity = new Vector2 (1f, 15f);
myFeetCollider.sharedMaterial.friction = 0.5f;
myBodyCollider.sharedMaterial.friction = 0.5f;
bloodSplatter.Play();
GetComponent<AudioSource>().PlayOneShot(deathState);
playerColor.color = color;
myAnimator.SetTrigger("isDead");
}
}
}
And when I try to run the animation event, I get a ‘Isekai Protag’ AnimationEvent ‘doneFiring()’ on animation ‘fire’ has no receiver! Are you missing a component? error.
After looking up this issue at many places, it seems that the animation event can only look up events on the script if the script is attached to the same game object as the animation. But in this case, since the player script and the animator are both components of the ‘Isekai Protag’ game object, why is this error still there?