Forum begins after the advertisement:
[Part 5] Scene Transition Errors
Home › Forums › Video Game Tutorial Series › Creating a Metroidvania in Unity › [Part 5] Scene Transition Errors
- This topic has 30 replies, 4 voices, and was last updated 23 hours, 35 minutes ago by
Nirvik Rajbhandari.
-
AuthorPosts
-
December 25, 2025 at 12:17 am #19120::
I was trying to get the scene transition code to work and I decided to test it out, but there were many things wrong with my code or something which ended up in the player having increased jump height for some reason and the player not going through the cutscene. I can give scripts if needed and a screenshot of any of the game object’s inspectors.
December 25, 2025 at 2:17 am #19122::Sure, I can help you troubleshoot the issue with your scene transition code and the unexpected jump height of the player. Please provide the relevant scripts and any screenshots of the game object’s inspector that you think might help clarify the problem. This will allow me to assist you better!
December 25, 2025 at 5:06 pm #19123::Can you share your SceneTransition script, as well as a video recording of how your project’s scene transition betweeen levels look like now?
December 26, 2025 at 1:24 pm #19124December 26, 2025 at 11:12 pm #19125::sorry for the late response. Here is the scene transition script code, the game manager script, and the player controller script.
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class Scene_Transition : MonoBehaviour { [SerializeField] private string Transition_To; [SerializeField] private Transform Start_Point; [SerializeField] private Vector2 Exit_Direction; [SerializeField] private float Exit_Time; private void Start() { if(Transition_To == Game_Manager.Instance.Transitioned_From) { Player_Controller.Instance.transform.position = Start_Point.position; StartCoroutine(Player_Controller.Instance.Walk_Into_New_Scene(Exit_Direction, Exit_Time)); } } void OnTriggerEnter2D(Collider2D Other) { if(Other.CompareTag("Player")) { Game_Manager.Instance.Transitioned_From = SceneManager.GetActiveScene().name; Player_Controller.Instance.Player_State.Cutscene = true; Player_Controller.Instance.Player_State.Invincible = true; SceneManager.LoadScene(Transition_To); } } }using System.Collections; using System.Collections.Generic; using UnityEngine; public class Game_Manager : MonoBehaviour { public string Transitioned_From; public static Game_Manager Instance {get; private set;} private void Awake() { if(Instance != null && Instance != this) { Destroy(gameObject); } else { Instance = this; } DontDestroyOnLoad(gameObject); } }using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class Player_Controller : MonoBehaviour { [Header("Horizontal Movement Settings")] [SerializeField] private float WalkSpeed = 1; [Space(5)] [Header("Vertical Movement Settings")] [SerializeField] private float Jump_Force = 45; private float Jump_Buffer_Counter; [SerializeField] private float Jump_Buffer_Frames = 0; private float Coyote_Time_Counter; [SerializeField] private float Coyote_Time; private int Air_Jump_Counter = 0; [SerializeField] private int Max_Air_Jumps; [Space(5)] [Header("Ground Check Settings")] public ContactFilter2D ContactFilter; [Space(5)] [Header("Dash Settings")] [SerializeField] private float Dash_Speed; [SerializeField] private float Dash_Time; [SerializeField] private float Dash_Cooldown; private bool Can_Dash = true; private bool Dashed; [SerializeField] GameObject Dash_Effect; [Space(5)] [Header("Mouse Settings")] [SerializeField] private float Up_Parameter_1; [SerializeField] private float Up_Parameter_2; [SerializeField] private float Down_Parameter_1; [SerializeField] private float Down_Parameter_2; private Vector3 Mouse_Screen_Positon; private Vector3 Mouse_World_Positon; private Vector2 Mouse_Direction; private float Mouse_Angle; private bool Mouse_On_Top; private bool Mouse_On_Bottom; [Header("Attack Settings")] [SerializeField] float Time_Between_Attack; float Attack_Time_Counter; [SerializeField] private Transform Side_Attack_Transform; [SerializeField] private Transform Up_Attack_Transform; [SerializeField] private Transform Down_Attack_Transform; [SerializeField] private Vector2 Side_Attack_Area; [SerializeField] private Vector2 Up_Attack_Area; [SerializeField] private Vector2 Down_Attack_Area; [SerializeField] private LayerMask Attackable_Layer; [SerializeField] private float Player_Damage; [SerializeField] GameObject Slash_Effect_Object; bool Attack_Bool = false; bool Restore_Time; float Restore_Time_Speed; [Space(5)] [Header("Recoil Settings")] [SerializeField] int Recoil_X_Steps = 5; [SerializeField] int Recoil_Y_Steps = 5; [SerializeField] int Recoil_X_Speed = 100; [SerializeField] int Recoil_Y_Speed = 100; int Steps_X_Recoiled; int Steps_Y_Recoiled; [Header("Health Settings")] public int Player_Health; public int Player_Max_Health; [SerializeField] GameObject Blood_Spurt; [SerializeField] float Hit_Flash_Speed; public delegate void On_Health_Changed_Delegate(); [HideInInspector] public On_Health_Changed_Delegate On_Health_Changed_Callback; float Heal_Timer; [SerializeField] float Time_To_Heal; [Space(5)] [Header("Mana Settings")] [SerializeField] UnityEngine.UI.Image Mana_Storage; [SerializeField] float Mana; [SerializeField] float Mana_Drain_Speed; [SerializeField] float Mana_Gain; [Space(5)] [Header("Spell Casting")] [SerializeField] float Mana_Spell_Cost = 0.3f; [SerializeField] float Time_Between_Cast = 0.5f; [SerializeField] float Spell_Damage; [SerializeField] float Down_Spell_Force; [SerializeField] GameObject Side_Spell; [SerializeField] GameObject Up_Spell; [SerializeField] GameObject Down_Spell; float Cast_Time_Counter; float Cast_Or_Heal_Timer; [Space(5)] [HideInInspector] public Player_State_List Player_State; private Rigidbody2D Rigidbody; private SpriteRenderer Sprite_Renderer; private float Gravity; private float XAxis; Animator Animator; public static Player_Controller Instance; private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); } else { Instance = this; } Player_Health = Player_Max_Health; } // Start is called before the first frame update void Start() { Player_State = GetComponent<Player_State_List>(); Rigidbody = GetComponent<Rigidbody2D>(); Sprite_Renderer = GetComponent<SpriteRenderer>(); Animator = GetComponent<Animator>(); Gravity = Rigidbody.gravityScale; Player_Mana = Mana; Mana_Storage.fillAmount = Mana; } private void OnDrawGizmos() { Gizmos.color = Color.blue; Gizmos.DrawWireCube(Side_Attack_Transform.position, Side_Attack_Area); Gizmos.DrawWireCube(Up_Attack_Transform.position, Up_Attack_Area); Gizmos.DrawWireCube(Down_Attack_Transform.position, Down_Attack_Area); } // Update is called once per frame void Update() { if(Player_State.Cutscene) { return; } GetInputs(); UpdateJumpVariables(); if (Player_State.Dashing) { return; } Restore_Time_Scale(); Flash_While_Invincible(); Move(); Heal(); Cast_Spell(); if (Player_State.Healing) { return; } Flip(); Jump(); Attack(); Start_Dash(); Debug.Log(Grounded()); } private void OnTriggerEnter2D(Collider2D Other) { if(Other.GetComponent<Enemy>() != null && Player_State.Casting) { Other.GetComponent<Enemy>().Enemy_Hit(Spell_Damage, (Other.transform.position - transform.position).normalized, -Recoil_Y_Speed); } } private void FixedUpdate() { if(Player_State.Cutscene||Player_State.Dashing||Player_State.Healing) { return; } Recoil(); } void GetInputs() { XAxis = Input.GetAxisRaw("Horizontal"); Attack_Bool = Input.GetButtonDown("Attack"); Mouse_Screen_Positon = Input.mousePosition; Mouse_Screen_Positon.z = Camera.main.ScreenToWorldPoint(transform.position).z; Mouse_World_Positon = Camera.main.ScreenToWorldPoint(Mouse_Screen_Positon); Mouse_Direction = transform.position - Mouse_World_Positon; Mouse_Angle = Vector2.SignedAngle(Vector2.right, Mouse_Direction); if (Mouse_Angle > Up_Parameter_1 && Mouse_Angle < Up_Parameter_2) { Mouse_On_Top = true; } else if (Mouse_Angle < Down_Parameter_1 && Mouse_Angle > Down_Parameter_2) { Mouse_On_Bottom = true; } else { Mouse_On_Top = false; Mouse_On_Bottom = false; } if (Input.GetButton("Cast/Heal")) { Cast_Or_Heal_Timer += Time.deltaTime; } else { Cast_Or_Heal_Timer = 0; } } void Flip() { if(Attack_Time_Counter < 0.5f) { return; } if(XAxis < 0) { transform.localScale = new Vector2(-Mathf.Abs(transform.localScale.x), transform.localScale.y); Player_State.Looking_Right = false; } else if(XAxis > 0) { transform.localScale = new Vector2(Mathf.Abs(transform.localScale.x), transform.localScale.y); Player_State.Looking_Right = true; } } private void Move() { if(Player_State.Healing) { Rigidbody.velocity = new Vector2(0,0); } Rigidbody.velocity = new Vector2(WalkSpeed * XAxis, Rigidbody.velocity.y); Animator.SetBool("Walking", Rigidbody.velocity.x != 0 && Grounded()); } void Start_Dash() { if(Input.GetButtonDown("Dash") && Can_Dash && !Dashed) { StartCoroutine(Dash()); Dashed = true; } if(Grounded()) { Dashed = false; } } IEnumerator Dash() { Player_State.Dashing = true; Player_State.Invincible = true; Can_Dash = false; Animator.SetTrigger("Dashing"); Rigidbody.gravityScale = 0; Rigidbody.velocity = new Vector2(transform.localScale.x * Dash_Speed, 0); if(Grounded()) { Instantiate(Dash_Effect, transform); } yield return new WaitForSeconds(Dash_Time); Rigidbody.gravityScale = Gravity; Player_State.Dashing = false; Player_State.Invincible = false; yield return new WaitForSeconds(Dash_Cooldown); Can_Dash = true; } public IEnumerator Walk_Into_New_Scene(Vector2 Exit_Direction, float Delay) { if(Exit_Direction.y > 0) { Rigidbody.velocity = Jump_Force * Exit_Direction; } if(Exit_Direction.x != 0) { XAxis = Exit_Direction.x > 0? 1 : -1; Move(); } Flip(); yield return new WaitForSeconds(Delay); Player_State.Invincible = false; Player_State.Cutscene = false; } void Attack() { Attack_Time_Counter += Time.deltaTime; if(Attack_Bool && Attack_Time_Counter >= Time_Between_Attack) { Attack_Time_Counter = 0; Animator.SetTrigger("Attacking"); if(!Mouse_On_Top && !Mouse_On_Bottom|| Mouse_On_Bottom && Grounded()) { Hit(Side_Attack_Transform, Side_Attack_Area, ref Player_State.Recoiling_X, Recoil_X_Speed); Slash_Effect_Angle(Slash_Effect_Object, 0, Side_Attack_Transform); } else if(Mouse_On_Top) { Hit(Up_Attack_Transform, Up_Attack_Area, ref Player_State.Recoiling_Y, Recoil_Y_Speed); Slash_Effect_Angle(Slash_Effect_Object, 80, Up_Attack_Transform); } else if(Mouse_On_Bottom && !Grounded()) { Hit(Down_Attack_Transform, Down_Attack_Area, ref Player_State.Recoiling_Y, Recoil_Y_Speed); Slash_Effect_Angle(Slash_Effect_Object, -90, Down_Attack_Transform); } } } void Hit(Transform Attack_Transform, Vector2 Attack_Area, ref bool Recoil_Directory, float Recoil_Strength) { Collider2D[] Objects_To_Hit = Physics2D.OverlapBoxAll(Attack_Transform.position, Attack_Area, 0, Attackable_Layer); List<Enemy> Hit_Enemies = new List<Enemy>(); if(Objects_To_Hit.Length > 0) { Recoil_Directory = true; } for(int i = 0; i < Objects_To_Hit.Length; i++) { Enemy e = Objects_To_Hit[i].GetComponent<Enemy>(); if(e && !Hit_Enemies.Contains(e)) { e.Enemy_Hit(Player_Damage, (transform.position - Objects_To_Hit[i].transform.position).normalized, Recoil_Strength); Hit_Enemies.Add(e); if(Objects_To_Hit[i].CompareTag("Enemy")) { Player_Mana += Mana_Gain; } } } } void Slash_Effect_Angle(GameObject Slash_Effect, int Effect_Angle, Transform Attack_Transform) { Slash_Effect = Instantiate(Slash_Effect, Attack_Transform); Slash_Effect.transform.eulerAngles = new Vector3(0, 0, Effect_Angle); Slash_Effect.transform.localScale = new Vector2(transform.localScale.x, transform.localScale.y); } void Recoil() { if(Player_State.Recoiling_X) { if(Player_State.Looking_Right) { Rigidbody.velocity = new Vector2(-Recoil_X_Speed, 0); } else if(!Player_State.Looking_Right) Rigidbody.velocity = new Vector2(Recoil_X_Speed, 0); } if(Player_State.Recoiling_Y) { if(Mouse_On_Bottom) { Rigidbody.gravityScale = 0; Rigidbody.velocity = new Vector2(Rigidbody.velocity.x, Recoil_Y_Speed); } else if(Mouse_On_Top) { Rigidbody.gravityScale = 0; Rigidbody.velocity = new Vector2(Rigidbody.velocity.x, -Recoil_Y_Speed); } Air_Jump_Counter = 0; } else { Rigidbody.gravityScale = Gravity; } if(Player_State.Recoiling_X && Steps_X_Recoiled < Recoil_X_Steps) { Steps_X_Recoiled++; } else { Stop_Recoil_X(); } if(Player_State.Recoiling_Y && Steps_Y_Recoiled < Recoil_Y_Steps) { Steps_Y_Recoiled++; } else { Stop_Recoil_Y(); } if(Grounded()) { Stop_Recoil_Y(); } } void Stop_Recoil_X() { Steps_X_Recoiled = 0; Player_State.Recoiling_X = false; } void Stop_Recoil_Y() { Steps_Y_Recoiled = 0; Player_State.Recoiling_Y = false; } public void Take_Damage(float Damage_Taken) { Player_Health_Int -= Mathf.RoundToInt(Damage_Taken); StartCoroutine(Stop_Taking_Damage()); } public IEnumerator Stop_Taking_Damage() { Player_State.Invincible = true; GameObject Blood_Spurt_Particles = Instantiate(Blood_Spurt, transform.position, Quaternion.identity); Destroy(Blood_Spurt_Particles, 1.5f); Animator.SetTrigger("Take Damage"); yield return new WaitForSeconds(1f); Player_State.Invincible = false; } void Flash_While_Invincible() { Sprite_Renderer.color = Player_State.Invincible ? Color.Lerp(Color.white, Color.black, Mathf.PingPong(Time.time * Hit_Flash_Speed, 1.0f)) : Color.white; } void Restore_Time_Scale() { if(Restore_Time) { if (Time.timeScale < 1) { Time.timeScale += Time.deltaTime * Restore_Time_Speed; } else { Time.timeScale = 1; Restore_Time = false; } } } public void Hit_Stop_Time(float New_Time_Scale, int Restore_Speed, float Delay) { Restore_Time_Speed = Restore_Speed; Time.timeScale = New_Time_Scale; if (Delay > 0) { StopCoroutine(Start_Time_Again(Delay)); StartCoroutine(Start_Time_Again(Delay)); } } IEnumerator Start_Time_Again(float Delay) { Restore_Time = true; yield return new WaitForSeconds(Delay); } public int Player_Health_Int { get { return Player_Health; } set { if (Player_Health != value) { Player_Health = Mathf.Clamp(value, 0, Player_Max_Health); if (On_Health_Changed_Callback != null) { On_Health_Changed_Callback.Invoke(); } } } } private void Heal() { if (Input.GetButton("Cast/Heal") && Cast_Or_Heal_Timer > 0.05f && Player_Health_Int < Player_Max_Health && Player_Mana > 0 && Grounded() && !Player_State.Dashing) { Player_State.Healing = true; Heal_Timer += Time.deltaTime; Animator.SetBool("Healing", true); Player_Mana -= Time.deltaTime * Mana_Drain_Speed; if (Heal_Timer >= Time_To_Heal) { Player_Health_Int++; Heal_Timer = 0; } } else { Player_State.Healing = false; Heal_Timer = 0; Animator.SetBool("Healing", false); } } private float Player_Mana { get { return Mana; } set { if (Mana != value) { Mana = Mathf.Clamp(value, 0, 1); Mana_Storage.fillAmount = Mana; } } } void Cast_Spell() { if (Input.GetButtonUp("Cast/Heal") && Cast_Or_Heal_Timer <= 0.05f && Cast_Time_Counter >= Time_Between_Cast && Mana >= Mana_Spell_Cost) { Player_State.Casting = true; Cast_Time_Counter = 0; StartCoroutine(Cast_Coroutine()); } else { Cast_Time_Counter += Time.deltaTime; } if (Grounded()) { Down_Spell.SetActive(false); } if(Down_Spell.activeInHierarchy) { Rigidbody.velocity = Down_Spell_Force * Vector2.down; } } IEnumerator Cast_Coroutine() { Animator.SetBool("Casting", true); Rigidbody.gravityScale = 0; yield return new WaitForSeconds(0.12f); Rigidbody.gravityScale = Gravity; if (!Mouse_On_Top && !Mouse_On_Bottom || Mouse_On_Bottom && Grounded()) { GameObject Fire_Ball = Instantiate(Side_Spell, Side_Attack_Transform.position, Quaternion.identity); if (Player_State.Looking_Right) { Fire_Ball.transform.eulerAngles = Vector3.zero; } else { Fire_Ball.transform.eulerAngles = new Vector3(Fire_Ball.transform.eulerAngles.x, 180); } Player_State.Recoiling_X = true; } else if (Mouse_On_Top) { Instantiate(Up_Spell, transform); Rigidbody.velocity = Vector2.zero; } else if (Mouse_On_Bottom && !Grounded()) { Down_Spell.SetActive(true); } Player_Mana -= Mana_Spell_Cost; yield return new WaitForSeconds(0.11f); Animator.SetBool("Casting", false); Player_State.Casting = false; } public bool Grounded() { return Rigidbody.IsTouching(ContactFilter); } void Jump() { if (Jump_Buffer_Counter > 0 && Coyote_Time_Counter > 0 && !Player_State.Jumping) { Rigidbody.velocity = new Vector3(Rigidbody.velocity.x, Jump_Force); Player_State.Jumping = true; } else if (!Grounded() && Air_Jump_Counter < Max_Air_Jumps && Input.GetButtonDown("Jump")) { Player_State.Jumping = true; Air_Jump_Counter++; Rigidbody.velocity = new Vector3(Rigidbody.velocity.x, Jump_Force); } if (Input.GetButtonUp("Jump") && Rigidbody.velocity.y > 0) { Rigidbody.velocity = new Vector2(Rigidbody.velocity.x, Rigidbody.velocity.y * 0.5f); } Animator.SetBool("Jumping", Rigidbody.velocity.y > 0 && !Grounded()); Animator.SetBool("Falling", Rigidbody.velocity.y < 0 && !Grounded()); } void UpdateJumpVariables() { if(Grounded()) { Player_State.Jumping = false; Coyote_Time_Counter = Coyote_Time; Air_Jump_Counter = 0; } else { Coyote_Time_Counter -= Time.deltaTime; } if(Input.GetButtonDown("Jump")) { Jump_Buffer_Counter = Jump_Buffer_Frames; } else { Jump_Buffer_Counter -= Time.deltaTime * 10; } } }December 26, 2025 at 11:17 pm #19126::Thanks for sharing your code! Let’s break down the potential issues you’re facing with the scene transition and the jump height.
-
Scene Transition Logic: In your
Scene_Transitionscript, you’re loading a new scene in theOnTriggerEnter2Dmethod, but you also have aStartmethod that checks if the player should be positioned at theStart_Pointof the new scene. This can lead to unexpected behaviors if the transition logic isn’t well controlled.Make sure that the
Startmethod only runs after the scene has fully loaded. You might want to delay the position setting until the new scene is fully initialized. You can do this by calling theWalk_Into_New_Scenecoroutine after loading the scene.Here’s an example of how to modify your
OnTriggerEnter2Dmethod:void OnTriggerEnter2D(Collider2D Other) { if (Other.CompareTag("Player")) { Game_Manager.Instance.Transitioned_From = SceneManager.GetActiveScene().name; Player_Controller.Instance.Player_State.Cutscene = true; Player_Controller.Instance.Player_State.Invincible = true; SceneManager.LoadScene(Transition_To); // Set position after the scene has loaded StartCoroutine(SetPlayerPositionAfterLoad()); } } private IEnumerator SetPlayerPositionAfterLoad() { yield return new WaitForSeconds(0.1f); // Delay to ensure scene is fully loaded Player_Controller.Instance.transform.position = Start_Point.position; StartCoroutine(Player_Controller.Instance.Walk_Into_New_Scene(Exit_Direction, Exit_Time)); } -
Jump Height Issues: The jump height issue may arise from the way the
Jumpmethod is implemented in yourPlayer_Controllerscript. TheJump_Forcevariable directly affects how high the player jumps. If it’s being modified unintentionally or if theJumpmethod is being called when it shouldn’t be, it can lead to unexpected jump heights.Make sure that
Jump()is only called when you want the player to jump. Additionally, check if there are any other scripts that might modify theJump_Forcedynamically during gameplay. -
Debugging: Utilize debugging tools to log the jump height and ensure that values are as expected at runtime. You can add
Debug.Log(Jump_Force);in the relevant parts of your jump logic to see what value it holds when the jump is triggered. -
Player State Management: Ensure that the player state management (like
Player_State.CutsceneandPlayer_State.Invincible) is correctly implemented and reset when transitioning back to normal gameplay after the cutscene. If these states are not reset correctly, they might interfere with normal player controls.
If you still encounter issues after these adjustments, please provide any error messages, unexpected behaviors, or specific scenarios where the jump height changes, and we can further investigate!
December 27, 2025 at 4:51 am #19127December 27, 2025 at 4:52 am #19128::It also keeps giving me nullreferenceexcpetion errors in the console tab but I believe those are fine right?
December 27, 2025 at 8:17 am #19129::Thanks for sharing the video link! I’ll take a look at the video for additional context.
As for the
NullReferenceExceptionerrors, it’s important to address them rather than dismiss them as “fine.” ANullReferenceExceptiontypically occurs when your code tries to access a member on an object that isnull. This can lead to unpredictable behavior in your game, including problems like the ones you’re experiencing with scene transitions and player controls.Here are a few steps to debug and resolve
NullReferenceExceptionerrors:-
Check the Console: Look at the console output to see exactly where the errors are being thrown. The error message will usually include a line number and reference the specific script causing the issue.
-
Identify Null Objects: The error indicates that you’re trying to access a property or method on an object that hasn’t been instantiated or assigned. For example, if you’re trying to access
Player_Controller.Instanceand it’snull, you need to ensure that thePlayer_Controlleris properly instantiated and assigned before you call it. -
Use Debugging: Add
Debug.Logstatements before the lines where the exceptions are thrown to check if the objects arenull. For instance:Debug.Log(Player_Controller.Instance); // Check if this is null before using it -
Initialization Order: Make sure that your singleton instances (like
Game_ManagerandPlayer_Controller) are being initialized correctly. For instance, theAwakemethod should be used to set up singletons before any other methods that might reference them. -
Inspect the Inspector: If you’re using serialized fields (like in
Scene_TransitionorPlayer_Controller), ensure that all references in the Unity Inspector are correctly assigned. -
Review the Video: Watch the video for any specific moments where the player behaves unexpectedly. Look for any patterns or repeated errors in the console that coincide with these behaviors.
If you can identify the specific lines where the
NullReferenceExceptionis occurring, please share those details, and I can help you troubleshoot further!December 27, 2025 at 10:10 am #19130::It happens in line 244 of the player controller code but only when the player is moving from one scene to the next
December 27, 2025 at 10:28 pm #19132December 27, 2025 at 10:47 pm #19133::Line 244 is this right?
private void Move() { if(Player_State.Healing) { Rigidbody.velocity = new Vector2(0,0); } Rigidbody.velocity = new Vector2(WalkSpeed * XAxis, Rigidbody.velocity.y); Animator.SetBool("Walking", Rigidbody.velocity.x != 0 && Grounded()); }If there is a null reference exception, it means that
Player_Stateis empty. Check if you have aPlayer_Statecomponent on your Player GameObject.December 28, 2025 at 12:34 am #19140::My Player Character does have a player state component. I don’t mean that to sound rude. If it helps here’s the full error log.
NullReferenceException: Object reference not set to an instance of an object Player_Controller.Move () (at Assets/Scripts/Player_Controller.cs:244) Player_Controller+<Walk_Into_New_Scene>d__84.MoveNext () (at Assets/Scripts/Player_Controller.cs:295) UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <f712b1dc50b4468388b9c5f95d0d0eaf>:0) UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) Scene_Transition:Start() (at Assets/Scripts/Scene_Transition.cs:18)December 28, 2025 at 5:17 am #19143::The
NullReferenceExceptionyou’re encountering at line 244 in thePlayer_Controllerscript likely indicates that you’re trying to access a member of an object that hasn’t been initialized or isnull. Given that this error occurs when transitioning between scenes, it may be related to the timing of when certain components are accessed.Here are a few steps to help you troubleshoot and resolve this issue:
-
Check Line 244: Look at what is happening at line 244 in your
Player_Controllerscript. This line is likely trying to access a property or method on an object that is not set. Ensure that all objects being accessed are properly initialized. -
Player State Component: Since you mentioned that your player character does have a player state component, ensure that it is correctly assigned in the Inspector and that it is not being destroyed or set to
nullduring the scene transition. -
Coroutine Timing: The
Walk_Into_New_Scenecoroutine is called immediately after loading the new scene. If the player state or any other required component is not ready yet, it could lead to aNullReferenceException. You may want to add a small delay before starting the coroutine to ensure everything is initialized correctly:private IEnumerator SetPlayerPositionAfterLoad() { yield return new WaitForSeconds(0.1f); // Delay to ensure scene is fully loaded Player_Controller.Instance.transform.position = Start_Point.position; yield return new WaitForSeconds(0.1f); // Additional delay before walking into the new scene StartCoroutine(Player_Controller.Instance.Walk_Into_New_Scene(Exit_Direction, Exit_Time)); } -
Debugging: Add
Debug.Logstatements before line 244 to check if any objects arenull. For example:Debug.Log(Player_State); // Check if Player_State is null -
Initialization Order: Ensure that the
Player_Controllerand its components are initialized properly before the scene transition occurs. You might want to check the order of your scripts in the Unity Editor to ensure that thePlayer_Controlleris not being destroyed or reset unexpectedly.
If you continue to face issues, could you please specify what exactly is happening at line 244? This will help in diagnosing the problem more accurately.
December 28, 2025 at 2:33 pm #19145::My Player Character does have a player state component. I don’t mean that to sound rude. If it helps here’s the full error log.
No worries, you’re not sounding rude at all.
I can’t tell which line specifically based on the information you provided, only that the
Move()function is causing the error. Let’s add the following lines to yourMove()function so we can tell which is the element that is null.private void Move() { print("Player state: " + Player_State); print("Rigidbody: " + Rigidbody); print("Animator: " + Animator); if(Player_State.Healing) { Rigidbody.velocity = new Vector2(0,0); } Rigidbody.velocity = new Vector2(WalkSpeed * XAxis, Rigidbody.velocity.y); Animator.SetBool("Walking", Rigidbody.velocity.x != 0 && Grounded()); }Run the game, and show me the messages that are printed when the game is running.
December 29, 2025 at 12:05 pm #19149::View post on imgur.com
Sorry for the late response. The image above is the image of my console tab after passing thru a scene change. I believe all the variables are being considered null for one frame before moving on to the next scene.
December 29, 2025 at 3:05 pm #19150::@nirvikrajbhandari type “t:Player_Controller” into your Hierarchy search bar and see if there is more than 1 game object that shows up. I suspect you have multiple player controller scripts attached in your Scene, which is what is causing the null reference exception.
December 29, 2025 at 5:17 pm #19151::The
NullReferenceExceptionyou’re encountering at line 244 in yourPlayer_Controllerscript likely indicates that some variables or components are not properly initialized or assigned when transitioning between scenes.Given that the error occurs during a scene transition, it’s possible that the player state or other components are not yet available when the
Move()method is called. Here are a few suggestions to help resolve this issue:-
Check Player State Initialization: Ensure that the
Player_Statecomponent is properly assigned in theStart()method of thePlayer_Controllerscript. If thePlayer_Statecomponent is not found, it will benull, leading to the exception when you try to access its properties.Player_State = GetComponent(); if (Player_State == null) { Debug.LogError("Player_State component is not attached to the Player_Controller."); } -
Delay Scene Transition Logic: Since you suspect that variables are being considered null for one frame, you might want to introduce a slight delay before executing the
Move()method after the scene transition. This can be done by modifying theWalk_Into_New_Scenecoroutine to wait a bit longer before accessing player state or other components.public IEnumerator Walk_Into_New_Scene(Vector2 Exit_Direction, float Delay) { yield return new WaitForSeconds(0.1f); // Add a small delay before executing the rest of the logic if (Exit_Direction.y > 0) { Rigidbody.velocity = Jump_Force * Exit_Direction; } if (Exit_Direction.x != 0) { XAxis = Exit_Direction.x > 0 ? 1 : -1; Move(); } Flip(); yield return new WaitForSeconds(Delay); Player_State.Invincible = false; Player_State.Cutscene = false; } -
Ensure Singleton Instances are Ready: Make sure that the singleton instances (like
Player_ControllerandGame_Manager) are initialized before any scene transitions occur. You can add checks to ensure that these instances are not null before accessing them. -
Debugging: Use
Debug.Logstatements to track the state of your variables before the line that throws the exception. This can help you identify which specific variable is null. -
Scene Management: If you’re using
DontDestroyOnLoadfor your player or game manager, ensure that they are not being destroyed or reset during the scene transition.
If the issue persists, could you provide more details about what happens in your game just before the transition? For example, are there any specific actions or conditions that lead to the transition? This information could help further diagnose the problem.
December 29, 2025 at 11:41 pm #19152::View post on imgur.com
Sorry for the late response. The image above is the image of my console tab after passing thru a scene change. I believe all the variables are being considered null for one frame before moving on to the next scene.December 30, 2025 at 12:17 am #19153::It looks like the
NullReferenceExceptionis occurring in theMove()method of yourPlayer_Controllerscript, specifically when transitioning between scenes. This can happen if certain variables or components are not properly initialized before the scene transition occurs.Here are a few suggestions to help resolve this issue:
-
Check Player State Initialization: Ensure that the
Player_Statecomponent is correctly assigned and initialized before theMove()method is called. You can add a null check at the beginning of theMove()method to prevent the exception:if (Player_State == null) { Debug.LogError("Player_State is null!"); return; } -
Delay Scene Transition Logic: If you suspect that variables are being accessed before they are initialized, consider adding a slight delay before executing the logic in
Walk_Into_New_Scene. This can help ensure that the scene has fully loaded and all components are ready:private IEnumerator SetPlayerPositionAfterLoad() { yield return new WaitForSeconds(0.1f); // Adjust the delay if necessary Player_Controller.Instance.transform.position = Start_Point.position; yield return new WaitForEndOfFrame(); // Wait for the end of the frame StartCoroutine(Player_Controller.Instance.Walk_Into_New_Scene(Exit_Direction, Exit_Time)); } -
Debugging: Use
Debug.Logstatements to track the state of your variables before the exception occurs. This can help you identify which variable is null:Debug.Log("Player State: " + Player_State); Debug.Log("Rigidbody: " + Rigidbody); -
Check Scene Setup: Make sure that all necessary components are attached to the player GameObject in the new scene. If the player GameObject is being destroyed or not properly instantiated, it can lead to null references.
-
Review the Transition Logic: Ensure that the logic in your
Scene_Transitionscript is correctly managing the player’s state and position before the scene loads. If the player is being moved or manipulated while the scene is transitioning, it can lead to unexpected behavior.
If you’ve tried these suggestions and are still encountering issues, could you provide more details about the specific variables or components that are null when the exception occurs? This will help narrow down the problem further.
-
-
AuthorPosts
- You must be logged in to reply to this topic.
Advertisement below: