Forum begins after the advertisement:
[Part 3] NullReferenceException error on DestroyAfterAnimation
Home › Forums › Video Game Tutorial Series › Creating a Metroidvania in Unity › [Part 3] NullReferenceException error on DestroyAfterAnimation
- This topic has 0 replies, 2 voices, and was last updated 5 days, 4 hours ago by
Ser Apustaja.
-
AuthorPosts
-
November 19, 2025 at 6:17 pm #19053::
After adding DestroyAfterAnimation script
using System.Collections; using System.Collections.Generic; using UnityEngine; public class DestroyAfterAnimation : MonoBehaviour { // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { Destroy(gameObject, GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).length); } }it is showing a nullreferenceexception:object reference not set to an instance of an object i didn’t make the dust animation i directly make the slash animation. slash animation is working but after adding destroyafteranimation script it is showing nullreferenceexception. if anyone faces the same error please help me
and this is my player controller script
using System.Collections; using System.Collections.Generic; public class playercontroller : MonoBehaviour { [Header("Horizontal Movement Settings")] [SerializeField] private float walkspeed = 1; [Space(5)] [Header("Vertical Movement Settings")] [SerializeField] private float jumpForce = 45; private int jumpBufferCounter = 0; [SerializeField] private int jumpBufferFrames; private float coyoteTimeCounter = 0; [SerializeField] private float coyoteTime; private int airJumpCounter = 0; [SerializeField] private int maxAirJumps; [Space(5)] [Header("Ground Check Settings")] [SerializeField] private Transform groundCheckPoint; [SerializeField] private float groundCheckY = 0.2f; [SerializeField] private float groundCheckX = 0.5f; [SerializeField] private LayerMask WhatIsGround; [Space(5)] [Header("Dash Settings")] [SerializeField] private float dashSpeed; [SerializeField] private float dashTime; [SerializeField] private float dashCooldown; [Space(5)] [Header("Attacking")] bool attack = false; float timeBetweenAttack, timeSinceAttack; [SerializeField] Transform SideAttackTransform, UpAttackTransform, DownAttackTransform; [SerializeField] Vector2 SideAttackArea, UpAttackArea, DownAttackArea; [SerializeField] LayerMask attackableLayer; [SerializeField] float damage; [SerializeField] GameObject slashEffect; private Rigidbody2D rb; PlayerStateList pState; private float xAxis, yAxis; private float gravity; Animator anim; private bool canDash; private bool dashed; public static playercontroller Instance; private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); } else { Instance = this; } } // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { pState = GetComponent<PlayerStateList>(); rb = GetComponent<Rigidbody2D>(); anim = GetComponent<Animator>(); gravity = rb.gravityScale; canDash = true; } private void OnDrawGizmos() { Gizmos.color = Color.red; Gizmos.DrawWireCube(SideAttackTransform.position, SideAttackArea); Gizmos.DrawWireCube(UpAttackTransform.position, UpAttackArea); Gizmos.DrawWireCube(DownAttackTransform.position, DownAttackArea); } // Update is called once per frame void Update() { Getinputs(); UpdateJumpVariables(); if (pState.dashing) return; Flip(); Move(); Jump(); StartDash(); Attack(); } void Getinputs() { xAxis = Input.GetAxisRaw("Horizontal"); yAxis = Input.GetAxisRaw("Vertical"); attack = Input.GetMouseButtonDown(0); } void Flip() { if(xAxis < 0) { transform.localScale = new Vector2(-1, transform.localScale.y); } else if(xAxis > 0) { transform.localScale = new Vector2(1, transform.localScale.y); } } private void Move() { rb.linearVelocity = new Vector2(walkspeed * xAxis, rb.linearVelocity.y); } void StartDash() { if (Input.GetButtonDown("Dash") && canDash && !dashed) { StartCoroutine(Dash()); dashed = true; } if (Grounded()) { dashed = false; } } IEnumerator Dash() { canDash = false; pState.dashing = true; anim.SetTrigger("Dashing"); rb.gravityScale = 0; rb.linearVelocity = new Vector2(transform.localScale.x * dashSpeed, 0); yield return new WaitForSeconds(dashTime); rb.gravityScale = gravity; pState.dashing = false; yield return new WaitForSeconds(dashCooldown); canDash = true; } void Attack() { timeSinceAttack += Time.deltaTime; if (attack && timeSinceAttack >= timeBetweenAttack) { timeSinceAttack = 0; anim.SetTrigger("Attacking"); if (yAxis == 0 || yAxis < 0 && Grounded()) { Hit(SideAttackTransform, SideAttackArea); Instantiate(slashEffect, SideAttackTransform); } else if (yAxis > 0) { Hit(UpAttackTransform, UpAttackArea); SlashEffectAtAngle(slashEffect, 90, UpAttackTransform); } else if(yAxis < 0 && !Grounded()) { Hit(DownAttackTransform, DownAttackArea); SlashEffectAtAngle(slashEffect, -90, DownAttackTransform); } } } private void Hit(Transform _attackTransform, Vector2 _attackArea) { Collider2D[] objectsToHit = Physics2D.OverlapBoxAll(_attackTransform.position, _attackArea, 0, attackableLayer); if(objectsToHit.Length > 0) { Debug.Log("Hit"); } for(int i = 0; i < objectsToHit.Length; i++) { if(objectsToHit[i].GetComponent<Enemy>() != null) { objectsToHit[i].GetComponent<Enemy>().EnemyHit(damage); } } } void SlashEffectAtAngle(GameObject _slashEffect, int _effectAngle, Transform _attackTransform) { _slashEffect = Instantiate(_slashEffect, _attackTransform); _slashEffect.transform.eulerAngles = new Vector3(0, 0, _effectAngle); _slashEffect.transform.localScale = new Vector2(transform.localScale.x, transform.localScale.y); } public bool Grounded() { if (Physics2D.Raycast(groundCheckPoint.position, Vector2.down, groundCheckY, WhatIsGround) || Physics2D.Raycast(groundCheckPoint.position + new Vector3(groundCheckX, 0, 0), Vector2.down, groundCheckY, WhatIsGround) || Physics2D.Raycast(groundCheckPoint.position + new Vector3(-groundCheckX, 0, 0), Vector2.down, groundCheckY, WhatIsGround)) { return true; } else { return false; } } void Jump() { if (Input.GetButtonUp("Jump") && rb.linearVelocity.y > 0) { rb.linearVelocity = new Vector2(rb.linearVelocity.x, 0); pState.jumping = false; } if (!pState.jumping) { if (jumpBufferCounter > 0 && coyoteTimeCounter > 0) { rb.linearVelocity = new Vector3(rb.linearVelocity.x, jumpForce); pState.jumping = true; } else if(!Grounded() && airJumpCounter < maxAirJumps && Input.GetButtonDown("Jump")) { pState.jumping = true; airJumpCounter++; rb.linearVelocity = new Vector3(rb.linearVelocity.x, jumpForce); } } anim.SetBool("Jumping", !Grounded()); } void UpdateJumpVariables() { if (Grounded()) { pState.jumping = false; coyoteTimeCounter = coyoteTime; airJumpCounter = 0; } else { coyoteTimeCounter -= Time.deltaTime; } if (Input.GetButtonDown("Jump")) { jumpBufferCounter = jumpBufferFrames; } else { jumpBufferCounter--; } } } ```November 19, 2025 at 10:03 pm #19054::Hello MOHD YASAR! It looks like you’re encountering a
NullReferenceExceptionin yourDestroyAfterAnimationscript. This error typically occurs when you’re trying to access a component or variable that hasn’t been initialized or assigned.In your
DestroyAfterAnimationscript, you’re trying to get theAnimatorcomponent and immediately access its current state length in theStartmethod. However, if theAnimatorcomponent is not attached to the same GameObject as theDestroyAfterAnimationscript, you’ll get aNullReferenceException.Here’s how you can fix it:
-
Ensure the Animator Component is Present: Make sure that the GameObject to which the
DestroyAfterAnimationscript is attached also has anAnimatorcomponent. If it doesn’t, you need to add one or ensure that the script is attached to the correct GameObject. -
Check for Null Reference: You can add a null check to ensure that the
Animatorcomponent is not null before trying to access it. Here’s an updated version of yourDestroyAfterAnimationscript:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class DestroyAfterAnimation : MonoBehaviour { void Start() { Animator animator = GetComponent(); if (animator != null) { Destroy(gameObject, animator.GetCurrentAnimatorStateInfo(0).length); } else { Debug.LogError("Animator component not found on " + gameObject.name); } } }With this change, if the
Animatorcomponent is missing, you’ll get a clear error message in the console instead of aNullReferenceException.-
Check Animation States: If the
Animatoris present but the animation state is not set correctly, it might also lead to issues. Make sure that the animation you want to destroy the GameObject after is the one currently playing. -
Debugging: If you’re still having issues, you can add more debug logs to see what is happening at runtime. For example, log the current state of the animator to see if it’s transitioning correctly.
Let me know if you need further assistance! Happy coding!
-
-
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: