Forum begins after the advertisement:


[Part 7] Death respawn screen always on screen

Home Forums Video Game Tutorial Series Creating a Metroidvania in Unity [Part 7] Death respawn screen always on screen

Viewing 15 posts - 1 through 15 (of 19 total)
  • Author
    Posts
  • #15692
    Sanket Pise
    Level 4
    Participant
    Helpful?
    Up
    0
    ::

    I am having a issue with my death screen,it happens so that my death screen is always on screen along with the mana and health UI and I dont know how to fix it whenever the player die the scene fades to black and yet the death screen occurs could anyone help out..

    UI manager

    <code>using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class UIManager : MonoBehaviour
    {
        public SceneFader sceneFader;
    
        public static UIManager Instance;
    
        [SerializeField] GameObject deathScreen;
    
        [SerializeField] GameObject halfMana, fullMana;
    
        public enum ManaState
        {
            fullMana,
            halfMana,
        }
    
        public ManaState manaState;
    
        private void Awake()
        {
            if (Instance != null && Instance != this)
            {
                Destroy(gameObject);
            }
            else
            {
                Instance = this;
            }
            DontDestroyOnLoad(gameObject);
    
            sceneFader = GetComponentInChildren<SceneFader>();
        }
    
        public void SwitchMana(ManaState _manaState)
        {
            switch (_manaState) 
            { 
                case ManaState.fullMana:
                    halfMana.SetActive(false);
                    fullMana.SetActive(true);
                    break;
    
                case ManaState.halfMana:
                    fullMana.SetActive(false);
                    halfMana.SetActive(true);
                    break;
    
            }
    
            manaState = _manaState;  
        }
    
        public IEnumerator ActivateDeathScreen()
        {
            yield return new WaitForSeconds(0.8f);
            StartCoroutine(sceneFader.Fade(SceneFader.FadeDirection.In));
    
            yield return new WaitForSeconds(0.8f);
            deathScreen.SetActive(true);
    
        }
    
        public void StartDeactivateDeathScreenCoroutine()
        {
            StartCoroutine(DeactivateDeathScreen());
        }
    
        public IEnumerator DeactivateDeathScreen()
        {
            yield return new WaitForSeconds(0.5f);
            deathScreen.SetActive(false);
            StartCoroutine(sceneFader.Fade(SceneFader.FadeDirection.Out));
        }
    
    }</code>

    Player Controller

    <code>using UnityEngine.UIElements;
    using UnityEngine.UI;
    using System.Collections.Generic;
    using UnityEngine;
    using System.Collections;
    
    public class PlayerController : MonoBehaviour
    {
        [Header("Horizontal Movement Settings:")]
        [SerializeField] private float walkSpeed = 1; //sets the players movement speed on the ground
        [Space(5)]
    
        [Header("Vertical Movement Settings")]
        [SerializeField] private float jumpForce = 45f; //sets how hight the player can jump
    
        private float jumpBufferCounter = 0; //stores the jump button input
        [SerializeField] private float jumpBufferFrames; //sets the max amount of frames the jump buffer input is stored
    
        private float coyoteTimeCounter = 0; //stores the Grounded() bool
        [SerializeField] private float coyoteTime; //sets the max amount of frames the Grounded() bool is stored
    
        private int airJumpCounter = 0; //keeps track of how many times the player has jumped in the air
        [SerializeField] private int maxAirJumps; //the max no. of air jumps
    
        private float gravity; //stores the gravity scale at start
        [Space(5)]
    
        [Header("Ground Check Settings:")]
        [SerializeField] private Transform groundCheckPoint; //point at which ground check happens
        [SerializeField] private float groundCheckY = 0.2f; //how far down from ground chekc point is Grounded() checked
        [SerializeField] private float groundCheckX = 0.5f; //how far horizontally from ground chekc point to the edge of the player is
        [SerializeField] private LayerMask whatIsGround; //sets the ground layer
        [Space(5)]
    
        [Header("Dash Settings")]
        [SerializeField] private float dashSpeed; //speed of the dash
        [SerializeField] private float dashTime; //amount of time spent dashing
        [SerializeField] private float dashCooldown; //amount of time between dashes
        [SerializeField] GameObject dashEffect;
        private bool canDash = true, dashed;
        [Space(5)]
    
        [Header("Attack Settings:")]
        [SerializeField] private Transform SideAttackTransform; //the middle of the side attack area
        [SerializeField] private Vector2 SideAttackArea; //how large the area of side attack is
    
        [SerializeField] private Transform UpAttackTransform; //the middle of the up attack area
        [SerializeField] private Vector2 UpAttackArea; //how large the area of side attack is
    
        [SerializeField] private Transform DownAttackTransform; //the middle of the down attack area
        [SerializeField] private Vector2 DownAttackArea; //how large the area of down attack is
    
        [SerializeField] private LayerMask attackableLayer; //the layer the player can attack and recoil off of
    
        [SerializeField] private float timeBetweenAttack;
        private float timeSinceAttack;
    
        [SerializeField] private float damage; //the damage the player does to an enemy
    
        [SerializeField] private GameObject slashEffect; //the effect of the slashs
    
        bool restoreTime;
        float restoreTimeSpeed;
        [Space(5)]
    
        [Header("Recoil Settings:")]
        [SerializeField] private int recoilXSteps = 5; //how many FixedUpdates() the player recoils horizontally for
        [SerializeField] private int recoilYSteps = 5; //how many FixedUpdates() the player recoils vertically for
    
        [SerializeField] private float recoilXSpeed = 100; //the speed of horizontal recoil
        [SerializeField] private float recoilYSpeed = 100; //the speed of vertical recoil
    
        private int stepsXRecoiled, stepsYRecoiled; //the no. of steps recoiled horizontally and verticall
        [Space(5)]
    
        [Header("Health Settings")]
        public int health;
        public int maxHealth;
        [SerializeField] GameObject bloodSpurt;
        [SerializeField] float hitFlashSpeed;
        public delegate void OnHealthChangedDelegate();
        [HideInInspector] public OnHealthChangedDelegate onHealthChangedCallback;
    
        float healTimer;
        [SerializeField] float timeToHeal;
        [Space(5)]
    
        [Header("Mana Settings")]
        [SerializeField] UnityEngine.UI.Image manaStorage;
    
        [SerializeField] float mana;
        [SerializeField] float manaDrainSpeed;
        [SerializeField] float manaGain;
        bool halfMana;
        [Space(5)]
    
        [Header("Spell Settings")]
        //spell stats
        [SerializeField] float manaSpellCost = 0.3f;
        [SerializeField] float timeBetweenCast = 0.5f;
        float timeSinceCast;
        [SerializeField] float spellDamage; //upspellexplosion and downspellfireball
        [SerializeField] float downSpellForce; // desolate dive only
        //spell cast objects
        [SerializeField] GameObject sideSpellFireball;
        [SerializeField] GameObject upSpellExplosion;
        [SerializeField] GameObject downSpellFireball;
        float castOrHealTimer;
        [Space(5)]
    
        [HideInInspector] public PlayerStateList pState;
        private Animator anim;
        private Rigidbody2D rb;
        private SpriteRenderer sr;
    
        //Input Variables
        private float xAxis, yAxis;
        private bool attack = false;
    
        private bool canFlash = true;
    
        //creates a singleton of the PlayerController
        public static PlayerController Instance;
    
        private void Awake()
        {
            if (Instance != null && Instance != this)
            {
                Destroy(gameObject);
            }
            else
            {
                Instance = this;
            }
            DontDestroyOnLoad(gameObject);
        }
    
        // Start is called before the first frame update
        void Start()
        {
            pState = GetComponent<PlayerStateList>();
    
            rb = GetComponent<Rigidbody2D>();
            sr = GetComponent<SpriteRenderer>();
    
            anim = GetComponent<Animator>();
    
            gravity = rb.gravityScale;
    
            Health = maxHealth;
            Mana = mana;
            manaStorage.fillAmount = Mana;
    
            pState.alive = 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()
        {
            Debug.Log($"cutscene: {pState.cutscene}, dashing: {pState.dashing}, healing: {pState.healing}, alive: {pState.alive}");
    
            if (pState.cutscene) return;
            if (pState.alive)
            {
                GetInputs();
            }
    
            UpdateJumpVariables();
            RestoreTimeScale();
    
            if (pState.dashing || pState.healing) return;
            if (pState.alive)
            {
                Move();
                Heal();
                CastSpell();
                Flip();
                Jump();
                StartDash();
                Attack();
            }
            FlashWhileInvincible();
        }
        private void OnTriggerEnter2D(Collider2D _other) //for up and down cast spell
        {
            if (_other.GetComponent<Enemy>() != null && pState.casting)
            {
                _other.GetComponent<Enemy>().EnemyHit(spellDamage, (_other.transform.position - transform.position).normalized, -recoilYSpeed);
            }
        }
    
        private void FixedUpdate()
        {
            if (pState.dashing || pState.healing || pState.cutscene) return;
            Recoil();
        }
    
        void GetInputs()
        {
            xAxis = Input.GetAxisRaw("Horizontal");
            yAxis = Input.GetAxisRaw("Vertical");
            attack = Input.GetButtonDown("Attack");
    
            if (Input.GetButton("Cast/Heal"))
            {
                castOrHealTimer += Time.deltaTime;
            }
            else
            {
                castOrHealTimer = 0;
            }
    
            Debug.Log($"castOrHealTimer: {castOrHealTimer}");
        }
    
        void Flip()
        {
            if (xAxis < 0)
            {
                transform.localScale = new Vector2(-Mathf.Abs(transform.localScale.x), transform.localScale.y);
                pState.lookingRight = false;
            }
            else if (xAxis > 0)
            {
                transform.localScale = new Vector2(Mathf.Abs(transform.localScale.x), transform.localScale.y);
                pState.lookingRight = true;
            }
        }
    
        private void Move()
        {
            if (pState.healing) rb.velocity = new Vector2(0, 0);
            rb.velocity = new Vector2(walkSpeed * xAxis, rb.velocity.y);
            anim.SetBool("Walking", rb.velocity.x != 0 && Grounded());
        }
    
        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;
            int _dir = pState.lookingRight ? 1 : -1;
            rb.velocity = new Vector2(_dir * dashSpeed, 0);
            if (Grounded()) Instantiate(dashEffect, transform);
            yield return new WaitForSeconds(dashTime);
            rb.gravityScale = gravity;
            pState.dashing = false;
            yield return new WaitForSeconds(dashCooldown);
            canDash = true;
        }
    
        public IEnumerator WalkIntoNewScene(Vector2 _exitDir, float _delay)
        {
            pState.invincible = true;
    
            //If exit direction is upwards
            if (_exitDir.y > 0)
            {
                rb.velocity = jumpForce * _exitDir;
            }
    
            //If exit direction requires horizontal movement
            if (_exitDir.x != 0)
            {
                xAxis = _exitDir.x > 0 ? 1 : -1;
                Move();
            }
    
            Flip();
            yield return new WaitForSeconds(_delay);
            pState.invincible = false;
            pState.cutscene = false;
        }
    
        void Attack()
        {
            timeSinceAttack += Time.deltaTime;
            if (attack && timeSinceAttack >= timeBetweenAttack)
            {
                timeSinceAttack = 0;
                anim.SetTrigger("Attacking");
    
                if (yAxis == 0 || yAxis < 0 && Grounded())
                {
    
                    int _recoilLeftOrRight = pState.lookingRight ? 1 : -1;
    
                    Hit(SideAttackTransform, SideAttackArea, ref pState.recoilingX,Vector2.right * _recoilLeftOrRight, recoilXSpeed);
                    Instantiate(slashEffect, SideAttackTransform);
                }
                else if (yAxis > 0)
                {
                    Hit(UpAttackTransform, UpAttackArea, ref pState.recoilingY,Vector2.up, recoilYSpeed);
                    SlashEffectAtAngle(slashEffect, 80, UpAttackTransform);
                }
                else if (yAxis < 0 && !Grounded())
                {
                    Hit(DownAttackTransform, DownAttackArea, ref pState.recoilingY,Vector2.down, recoilYSpeed);
                    SlashEffectAtAngle(slashEffect, -90, DownAttackTransform);
                }
            }
    
        }
        void Hit(Transform _attackTransform, Vector2 _attackArea, ref bool _recoilBool,Vector2 _recoilDir, float _recoilStrength)
        {
            Collider2D[] objectsToHit = Physics2D.OverlapBoxAll(_attackTransform.position, _attackArea, 0, attackableLayer);
            List<Enemy> hitEnemies = new List<Enemy>();
    
            if (objectsToHit.Length > 0)
            {
                _recoilBool = true;
            }
            for (int i = 0; i < objectsToHit.Length; i++)
            {
                Enemy e = objectsToHit[i].GetComponent<Enemy>();
                if (e && !hitEnemies.Contains(e))
                {
                    e.EnemyHit(damage, _recoilDir, _recoilStrength);
                    hitEnemies.Add(e);
    
                    if (objectsToHit[i].CompareTag("Enemy"))
                    {
                        Mana += manaGain;
                    }
                }
            }
        }
        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);
        }
        void Recoil()
        {
            if (pState.recoilingX)
            {
                if (pState.lookingRight)
                {
                    rb.velocity = new Vector2(-recoilXSpeed, 0);
                }
                else
                {
                    rb.velocity = new Vector2(recoilXSpeed, 0);
                }
            }
    
            if (pState.recoilingY)
            {
                rb.gravityScale = 0;
                if (yAxis < 0)
                {
                    rb.velocity = new Vector2(rb.velocity.x, recoilYSpeed);
                }
                else
                {
                    rb.velocity = new Vector2(rb.velocity.x, -recoilYSpeed);
                }
                airJumpCounter = 0;
            }
            else
            {
                rb.gravityScale = gravity;
            }
    
            //stop recoil
            if (pState.recoilingX && stepsXRecoiled < recoilXSteps)
            {
                stepsXRecoiled++;
            }
            else
            {
                StopRecoilX();
            }
            if (pState.recoilingY && stepsYRecoiled < recoilYSteps)
            {
                stepsYRecoiled++;
            }
            else
            {
                StopRecoilY();
            }
    
            if (Grounded())
            {
                StopRecoilY();
            }
        }
        void StopRecoilX()
        {
            stepsXRecoiled = 0;
            pState.recoilingX = false;
        }
        void StopRecoilY()
        {
            stepsYRecoiled = 0;
            pState.recoilingY = false;
        }
    
        public void TakeDamage(float _damage)
        {
            if (pState.alive)
            {
                Health -= Mathf.RoundToInt(_damage);
                if (Health <= 0)
                {
                    Health = 0;
                    StartCoroutine(Death());
                }
                else
                {
                    StartCoroutine(StopTakingDamage());
                }
            }
        }
    
        IEnumerator StopTakingDamage()
        {
            pState.invincible = true;
            GameObject _bloodSpurtParticles = Instantiate(bloodSpurt, transform.position, Quaternion.identity);
            Destroy(_bloodSpurtParticles, 1.5f);
            anim.SetTrigger("TakeDamage");
            yield return new WaitForSeconds(1f);
            pState.invincible = false;
        }
        IEnumerator Flash()
        {
            sr.enabled = !sr.enabled;
            canFlash = false;
            yield return new WaitForSeconds(0.1f);
            canFlash = true;
        }
        void FlashWhileInvincible()
        {
            if (pState.invincible && !pState.cutscene)
            {
                if (Time.timeScale > 0.2 && canFlash)
                {
                    StartCoroutine(Flash());
                }
            }
            else
            {
                sr.enabled = true;
            }
        }
        void RestoreTimeScale()
        {
            if (restoreTime)
            {
                if (Time.timeScale < 1)
                {
                    Time.timeScale += Time.unscaledDeltaTime * restoreTimeSpeed;
                }
                else
                {
                    Time.timeScale = 1;
                    restoreTime = false;
                }
            }
        }
        public void HitStopTime(float _newTimeScale, int _restoreSpeed, float _delay)
        {
            restoreTimeSpeed = _restoreSpeed;
            if (_delay > 0)
            {
                StopCoroutine(StartTimeAgain(_delay));
                StartCoroutine(StartTimeAgain(_delay));
            }
            else
            {
                restoreTime = true;
            }
            Time.timeScale = _newTimeScale;
        }
        IEnumerator StartTimeAgain(float _delay)
        {
            yield return new WaitForSecondsRealtime(_delay);
            restoreTime = true;
        }
    
        IEnumerator Death()
        {
            pState.alive = false;
            Time.timeScale = 1f;
            GameObject _bloodSpurtParticles = Instantiate(bloodSpurt, transform.position, Quaternion.identity);
            Destroy(_bloodSpurtParticles, 1.5f);
            anim.SetTrigger("Death");
    
            yield return new WaitForSeconds(0.9f);
            StartCoroutine(UIManager.Instance.ActivateDeathScreen());
    
        }
    
        public void Respawned()
        {
            if (!pState.alive)
            {
                pState.alive = true;
                halfMana = true;
                UIManager.Instance.SwitchMana(UIManager.ManaState.halfMana);
                Mana = 0;
                Health = maxHealth;
                anim.Play("Player_Idle");
            }
        }
    
        public int Health
        {
            get { return health; }
            set
            {
                if (health != value)
                {
                    health = Mathf.Clamp(value, 0, maxHealth);
    
                    if (onHealthChangedCallback != null)
                    {
                        onHealthChangedCallback.Invoke();
                    }
                }
            }
        }
        void Heal()
        {
            if (Input.GetButton("Cast/Heal") && castOrHealTimer > 0.05f && Health < maxHealth && Mana > 0 && Grounded() && !pState.dashing)
            {
                pState.healing = true;
                anim.SetBool("Healing", true);
    
                //healing
                healTimer += Time.deltaTime;
                if (healTimer >= timeToHeal)
                {
                    Health++;
                    healTimer = 0;
                }
    
                //drain mana
                Mana -= Time.deltaTime * manaDrainSpeed;
            }
            else
            {
                pState.healing = false;
                anim.SetBool("Healing", false);
                healTimer = 0;
            }
        }
        float Mana
        {
            get { return mana; }
            set
            {
                //if mana stats change
                if (mana != value)
                {
                    if (!halfMana)
                    {
                        mana = Mathf.Clamp(value, 0, 1);
                    }
                    else
                    {
                        mana = Mathf.Clamp(value, 0, 0.5f);
                    }
                    manaStorage.fillAmount = Mana;
                }
            }
        }
    
        void CastSpell()
        {
            if (Input.GetButtonUp("Cast/Heal") && castOrHealTimer <= 0.05f && timeSinceCast >= timeBetweenCast && Mana >= manaSpellCost)
            {
                pState.casting = true;
                timeSinceCast = 0;
                StartCoroutine(CastCoroutine());
            }
            else
            {
                timeSinceCast += Time.deltaTime;
            }
    
            if (Grounded())
            {
                //disable downspell if on the ground
                downSpellFireball.SetActive(false);
            }
            //if down spell is active, force player down until grounded
            if (downSpellFireball.activeInHierarchy)
            {
                rb.velocity += downSpellForce * Vector2.down;
            }
        }
        IEnumerator CastCoroutine()
        {
            anim.SetBool("Casting", true);
            yield return new WaitForSeconds(0.15f);
    
            //side cast
            if (yAxis == 0 || (yAxis < 0 && Grounded()))
            {
                GameObject _fireBall = Instantiate(sideSpellFireball, SideAttackTransform.position, Quaternion.identity);
    
                //flip fireball
                if (pState.lookingRight)
                {
                    _fireBall.transform.eulerAngles = Vector3.zero; // if facing right, fireball continues as per normal
                }
                else
                {
                    _fireBall.transform.eulerAngles = new Vector2(_fireBall.transform.eulerAngles.x, 180);
                    //if not facing right, rotate the fireball 180 deg
                }
                pState.recoilingX = true;
            }
    
            //up cast
            else if (yAxis > 0)
            {
                Instantiate(upSpellExplosion, transform);
                rb.velocity = Vector2.zero;
            }
    
            //down cast
            else if (yAxis < 0 && !Grounded())
            {
                downSpellFireball.SetActive(true);
            }
    
            Mana -= manaSpellCost;
            yield return new WaitForSeconds(0.35f);
            anim.SetBool("Casting", false);
            pState.casting = false;
        }
    
        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 (jumpBufferCounter > 0 && coyoteTimeCounter > 0 && !pState.jumping)
            {
                rb.velocity = new Vector3(rb.velocity.x, jumpForce);
    
                pState.jumping = true;
            }
    
            if (!Grounded() && airJumpCounter < maxAirJumps && Input.GetButtonDown("Jump"))
            {
                pState.jumping = true;
    
                airJumpCounter++;
    
                rb.velocity = new Vector3(rb.velocity.x, jumpForce);
            }
    
            if (Input.GetButtonUp("Jump") && rb.velocity.y > 3)
            {
                pState.jumping = false;
    
                rb.velocity = new Vector2(rb.velocity.x, 0);
            }
    
            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 = jumpBufferCounter - Time.deltaTime * 10;
            }
        }
    }</code>

    game manager

    <code>using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class GameManager : MonoBehaviour
    {
        public string transitionedFromScene;
    
        public Vector2 platformingRespawnPoint;
        public Vector2 respawnPoint;
        [SerializeField] Lantern lantern;
    
        public static GameManager Instance { get; private set; }
        private void Awake()
        {
            if(Instance != null && Instance != this)
            {
                Destroy(gameObject);
            }
            else
            {
                Instance = this;
            }
            DontDestroyOnLoad(gameObject);
            lantern = FindObjectOfType<Lantern>();
        }
        public void RespawnPlayer()
        {
            if (lantern != null) {
                if (lantern.interacted)
                {
                    respawnPoint = lantern.transform.position;
                }
                else
                {
                    respawnPoint = platformingRespawnPoint;
                }
            }
            else
            {
                respawnPoint = platformingRespawnPoint;
            }
    
            PlayerController.Instance.transform.position = respawnPoint + new Vector2(0, 2f); ;
            // StartCoroutine(UIManager.Instance.DeactivateDeathScreen());
    
            Rigidbody2D rb = PlayerController.Instance.GetComponent<Rigidbody2D>();
            if (rb != null)
            {
                rb.velocity = Vector2.zero;
            }
    
            UIManager.Instance.StartDeactivateDeathScreenCoroutine();
            PlayerController.Instance.Respawned();
        }
    
    }
    </code>

    scene fader

    <code>using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.SceneManagement;
    
    public class SceneFader : MonoBehaviour
    {
        [SerializeField] private float fadeTime;
    
        private Image fadeOutUIImage;
    
        public enum FadeDirection
        {
            In, 
            Out
        }
    
        // Start is called before the first frame update
        private void Awake()
        {
            fadeOutUIImage = GetComponent<Image>();
        }
    
        // Update is called once per frame
        void Update()
        {
    
        }
    
        public IEnumerator Fade(FadeDirection _fadeDirection)
        {
            float _alpha = _fadeDirection == FadeDirection.Out ? 1 : 0;
            float _fadeEndValue = _fadeDirection == FadeDirection.Out ? 0 : 1;
    
            if(_fadeDirection == FadeDirection.Out)
            {
                while(_alpha >= _fadeEndValue)
                {
                    SetColorImage(ref _alpha, _fadeDirection);
    
                    yield return null;
                }
    
                fadeOutUIImage.enabled = false;
            }
            else
            {
                fadeOutUIImage.enabled = true;
    
                while (_alpha <= _fadeEndValue)
                {
                    SetColorImage(ref _alpha, _fadeDirection);
    
                    yield return null;
                }
            }
        }
    
        public IEnumerator FadeAndLoadScene(FadeDirection _fadeDirection, string _sceneToLoad)
        {
            fadeOutUIImage.enabled = true;
    
            yield return Fade(_fadeDirection);
    
            SceneManager.LoadScene(_sceneToLoad);
        }
    
        void SetColorImage(ref float _alpha, FadeDirection _fadeDirection)
        {
            fadeOutUIImage.color = new Color(fadeOutUIImage.color.r, fadeOutUIImage.color.g, fadeOutUIImage.color.b, _alpha);
    
            _alpha += Time.deltaTime * (1 / fadeTime) * (_fadeDirection == FadeDirection.Out ? -1 : 1);
        }
    }
    </code>
    #15693
    Sanket Pise
    Level 4
    Participant
    Helpful?
    Up
    0
    ::
    View post on imgur.com
    This is how it looks
    #15698
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    Can you help set up some print/debug logs to see whether things are triggering as intended?

    Also, if possible, can you try getting a video of the bug happening?

    For the prints, can you add them here:

    UI Manager:

        public void StartDeactivateDeathScreenCoroutine()
        {
            print("Called by GameManager");
            StartCoroutine(DeactivateDeathScreen());
            print("Activating Deactivate");
        }
    
        public IEnumerator DeactivateDeathScreen()
        {
            print("Activated");
            yield return new WaitForSeconds(0.5f);
            deathScreen.SetActive(false);
            print("Death screen off");
            StartCoroutine(sceneFader.Fade(SceneFader.FadeDirection.Out));
        }

    and GameManager:

        public void RespawnPlayer()
        {
            if (lantern != null) {
                if (lantern.interacted)
                {
                    respawnPoint = lantern.transform.position;
                }
                else
                {
                    respawnPoint = platformingRespawnPoint;
                }
            }
            else
            {
                respawnPoint = platformingRespawnPoint;
            }
    
            PlayerController.Instance.transform.position = respawnPoint + new Vector2(0, 2f); ;
            // StartCoroutine(UIManager.Instance.DeactivateDeathScreen());
    
            Rigidbody2D rb = PlayerController.Instance.GetComponent<Rigidbody2D>();
            if (rb != null)
            {
                rb.velocity = Vector2.zero;
            }
    
            print("Respawn calling UIManager");
            UIManager.Instance.StartDeactivateDeathScreenCoroutine();
            print("Called UI");
            PlayerController.Instance.Respawned();
        }
    #15700
    Sanket Pise
    Level 4
    Participant
    #15702
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    From the video, we can say that the code is working as intended when respawning. There are no errors that show that the code was unable to find the death screen nor turn it off.

    So, could you check that both the Death text and respawn button is attached to the death screen as children?

    It’s a possibility that the reason they are on the screen is because they are not attached to the deathscreen as a child. One way you can also check this is by seeing if you can press the respawn button despite the player not having died yet.


    Aside from that, you take a concerning amount of time to revive in the first place, considering the death screen is supposed to fade in by around 2 seconds after you die rather than that 6-7 seconds it took.

    In any case, can you show your Canvas’ Hierarchy and check that it’s parented like this?

    #15712
    Sanket Pise
    Level 4
    Participant
    Helpful?
    Up
    0
    ::

    I checked my hierarchy as mentioned and I had made death screen the child of scene fader I fixed it,like the hierarchy you provided and the death screen no longer remains on the screen all the time but now when the player dies I just get a black screen no death screen(with respawn button appears)

    View post on imgur.com

    video of new issue is provided too

    View post on imgur.com
    #15713
    Sanket Pise
    Level 4
    Participant
    Helpful?
    Up
    0
    ::
    View post on imgur.com
    video of new bug
    #15717
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    What you want to do is to make “Death Screen” a child of “Canvas”, not a prefab on it’s own.

    Then, disable the “Death Screen” that you placed into the “Canvas”, only the “Death Screen” itself and not the children.


    Finally, make sure you add “Death Screen” into your UIManager.cs in the “Canvas” inspector.

    #15721
    Sanket Pise
    Level 4
    Participant
    Helpful?
    Up
    0
    ::

    I added “Death Screen” to the Canvas,but I dont know how to disable only “Death Screen” and not its children whenever parent is disabled whole prefab is disabled. could you tell me the step for that

    View post on imgur.com
    updated hierarchy

    I have already added “Death Screen” into UIManager.cs in the “Canvas” inspector.

    View post on imgur.com

    image of UIManager.cs

    #15724
    Sanket Pise
    Level 4
    Participant
    Helpful?
    Up
    0
    ::

    I made the changes and disabled the parent and kept children active, yet a black screen appears after the player death and no death screen appears

    View post on imgur.com

    black screen

    #15725
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    As a tip, since you know that your death screen doesn’t appear, always leave the canvas hierarchy open in the scene when testing to know whether it’s active or not.

    As for Deactivating “Death Screen”, you just need to uncheck the box next to the name of the “Death Screen”, but leave the children of it checked.


    Next, i think the reason it’s not appearing may be that we’ve put the “Death Screen” above the “SceneFader” in the Canvas Hierarchy. [Putting above the hierarchy means it’ll appear below the “Scenefader” in the game.]

    So try putting the Death Screen here:

    Directly below the “SceneFader” [Not as a child] While inside the Canvas.

    #15728
    Sanket Pise
    Level 4
    Participant
    Helpful?
    Up
    0
    ::

    I did everything as told by you, but unfortunately the problem still persists, The death screen does not come no matter what I do below is the video of the game running

    View post on imgur.com
    black screen instead of death screen
    #15729
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    Can you try, adding the “Death Screen” to the Prefab of the Canvas, then reapplying the death screen that’s in the canvas to the UIManager of said prefab?

    I think there’s a possibility that the “Death Screen” in the UI Manager is a “Death Screen” prefab, and not the “Death Screen itself.


    Next can you also test something by manually activating the Death Screen to see if it’s functional when activated.


    Can you also put up the print logs in my initial comment before to see if everything is working as intended?

    #15730
    Sanket Pise
    Level 4
    Participant
    Helpful?
    Up
    0
    ::

    It worked!!! thank you soo much

    The death screen arrives a bit late for my liking,which setting do I have to change to decrease the time?

    #15731
    Joseph Tang
    Level 13
    Moderator
    Helpful?
    Up
    0
    ::

    Could you check something? Can you go to your SceneFader game object, the one with the SceneFader script on it, and check what the FadeTime is set to?

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

Go to Login Page →


Advertisement below: