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

Viewing 20 posts - 1 through 20 (of 31 total)
  • Author
    Posts
  • #19120
    Nirvik Rajbhandari
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    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.

    #19122
    Ser Apustaja
    Level 6
    AI Assistant
    (BETA)
    Helpful?
    Up
    0
    ::

    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!

    #19123
    Terence
    Level 31
    Keymaster
    Helpful?
    Up
    0
    ::

    Can you share your SceneTransition script, as well as a video recording of how your project’s scene transition betweeen levels look like now?

    #19124
    Terence
    Level 31
    Keymaster
    Helpful?
    Up
    0
    ::

    @nirvikrajbhandari let me know if you still need your help on this yeah

    #19125
    Nirvik Rajbhandari
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    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;
            }
        }
    }
    #19126
    Ser Apustaja
    Level 6
    AI Assistant
    (BETA)
    Helpful?
    Up
    0
    ::

    Thanks for sharing your code! Let’s break down the potential issues you’re facing with the scene transition and the jump height.

    1. Scene Transition Logic: In your Scene_Transition script, you’re loading a new scene in the OnTriggerEnter2D method, but you also have a Start method that checks if the player should be positioned at the Start_Point of the new scene. This can lead to unexpected behaviors if the transition logic isn’t well controlled.

      Make sure that the Start method 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 the Walk_Into_New_Scene coroutine after loading the scene.

      Here’s an example of how to modify your OnTriggerEnter2D method:

      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));
      }
    2. Jump Height Issues: The jump height issue may arise from the way the Jump method is implemented in your Player_Controller script. The Jump_Force variable directly affects how high the player jumps. If it’s being modified unintentionally or if the Jump method 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 the Jump_Force dynamically during gameplay.

    3. 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.

    4. Player State Management: Ensure that the player state management (like Player_State.Cutscene and Player_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!

    #19127
    Nirvik Rajbhandari
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    I forgot to send a video here it is.

    View post on imgur.com
    #19128
    Nirvik Rajbhandari
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    It also keeps giving me nullreferenceexcpetion errors in the console tab but I believe those are fine right?

    #19129
    Ser Apustaja
    Level 6
    AI Assistant
    (BETA)
    Helpful?
    Up
    0
    ::

    Thanks for sharing the video link! I’ll take a look at the video for additional context.

    As for the NullReferenceException errors, it’s important to address them rather than dismiss them as “fine.” A NullReferenceException typically occurs when your code tries to access a member on an object that is null. 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 NullReferenceException errors:

    1. 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.

    2. 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.Instance and it’s null, you need to ensure that the Player_Controller is properly instantiated and assigned before you call it.

    3. Use Debugging: Add Debug.Log statements before the lines where the exceptions are thrown to check if the objects are null. For instance:

      Debug.Log(Player_Controller.Instance); // Check if this is null before using it
    4. Initialization Order: Make sure that your singleton instances (like Game_Manager and Player_Controller) are being initialized correctly. For instance, the Awake method should be used to set up singletons before any other methods that might reference them.

    5. Inspect the Inspector: If you’re using serialized fields (like in Scene_Transition or Player_Controller), ensure that all references in the Unity Inspector are correctly assigned.

    6. 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 NullReferenceException is occurring, please share those details, and I can help you troubleshoot further!

    #19130
    Nirvik Rajbhandari
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    It happens in line 244 of the player controller code but only when the player is moving from one scene to the next

    #19132
    Nirvik Rajbhandari
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    I tried using the code ser apustaja gave me but it didn’t work

    #19133
    Terence
    Level 31
    Keymaster
    Helpful?
    Up
    0
    ::

    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_State is empty. Check if you have a Player_State component on your Player GameObject.

    #19140
    Nirvik Rajbhandari
    Level 5
    Participant
    Helpful?
    Up
    0
    ::

    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)
    #19143
    Ser Apustaja
    Level 6
    AI Assistant
    (BETA)
    Helpful?
    Up
    0
    ::

    The NullReferenceException you’re encountering at line 244 in the Player_Controller script likely indicates that you’re trying to access a member of an object that hasn’t been initialized or is null. 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:

    1. Check Line 244: Look at what is happening at line 244 in your Player_Controller script. 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.

    2. 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 null during the scene transition.

    3. Coroutine Timing: The Walk_Into_New_Scene coroutine 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 a NullReferenceException. 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));
      }
    4. Debugging: Add Debug.Log statements before line 244 to check if any objects are null. For example:

      Debug.Log(Player_State); // Check if Player_State is null
    5. Initialization Order: Ensure that the Player_Controller and 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 the Player_Controller is 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.

    #19145
    Terence
    Level 31
    Keymaster
    Helpful?
    Up
    0
    ::
    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 your Move() 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.

    #19149
    Nirvik Rajbhandari
    Level 5
    Participant
    Helpful?
    Up
    0
    ::
    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.

    #19150
    Terence
    Level 31
    Keymaster
    Helpful?
    Up
    0
    ::

    @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.

    #19151
    Ser Apustaja
    Level 6
    AI Assistant
    (BETA)
    Helpful?
    Up
    0
    ::

    The NullReferenceException you’re encountering at line 244 in your Player_Controller script 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:

    1. Check Player State Initialization: Ensure that the Player_State component is properly assigned in the Start() method of the Player_Controller script. If the Player_State component is not found, it will be null, 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.");
      }
    2. 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 the Walk_Into_New_Scene coroutine 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;
      }
    3. Ensure Singleton Instances are Ready: Make sure that the singleton instances (like Player_Controller and Game_Manager) are initialized before any scene transitions occur. You can add checks to ensure that these instances are not null before accessing them.

    4. Debugging: Use Debug.Log statements to track the state of your variables before the line that throws the exception. This can help you identify which specific variable is null.

    5. Scene Management: If you’re using DontDestroyOnLoad for 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.

    #19152
    Nirvik Rajbhandari
    Level 5
    Participant
    Helpful?
    Up
    0
    ::
    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.
    #19153
    Ser Apustaja
    Level 6
    AI Assistant
    (BETA)
    Helpful?
    Up
    0
    ::

    It looks like the NullReferenceException is occurring in the Move() method of your Player_Controller script, 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:

    1. Check Player State Initialization: Ensure that the Player_State component is correctly assigned and initialized before the Move() method is called. You can add a null check at the beginning of the Move() method to prevent the exception:

      if (Player_State == null)
      {
          Debug.LogError("Player_State is null!");
          return;
      }
    2. 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));
      }
    3. Debugging: Use Debug.Log statements 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);
    4. 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.

    5. Review the Transition Logic: Ensure that the logic in your Scene_Transition script 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.

Viewing 20 posts - 1 through 20 (of 31 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: