Forum begins after the advertisement:


Search Results for 'fader'

Home Forums Search Search Results for 'fader'

Viewing 15 results - 16 through 30 (of 77 total)
  • Author
    Search Results
  • #15824

    In reply to: [Part 7] Map problem

    Terence
    Keymaster

    Does it fix the issue if you uncheck Raycast Target on Scene Fader?

    #15822

    In reply to: [Part 7] Map problem

    MI NI
    Bronze Supporter (Patron)

    My Scene Fader has raycast target checked

    #15821

    In reply to: [Part 7] Map problem

    Joseph Tang
    Moderator

    Have you checked if you removed the raycast target from your Scene Fader just in case?

    #15808

    In reply to: [Part 7] Map problem

    Joseph Tang
    Moderator

    1. For your Pause menu freezing the game, the only thing you need to do is to ensure your resume game is called. In other words, making sure you can press the resume button.

    Thus, let’s first see why your button isn’t able to be pressed. For this, I’m not too sure, however can you check out point 2b. of this article, turning off the raycast targetting of the “Scene Fader”:

    How to fix an unclickable Button in Unity’s Canvas UI system

    This is because it’s the only game object in the scene that could possibly be blocking the pause menu.

    Furthermore, I suggest you allow pressing the escape button again to unpause the game anyways.


    2. For your Pause, Map and Inventory not appearing. This is because you put all three into the GameManager.cs. The problem with that is due to the fact that the code we used for loading the game’s map, scenes and boss data is all not fully correct.

    Whenever we load the game’s data, we search for whether their file paths exists. but we forgot to check if there’s anything inside the file. Because of this, we will always be returned with an error saying that there was no data to be retrieved from the filepaths.
    Whenever your code encounters an error, the script will be paused there. Thus, since we called a lot of Load Data methods in the GameManager.cs Awake() method, our GameManager.cs encountered errors when we reset the game’s data and stopped functioning for the Update() method to fire.
    Thereby causing your map, inventory and pause menu unable to open.

    The fix is pretty simple, we just need to add the line that was commented out in your LoadPlayerData(), into each of the Load methods:

    GameManager.cs

        public void LoadPlayerData()
        {
            //string savePath = Application.persistentDataPath + "/save.player.data";
            //if (File.Exists(savePath) && new FileInfo(savePath).Length > 0) 
            if(File.Exists(Application.persistentDataPath + "/save.player.data"))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.player.data")))
                {
                    ....
                }
                Debug.Log("load player data");
            }
            else
            {
             ....
            }
        }
    
        public void LoadSceneData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.scenes.data") && new FileInfo(Application.persistentDataPath + "/save.scenes.data").Length > 0))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.scenes.data")))
                {
                    ...
                }
            }
            else
            {
                Debug.Log(sceneNames);
                Debug.Log("File doesnt exist");
                sceneNames = new HashSet();
            }
        }
    
        public void LoadMapData()
        {
            if (File.Exists(Application.persistentDataPath + "/save.maps.data") && new FileInfo(Application.persistentDataPath + "/save.maps.data").Length > 0))
            {
                using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.maps.data")))
                {
                    ...
                }
            }
            else
            {
                Debug.Log("File doesnt exist");
                mapNames = new HashSet();
            }
        }

    What this does is it checks for the contents of each file path first and sees if there is anything inside. If there is nothing inside, then we fire the else statement that the file doesnt exist. The reason we have to do this is because of our SaveData.cs Initialize() creating the file paths even if we deleted them with the reset data.

    has upvoted this post.
    #15733
    Joseph Tang
    Moderator

    Hmm, yea this seems weird to me.

    Well, I’m not confident in fixing this issue as i don’t know why your scene fader takes so long to come out.

    However, let’s try some things.


    First, can you try swapping out all WaitForSeconds() to WaitForSecondsRealtime() in the following methods and scripts:

    Player.cs

        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());
        }

    UIManager.cs

        public IEnumerator ActivateDeathScreen()
        {
            yield return new WaitForSeconds(0.8f);
            StartCoroutine(sceneFader.Fade(SceneFader.FadeDirection.In));
    
            yield return new WaitForSeconds(0.8f);
            deathScreen.SetActive(true);
        }

    If this works, it might mean that when you died, the game slowed down/time stopped.


    Second, you can try changing the code in SceneFader to this:

    SceneFader.cs

        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) 0.2f * (_fadeDirection == FadeDirection.Out ? -1 : 1);
        }

    Otherwise, let me think about some other possible reasons why your scenefader is so late.

    #15732
    Sanket Pise
    Participant

    View post on imgur.com


    here is the fade time for the Screen Fader

    #15731
    Joseph Tang
    Moderator

    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?

    #15725
    Joseph Tang
    Moderator

    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.

    #15712
    Sanket Pise
    Participant

    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

    #15698
    Joseph Tang
    Moderator

    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();
            if (rb != null)
            {
                rb.velocity = Vector2.zero;
            }
    
            print("Respawn calling UIManager");
            UIManager.Instance.StartDeactivateDeathScreenCoroutine();
            print("Called UI");
            PlayerController.Instance.Respawned();
        }
    Sanket Pise
    Participant

    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

    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));
        }
    
    }

    Player Controller

    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;
            }
        }
    }

    game manager

    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();
        }
    
    }
    

    scene fader

    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);
        }
    }
    
    #15639
    MI NI
    Bronze Supporter (Patron)

    I think I have a big problem, I can’t pause the game while I’m porting the switch map to GameManager, but I decided to finish the switch map first, and then make the time freeze, but after I port the code to GameManager my map Something went wrong, it was completely invisible, I couldn’t even see the map from the Scene screen, and the SceneTransition suddenly had problems.
    I restored the map part to PlayerController to no avail, it is still invisible.

    Update, I have no problem with SceneTransition. I was too nervous about the Map problem and accidentally turned off SceneFader without enabling it.

    update again, my map disappears as if I accidentally adjusted it to Alpha value. So the above problem is solved,

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    public class GameManager : MonoBehaviour
    {
        public string transitionedFromScene;  //儲存前一個場景
    
        public Vector2 platformingRespawnPoint; //重生點
        public Vector2 respawnPoint;
        [SerializeField] SavePoint savePoint;
    
        [SerializeField] private FadeUI pauseMenu;
        [SerializeField] private FadeUI mapPause;
        [SerializeField] private float fadeTime;
        public bool gameIsPaused;
        //public bool Resumed = false;
    
        bool openMap = false;
    
        public static GameManager Instance { get; private set; }
        private void Awake()
        {
            SaveData.Instance.Initialize();
    
            if(Instance != null && Instance != this)
            {
                Destroy(gameObject);
            }
            else
            {
                Instance = this;
            }
    
            SaveScene();
    
            DontDestroyOnLoad(gameObject);
    
            SaveData.Instance.LoadSceneData();
    
            SaveData.Instance.LoadMapData();
    
            savePoint = FindObjectOfType<SavePoint>();
    
        }
    
        private void Update()
        {
    
            if (Input.GetKeyDown(KeyCode.Escape) && !gameIsPaused)
            {
                pauseMenu.FadeUIIn(fadeTime);
                Time.timeScale = 0;
                GameManager.Instance.gameIsPaused = true;
            }
            
            if (Input.GetButtonDown("Map") && !openMap)
            {
                openMap = true;
            }
            else if (Input.GetButtonDown("Map") && openMap)
            {
                openMap = false;
            }
        }
        
        public void ToggleMap()
        {
            if (openMap)
            {
                //mapPause.FadeUIIn(fadeTime);
                //Time.timeScale = 0;
                //GameManager.Instance.gameIsPaused = true;
                UIManager.Instance.mapHandler.SetActive(true);
            }
            else
            {
                //mapPause.FadeUIOut(fadeTime);
                //UnpauseGame();
                UIManager.Instance.mapHandler.SetActive(false);
            }
        }
        
        public void SaveGame()
        {
            SaveData.Instance.SavePlayerData();
        }
    
        public void UnpauseGame()
        {
            //Resumed = true;
            Time.timeScale = 1;
            GameManager.Instance.gameIsPaused = false; //沒有正確銷毀gamemanager 導致需要加GameManager.Instance
            Debug.Log(gameIsPaused);
        }
    
        public void SaveScene()
        {
            //獲取當前場景名稱
            string currentSceneName = SceneManager.GetActiveScene().name;
            SaveData.Instance.sceneName.Add(currentSceneName);
            SaveData.Instance.SaveSceneData();
    
            //Debug.Log("saved" + currentSceneName);
        }
    
        public void RespawnPlayer()
        {
            SaveData.Instance.LoadSavePoint();
    
            if(SaveData.Instance.savePointSceneName != null) //載入重生點的場景
            {
                print(SaveData.Instance.savePointSceneName + "by GameManager");
                SceneManager.LoadScene(SaveData.Instance.savePointSceneName);
            }
    
            if(SaveData.Instance.savePointPos != null) //設定重生位置為savePoint
            {
                respawnPoint = SaveData.Instance.savePointPos;
            }
            else
            {
                respawnPoint = platformingRespawnPoint;
            }
    
            PlayerController.Instance.transform.position = respawnPoint;
    
            StartCoroutine(UIManager.Instance.DeactiveateDeathScreen()); //重生點淡入淡出
            PlayerController.Instance.Respawned(); //使角色重生
        }
    }
    

    PlayController.cs Add GameManager.Instance.ToggleMap(); to PlayerController

    void Update()
        {
            if (GameManager.Instance.gameIsPaused) return;
    
            RestoreTimeScale();
    
            if (pState.cutscene) return;
            if (pState.alive)
            {
                GetInputs();
                //ToggleMap();
                GameManager.Instance.ToggleMap();
                ToggleInventory();
            }
            UpdateJumpVariables();
            RestoreTimeScale();
            UpdateCameraYDampForPlayerFall();
    
            if (pState.alive)
            {
                Heal();
            }
    
            if (pState.dashing || pState.healing) return;
    
            if (pState.alive)
            {
                if (!isWallJumping)
                {
                    Flip();
                    Move();
                    Jump();
                }
                if (unlockWallJump)
                {
                    WallSlide();
                    WallJump();
                }
                if (unlockDash)
                {
                    StartDash();
                }
    
                Attack();
                CastSpell();
            }
            FlashWhileInvincible();
        }
    #15498
    reeean
    Participant

    ISSUE RESOLVED

    I UNCHECKED THE SCENEFADER BY ACCIDENT

    P.S I LOVE YOU GUYS, LOVE ME

    reeean
    Participant

    When I preview my game this error comes from console:
    NullReferenceException: Object reference not set to an instance of an object
    SceneTransition.Start () (at Assets/SceneTransition.cs:27)

    When I touch my Scene Transition, it does not transition me into my next scene, instead the player walks in one direction and the console give me this error.
    NullReferenceException: Object reference not set to an instance of an object
    SceneTransition.OnTriggerEnter2D (UnityEngine.Collider2D _other) (at Assets/SceneTransition.cs:40)

    This my scene transition code:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    public class SceneTransition : MonoBehaviour
    {
        // Start is called before the first frame update
    
        [SerializeField] private string transitionTo;
    
        [SerializeField] private Transform startPoint;
    
        [SerializeField] private Vector2 exitDirection;
    
        [SerializeField] private float exitTime;
    
        private void Start()
        {
            if(GameManager.Instance.transitionedFromScene == transitionTo)
            {
                PlayerController.Instance.transform.position = startPoint.position;
    
                StartCoroutine(PlayerController.Instance.WalkIntoNewScene(exitDirection, exitTime));
            }
    
            StartCoroutine(UIManager.Instance.sceneFader.Fade(SceneFader.FadeDirection.Out));
    
        }
    
        private void OnTriggerEnter2D(Collider2D _other)
        {
            if(_other.CompareTag("Player"))
            {
                GameManager.Instance.transitionedFromScene = SceneManager.GetActiveScene().name;
    
                PlayerController.Instance.pState.cutscene = true;
                PlayerController.Instance.pState.invincible = true;
    
                StartCoroutine(UIManager.Instance.sceneFader.FadeAndLoadScene(SceneFader.FadeDirection.In, transitionTo));
            }
        }
    }

    View post on imgur.com

    Hello, currently I’m finishing part 9 of your tutorial and throughout following it I’ve ran into a few issues I couldn’t find answers for here on forum for and also got a few questions myself.

    1. So the first thing is an error I’m receiving in the console as soon as I hit play for the first time after opening the project.


    My UIManager script that the error mentions looks like that:

    using System.Collections;
    using UnityEngine;
    
    public class UIManager : MonoBehaviour
    {
        public static UIManager Instance;
        public SceneFader sceneFader;
        [SerializeField] GameObject deathScreen;
        public GameObject mapHandler;
        public GameObject inventory;
    
        private void Awake()
        {
            if (Instance != null && Instance != this) 
            {
                Destroy(gameObject);
            }
            else
            {
                Instance = this;
            }
            <strong>DontDestroyOnLoad(gameObject);</strong>
    
            sceneFader = GetComponentInChildren<SceneFader>();
        }
    
        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 IEnumerator DeactivateDeathScreen()
        {
            yield return new WaitForSeconds(0.5f);
            deathScreen.SetActive(false);
            StartCoroutine(sceneFader.Fade(SceneFader.FadeDirection.Out));
        }
    }
    

    2. My bat enemy gets stunned even when I set stun duration to 0 and he also gets knockbacked and stunned after his hp reaches 0 (which I believe shouldn’t happen?)

    Bat problem

    Here’s my bat script:

    using UnityEngine;
    
    public class Bat : Enemy
    {
        [SerializeField] private float chaseDistance;
        [SerializeField] private float stunDuration;
        float timer;
    
        protected override void Start()
        {
            base.Start();
            ChangeState(EnemyStates.Bat_Idle);
        }
    
        protected override void Update()
        {
            base.Update();
            if (!PlayerController.Instance.pState.alive)
            {
                ChangeState(EnemyStates.Bat_Idle);
            }
        }
    
        protected override void UpdateEnemyStates()
        {
            float distance = Vector2.Distance(transform.position, PlayerController.Instance.transform.position);
    
            switch (GetCurrentEnemyState)
            {
                case EnemyStates.Bat_Idle:
                    rb.velocity = new Vector2(0, 0);
                    if (distance < chaseDistance)
                    {
                        ChangeState(EnemyStates.Bat_Chase);
                    }
                    break;
    
                case EnemyStates.Bat_Chase:
                    rb.MovePosition(Vector2.MoveTowards(transform.position, PlayerController.Instance.transform.position, Time.deltaTime * speed));
                    FlipBat();
                    if (distance > chaseDistance)
                    {
                        ChangeState(EnemyStates.Bat_Idle);
                    }
                    break;
    
                case EnemyStates.Bat_Stunned:
                    timer += Time.deltaTime;
                    if (timer >= stunDuration)
                    {
                        ChangeState(EnemyStates.Bat_Idle);
                        timer = 0;
                    }
    
                    break;
    
                case EnemyStates.Bat_Death:
                    Death(Random.Range(5,10));
                    break;
    
            }
        }
    
        public override void EnemyHit(float damageDealt, Vector2 hitDirection, float hitForce)
        {
            base.EnemyHit(damageDealt, hitDirection, hitForce);
    
            if (health > 0)
            {
                ChangeState(EnemyStates.Bat_Stunned);
            }
            else
            {
                ChangeState(EnemyStates.Bat_Death);
            }
        }
    
        protected override void Death(float destroyTime)
        {
            rb.gravityScale = 12;
            base.Death(destroyTime);
        }
    
        protected override void ChangeCurrentAnimation()
        {
            anim.SetBool("Idle", GetCurrentEnemyState == EnemyStates.Bat_Idle);
            anim.SetBool("Chase", GetCurrentEnemyState == EnemyStates.Bat_Chase);
            anim.SetBool("Stunned", GetCurrentEnemyState == EnemyStates.Bat_Stunned);
    
            if(GetCurrentEnemyState == EnemyStates.Bat_Death)
            {
                anim.SetTrigger("Death");
                int LayerIgnorePlayer = LayerMask.NameToLayer("Ignore Player");
                gameObject.layer = LayerIgnorePlayer;
            }
        }
    
        void FlipBat()
        {
            if(PlayerController.Instance.transform.position.x < transform.position.x)
            {
                sr.flipX = true;
            }
            else
            {
                sr.flipX = false;
            }
        }
    
    }
    

    3. My player jumping method seems to be malfunctioning as sometimes when I barely tap jump button, the character jumps very high as shown in the video below:

    Broken jumping

    My jumping method:

    private void Jump()
    {
        if (!pState.jumping && jumpBufferCounter > 0 && coyoteTimeCounter > 0)
        {
            rb.velocity = new Vector3(rb.velocity.x, jumpForce);
            pState.jumping = true;
        }
        if (!IsGrounded() && airJumpCounter < maxAirJumps && Input.GetButtonDown("Jump") && unlockedDoubleJump)
        {
            pState.jumping = true;
    
            airJumpCounter++;
    
            rb.velocity = new Vector3(rb.velocity.x, jumpForce);
        }
    
        if (Input.GetButtonUp("Jump") && rb.velocity.y > 3)
        {
            rb.velocity = new Vector2(rb.velocity.x, 0);
    
            pState.jumping = false;
        }
    
        rb.velocity = new Vector2(rb.velocity.x, Mathf.Clamp(rb.velocity.y, -maxFallingSpeed, rb.velocity.y));
        anim.SetBool("Jumping", !IsGrounded());
    }

    4. Walljumping seems to be working as intended when the wall I’m walljumping on is on the right side, while when I’m walljumping on left-side wall it’s working in a wrong way

    Weird walljumping

    My walljumping method:

    private void WallJump()
    {
        if (isWallSliding)
        {
            isWallJumping = false;
            wallJumpingDirection = !pState.lookingRight ? 1: -1;
            CancelInvoke(nameof(StopWallJumping));
        }
    
        if (Input.GetButtonDown("Jump") && isWallSliding)
        {
            isWallJumping = true;
            rb.velocity = new Vector2(wallJumpingDirection * wallJumpingPower.x, wallJumpingPower.y);
            dashed = false;
            airJumpCounter = 0;
    
            pState.lookingRight = !pState.lookingRight;
            transform.eulerAngles = new Vector2(transform.eulerAngles.x, 180);
    
            Invoke(nameof(StopWallJumping), wallJumpingDuration);
        }
    }
    
    private void StopWallJumping()
    {
        isWallJumping = false;
        transform.eulerAngles = new Vector2(transform.eulerAngles.x, 0);
    
        rb.velocity = new Vector2(rb.velocity.x, 0);
    }

    5. If I put a transition to the other scene in a place that’s being “operated” by camera that is not the default one on the current scene, how do I make it so when I return from that other scene to the first scene, the active camera is set to the one where the scene transition is at (place that is not being “operated” by scene’s default camera)? You can see what I mean on the video below:

    Camera

    6. How to code the ability to unpause the game using esc key except only just pressing resume button with your mouse?

Viewing 15 results - 16 through 30 (of 77 total)

Advertisement below: