Forum begins after the advertisement:


Big heart in the center scene and save didn’t save the Max hearth

Home Forums Video Game Tutorial Series Creating a Metroidvania in Unity Big heart in the center scene and save didn’t save the Max hearth

Viewing 10 posts - 1 through 10 (of 10 total)
  • Author
    Posts
  • #16279
    pepecry
    Level 6
    Participant
    Helpful?
    Up
    0
    ::

    So i’m making the heart collection function. The fill, the save look good but after i collect 4 heart to increase the max health. It has increase but when I exit the game and replay it, the max health turn back to basic health. Same as saved with the Alter(bench). Another problem that is the heart showup in the center of the game like the image below
    Heart in the scene
    This heart only disapear after I take the heartshard. Update, I forgot to turn off the Canvas in the HeatShard. Still need your help to figure all why the max health didn’t save. Here is the script of the SaveData, HeartShard and increaseMaxHealth.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.IO;
    using UnityEngine.SceneManagement;
    
    [System.Serializable]
    public struct SaveData
    {
    
        public static SaveData Instance;
       public HashSet<string> sceneNames;
        public string altersceneName;
        public Vector2 alterPos;
        public int playerHealth;
        public int playerHeartShards;
        public float playerMana;
        public Vector2 playerPosition;
        public string lastScene;
    
        public bool playerUnlockWallJump;
        public void Initialize()
        {
            if (!File.Exists(Application.persistentDataPath + "/save.alter.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.alter.data"));
            }
            if (!File.Exists(Application.persistentDataPath + "/save.player.data"))
            {
                BinaryWriter writer = new BinaryWriter(File.Create(Application.persistentDataPath + "/save.player.data"));
            }
            if (sceneNames == null)
            {
                sceneNames = new HashSet<string>();
            }
        }
    
        public void saveAlter()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.alter.data")))
            {
                writer.Write(altersceneName);
                writer.Write(alterPos.x);
                writer.Write(alterPos.y);
            }
        }
        public void loadAlter()
        {
            if (File.Exists(Application.persistentDataPath + "/save.alter.data"))
            {
                using(BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.alter.data")))
                {
                    altersceneName = reader.ReadString();
                    alterPos.x = reader.ReadSingle();
                    alterPos.y = reader.ReadSingle();
                }
            }
        }
        public void savePlayerData()
        {
            using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.player.data")))
            {
                playerHealth = Move.Instance.Health;
                writer.Write(playerHealth);
                playerMana = Move.Instance.Mana;
                writer.Write(playerMana);
                playerUnlockWallJump = Move.Instance.unlockWalljump;
                writer.Write(playerUnlockWallJump);
                playerPosition = Move.Instance.transform.position;
                writer.Write(playerPosition.x);
                writer.Write(playerPosition.y);
                lastScene = SceneManager.GetActiveScene().name;
                writer.Write(lastScene);
                playerHeartShards = Move.Instance.heartShards;
                writer.Write(playerHeartShards);
            }
        }
        public void loadPlayerData()
        {
            if(File.Exists(Application.persistentDataPath + "/save.player.data"))
            {
                using(BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.player.data")))
                {
                    playerHealth = reader.ReadInt32();
                    playerMana = reader.ReadSingle();
                    playerUnlockWallJump = reader.ReadBoolean();
                    playerPosition.x = reader.ReadSingle();
                    playerPosition.y = reader.ReadSingle();
                    lastScene = reader.ReadString();
                    playerHeartShards = reader.ReadInt32();
                    SceneManager.LoadScene(lastScene);
                    Move.Instance.transform.position = playerPosition;
                    Move.Instance.Health = playerHealth;
                    Move.Instance.Mana = playerMana;  
                    Move.Instance.unlockWalljump = playerUnlockWallJump;
                    Move.Instance.heartShards = playerHeartShards;
                }
                Debug.Log("load player Data");
            }
            else
            {
                Debug.Log("File doesn't exist");
                Move.Instance.Health = Move.Instance.MaxHealth;
                Move.Instance.heartShards = 0;
                Move.Instance.Mana = 0.5f;
                Move.Instance.unlockWalljump = false;
            }
        }
    
    }
    
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    public class HeartShards : MonoBehaviour
    {
    
        public Image fill;
        public float targetFillAmount;
        public float lerpDuration= 1.5f;
        public float initalFillAmount;
        // Start is called before the first frame update
        void Start()
        {
            
        }
    
        // Update is called once per frame
        void Update()
        {
            
        }
    
        public IEnumerator LerpFill()
        {
            float elapseTime = 0f;
            while(elapseTime < lerpDuration)
            {
                elapseTime += Time.deltaTime;
                float t = Mathf.Clamp01(elapseTime / lerpDuration);
                float lerpFillAmount = Mathf.Lerp(initalFillAmount, targetFillAmount, t);
                fill.fillAmount = lerpFillAmount;
                yield return null;
            }
    
            fill.fillAmount = targetFillAmount;
            if(fill.fillAmount == 1)
            {
                Move.Instance.MaxHealth++;
                Move.Instance.onHealthChangedCallback();
                Move.Instance.heartShards = 0;
            }
        }
    }
    
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class IncreaseMaxHealth : MonoBehaviour
    {
        // Start is called before the first frame update
        [SerializeField] GameObject canvasUI;
        bool used;
        [SerializeField] HeartShards heartShards;
        void Start()
        {
            if (Move.Instance.MaxHealth >= Move.Instance.maxTotalHealth)
            {
                Destroy(gameObject);
            }
        }
    
        // Update is called once per frame
        private void OnTriggerEnter2D(Collider2D collision)
        {
            if (collision.CompareTag("Player") && !used)
            {
                used = true;
                StartCoroutine(ShowUI());
            }
        }
    
        IEnumerator ShowUI()
        {
            yield return new WaitForSeconds(0.5f);
            canvasUI.SetActive(true);
            heartShards.initalFillAmount = Move.Instance.heartShards * 0.25f;
            Move.Instance.heartShards++;
            heartShards.targetFillAmount = Move.Instance.heartShards * 0.25f;
            Move.Instance.unlockWalljump = true;
            StartCoroutine(heartShards.LerpFill());
    
            yield return new WaitForSeconds(2.5f);
            SaveData.Instance.savePlayerData();
            canvasUI.SetActive(false);
            Destroy(gameObject);
        }
    }
    

    And the heartcontainer as well

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine.UI;
    using UnityEngine;
    
    public class HeartController : MonoBehaviour
    {
        Move Player;
        private GameObject[] heartContainer;
        private Image[] heartFill;
        public Transform heartParent;
        public GameObject heartContainerPrefab;
        // Start is called before the first frame update
        void Start()
        {
            Player = Move.Instance;
            heartContainer = new GameObject[Move.Instance.maxTotalHealth];
            heartFill = new Image[Move.Instance.maxTotalHealth];
    
            Move.Instance.onHealthChangedCallback += updateHeartHUD;
            InstantiateHeartContainer();
            updateHeartHUD();
        }
    
        // Update is called once per frame
        void Update()
        {
            
        }
        void SetHeartContainer()
        {
            for (int i = 0; i < heartContainer.Length; i++)
            {
                if (i < Move.Instance.MaxHealth)
                {
                    heartContainer[i].SetActive(true);
                }
                else 
                {
                    heartContainer[i].SetActive(false);
                }
            }
        }
        void SetFilledHeart()
        {
            for (int i = 0; i < heartFill.Length; i++)
            {
                if (i < Move.Instance.Health)
                {
                    heartFill[i].fillAmount = 1;
                }
                else
                {
                    heartFill[i].fillAmount = 0;
                }
            }
        }
    
        void InstantiateHeartContainer()
        {
            for(int i = 0; i < Move.Instance.maxTotalHealth; i++)
            {
                GameObject temp = Instantiate(heartContainerPrefab);
                temp.transform.SetParent(heartParent, false);
                heartContainer[i] = temp;
                heartFill[i] = temp.transform.Find("heartfill").GetComponent<Image>();
            }
        }
        void updateHeartHUD()
        {
            SetHeartContainer();
            SetFilledHeart();
        }
    }
    

    Thank you guys

    #16287
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    Did you use the bench after picking up a max health pickup?

    #16288
    pepecry
    Level 6
    Participant
    Helpful?
    Up
    1
    ::

    Yes. I have. As you could see in the record. I have saved my character and the console has log out that
    max health record

    has upvoted this post.
    #16290
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    Put a debug message on your loadPlayerData function. Let’s check whether the values are correctly loaded:

        public void loadPlayerData()
        {
            if(File.Exists(Application.persistentDataPath + "/save.player.data"))
            {
                using(BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.player.data")))
                {
                    playerHealth = reader.ReadInt32();
                    playerMana = reader.ReadSingle();
                    playerUnlockWallJump = reader.ReadBoolean();
                    playerPosition.x = reader.ReadSingle();
                    playerPosition.y = reader.ReadSingle();
                    lastScene = reader.ReadString();
                    playerHeartShards = reader.ReadInt32();
                    SceneManager.LoadScene(lastScene);
                    Move.Instance.transform.position = playerPosition;
                    Move.Instance.Health = playerHealth;
                    Move.Instance.Mana = playerMana;  
                    Move.Instance.unlockWalljump = playerUnlockWallJump;
                    Move.Instance.heartShards = playerHeartShards;
                    print("Loaded position: " + playerPosition);
                    print("Loaded health: " + playerHealth);
                    print("Loaded mana: " + playerMana);
                    print("Loaded unlock wall jump: " + playerUnlockWallJump);
                    print("Loaded heart shards: " + playerHeartShards);
                }
                Debug.Log("load player Data");
            }
            else
            {
                Debug.Log("File doesn't exist");
                Move.Instance.Health = Move.Instance.MaxHealth;
                Move.Instance.heartShards = 0;
                Move.Instance.Mana = 0.5f;
                Move.Instance.unlockWalljump = false;
            }
        }
    #16291
    pepecry
    Level 6
    Participant
    Helpful?
    Up
    0
    ::

    So when the game start. the console show up this
    start console
    After I get 1 heartshard. And save. The game could save the heartShard like in the second pic
    after pickup a shard
    But then I get all the shard to have 1 additional hearth and then save, the game still load only 4 health just like the first picture. I also try to change the Health to health in savePlayerData and loadPlayerData but not working thought
    playerHealth = Move.Instance.health;
    Move.Instance.health = playerHealth;
    I will put the player controller here if you need

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using Unity.Mathematics;
    using UnityEditor.Tilemaps;
    using UnityEngine;
    using UnityEngine.UI;
    
    [RequireComponent(typeof(Rigidbody2D))]
    public class Move : MonoBehaviour
    {
        //animation and physic
        [Header("physic of player")]
        public Rigidbody2D rbd2;
        [SerializeField] public float speed = 2.0f;
        private float xAxis, yAxis;
        [SerializeField] private float jumpForce = 10;
        private int dbJumpCounter;
        [SerializeField] private int maxdbJump = 1;
        [Space(5)]
    
        [Header("Groundcheck setting")]
        [SerializeField] private Transform groundcheck;
        [SerializeField] private float groundchecky = 0.2f;
        [SerializeField] private float groundcheckx = 0.5f;
        [SerializeField] private LayerMask isground;
        Animator animator;
        [HideInInspector] public PlayerStateList playerStateList;
        [Space(5)]
    
        [Header("Coyotetime setting")]
        [SerializeField] private float coyoteTime = 0.1f;
        private float coyoteTimeCounter = 0;
        [Space(5)]
    
        [Header("Attacking setting")]
        [SerializeField] private float timeBetweenattck;
        [SerializeField] Transform sideAttackTransform, upAttackTransform, downAttackTransform;
        [SerializeField] Vector2 sideAttackArea, upAttackArea, downAttackArea;
        [SerializeField] LayerMask attackableLayer;
        [SerializeField] float playerDmg;
        private float timeSinceattk;
        bool attk = false;
        [Space(5)]
    
        [Header("Health Setting")]
        [SerializeField] public int health;
        [SerializeField] public int MaxHealth;
        [SerializeField] GameObject bloodSpurt;
        [SerializeField] float hitFlashspeed;
        public delegate void OnHealthChangedDelegate();
        [HideInInspector] public OnHealthChangedDelegate onHealthChangedCallback;
        [SerializeField] float timetoHeal;
        float healTimer;
        public int maxTotalHealth = 10;
        public int heartShards;
        [Space(5)]
    
        [Header("Dash setting")]
        [SerializeField] private float dashSpeed;
        [SerializeField] private float dashTime;
        [SerializeField] private float dashCD;
        private bool canDash = true;
        private bool dashed;
        [Space(5)]
    
        [Header("Recoil")]
        [SerializeField] int recoilXSteps = 5;
        [SerializeField] int recoilYSteps = 5;
        [SerializeField] float recoilXSpeed = 100;
        [SerializeField] float recoilYSpeed = 100;
        int stepXrecoiled, stepYrecoiled;
        [Space(5)]
    
        [Header("Mana Setting")]
        [SerializeField] float mana;
        [SerializeField] float manaDrain;
        [SerializeField] float manaGain;
        [SerializeField] UnityEngine.UI.Image manaStorage;
        [Space(5)]
    
        [Header("Spellcasting")]
        [SerializeField] float manaSpellcost = 0.3f;
        [SerializeField] float timeBetweencast = 0.5f;
         float timeSincecast;
        float castOrhealTimer;
        [SerializeField] float spellDmg; //dark rising and skyfall only
        [SerializeField] float skyfallForce; // force for skyfall
        [SerializeField] GameObject sideSpellDarkBall;
        [SerializeField] GameObject upSpellDarkRising;
        [SerializeField] GameObject downSpellSkyFall;
        [Space(5)]
    
        [Header("Walljump")]
        [SerializeField] private float wallSlidingSpeed = 2f;
        [SerializeField] private Transform wallCheck;
        [SerializeField] private LayerMask wallLayer;
        [SerializeField] private float wallJumpingDuration;
        [SerializeField] private Vector2 wallJumpPow;
        float wallJumpDirection;
        bool iswallSliding;
        bool iswallJumping;
        public bool unlockWalljump = false;
        [Space(5)]
    
        bool restoreTime;
        float restoreTimeSpeed;
        private SpriteRenderer spriteRenderer;
        public static Move Instance;
        private float gravity;
        bool openMap;
        private void Awake()
        {
            if (Instance != null && Instance != this)
            {
                Destroy(gameObject);
            }
            else
            {
                Instance = this;
            }
            DontDestroyOnLoad(gameObject);
        }
        // Start is called before the first frame update
        private void Start()
        {
            //player game object
            playerStateList = GetComponent<PlayerStateList>();
            rbd2 = GetComponent<Rigidbody2D>();
            animator = GetComponent<Animator>();
            spriteRenderer = GetComponent<SpriteRenderer>();
            
            gravity = rbd2.gravityScale;
            Mana = mana;
            manaStorage.fillAmount = Mana;
            Health = MaxHealth;
            SaveData.Instance.loadPlayerData();
            if(Health == 0)
            {
                playerStateList.alive = false;
                GameManager.Instance.respawnPlayer();
            }
        }
    
        private void OnDrawGizmos()
        {
            Gizmos.color = Color.yellow;
            Gizmos.DrawWireCube(sideAttackTransform.position, sideAttackArea);
            Gizmos.DrawWireCube(upAttackTransform.position, upAttackArea);
            Gizmos.DrawWireCube(downAttackTransform.position, downAttackArea);
        }
        // Update is called once per frame
    
        private void Update()
        {
            if (playerStateList.incutscene) return;
    
            if(playerStateList.alive)
            {
                getInput();
                OpenMap();
            }
            UpdateJump();
            RestoreTimeScale();
            if (playerStateList.dashing) return;
            FlashWhenInvi();
            if (playerStateList.alive){
    
                if (!iswallJumping)
                {
                    Moving();
                    Flip();
                    Jump();
                }
            };
            Heal();
            CastSpell();
            if (playerStateList.healing) return;
    
            if (unlockWalljump)
            {
                WallSlide();
                WallJump();
            }
            WallSlide();
            WallJump();
            StartDash();
            Attack();
        }
    
        private void OnTriggerEnter2D(Collider2D _other)
        {
            if (_other.GetComponent<Enemy>() != null && playerStateList.castspell)
            {
                _other.GetComponent<Enemy>().EnemyHit(spellDmg, (_other.transform.position - _other.transform.position).normalized, -recoilYSpeed);
            }
        }
    
        private void FixedUpdate()
        {
            if (playerStateList.incutscene) return;
            if (playerStateList.dashing) return;
            Recoil();
        }
    
        void getInput()
        {
            xAxis = Input.GetAxisRaw("Horizontal");
            yAxis = Input.GetAxisRaw("Vertical");
            attk = Input.GetButtonDown("Attack");
            openMap = Input.GetButton("Map");
            if (Input.GetButton("Cast/Heal"))
            {
                castOrhealTimer += Time.deltaTime;
            }
            else
            {
                castOrhealTimer = 0;
            }
        }
        //player Attack
        void Attack()
        {
            timeSinceattk += Time.deltaTime;
            if (attk && timeSinceattk >= timeBetweenattck)
            {
                timeSinceattk = 0;
                animator.SetTrigger("Attacking");
    
                if (yAxis == 0 || yAxis < 0 && isonGround())
                {
                    int _recoilLeftorRight = playerStateList.lookingRight ? 1 : -1;
                    Hit(sideAttackTransform, sideAttackArea, ref playerStateList.recoilingX, recoilXSpeed, Vector2.right * _recoilLeftorRight);
                }
                else if (yAxis > 0)
                {
                    Hit(upAttackTransform, upAttackArea, ref playerStateList.recoilingY, recoilYSpeed, Vector2.up);
                }
                else if (yAxis < 0 && !isonGround())
                {
                    Hit(downAttackTransform, downAttackArea, ref playerStateList.recoilingY, recoilYSpeed, Vector2.down);
                }
            }
        }
    
        //Using for the character recoil
        void Recoil()
        {
            if (playerStateList.recoilingX)
            {
                if (playerStateList.lookingRight)
                {
                    rbd2.velocity = new Vector2(-recoilXSpeed, 0);
                }
                else
                {
                    rbd2.velocity = new Vector2(recoilXSpeed, 0);
                }
            }
    
            if (playerStateList.recoilingY)
            {
                rbd2.gravityScale = 0;
                if (yAxis < 0)
                {
    
                    rbd2.velocity = new Vector2(rbd2.velocity.x, recoilYSpeed);
                }
                else
                {
                    rbd2.velocity = new Vector2(rbd2.velocity.x, -recoilYSpeed);
                }
                dbJumpCounter = 0;
            }
            else
            {
                rbd2.gravityScale = gravity;
            }
            //Stop recoil X
            if (playerStateList.recoilingX && stepXrecoiled < recoilXSteps)
            {
                stepXrecoiled++;
            }
            else
            {
                StopRecoilX();
            }
            //Stop recoil Y
            if (playerStateList.recoilingY && stepYrecoiled < recoilYSteps)
            {
                stepYrecoiled++;
            }
            else
            {
                StopRecoilY();
            }
    
            // if hit ground stop recoil Y
            if (isonGround())
            {
                StopRecoilY();
            }
        }
    
        void StopRecoilX()
        {
            stepXrecoiled = 0;
            playerStateList.recoilingX = false;
        }
        void StopRecoilY()
        {
            stepYrecoiled = 0;
            playerStateList.recoilingY = false;
        }
        //player hit check
        void Hit(Transform _attackTransform, Vector2 _attackArea, ref bool _recoilBool, float _recoilStrenght, Vector2 _recoilDir)
        {
            Collider2D[] objecttoHit = Physics2D.OverlapBoxAll(_attackTransform.position, _attackArea, 0, attackableLayer);
            if (objecttoHit.Length > 0)
            {
                _recoilBool = true;
            }
    
            for (int i = 0; i < objecttoHit.Length; i++)
            {
                if (objecttoHit[i].GetComponent<Enemy>() != null)
                {
                    objecttoHit[i].GetComponent<Enemy>().EnemyHit(playerDmg, _recoilDir, _recoilStrenght);
                    if (objecttoHit[i].CompareTag("Enemy"))
                    {
                        Mana += manaGain;
                    }
                }
            }
        }
        //change dir of the player
        void Flip()
        {
            if (xAxis < 0)
            {
                transform.localScale = new Vector2(-1, transform.localScale.y);
                playerStateList.lookingRight = false;
            }
            else if (xAxis > 0)
            {
                transform.localScale = new Vector2(1, transform.localScale.y);
                playerStateList.lookingRight = true;
            }
        }
        // start the dash
        void StartDash()
        {
            if (Input.GetButtonDown("Dash") && canDash && !dashed)
            {
                StartCoroutine(Dash());
                dashed = true;
            }
            if (isonGround())
            {
                dashed = false;
            }
        }
        IEnumerator Dash()
        {
            canDash = false;
            playerStateList.dashing = true;
            animator.SetTrigger("Dashing");
            rbd2.gravityScale = 0;
            int _dir = playerStateList.lookingRight ? 1 : -1;
            rbd2.velocity = new Vector2(_dir * dashSpeed, 0);
            yield return new WaitForSeconds(dashTime);
            rbd2.gravityScale = gravity;
            playerStateList.dashing = false;
            yield return new WaitForSeconds(dashCD);
            canDash = true;
        }
        //moving of player
        private void Moving()
        {
            //if(playerStateList.healing) rbd2.velocity = new Vector2(0,0);
            rbd2.velocity = new Vector2(speed * xAxis, rbd2.velocity.y);
            animator.SetBool("Walking", rbd2.velocity.x != 0 && isonGround());
        }
        //check if player is on the ground or not
        public bool isonGround()
        {
            if (Physics2D.Raycast(groundcheck.position, Vector2.down, groundchecky, isground)
                || Physics2D.Raycast(groundcheck.position + new Vector3(groundcheckx, 0, 0), Vector2.down, groundchecky, isground)
                || Physics2D.Raycast(groundcheck.position + new Vector3(-groundcheckx, 0, 0), Vector2.down, groundchecky, isground)
                )
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //player jump
        void Jump()
        {
    
            if (Input.GetButtonDown("Jump") && coyoteTimeCounter > 0)
            {
                rbd2.velocity = new Vector3(rbd2.velocity.x, jumpForce);
                /* playerStateList.Jumping = true;*/
            }
            else if (!isonGround() && dbJumpCounter < maxdbJump && Input.GetButtonDown("Jump"))
            {
                dbJumpCounter++;
                rbd2.velocity = new Vector3(rbd2.velocity.x, jumpForce);
            }
    
            animator.SetBool("Jumping", !isonGround());
        }
        void UpdateJump()
        {
            if (isonGround())
            {
                /* playerStateList.Jumping = false;*/
                coyoteTimeCounter = coyoteTime;
                dbJumpCounter = 0;
            }
            else
            {
                coyoteTimeCounter -= Time.deltaTime;
            }
        }
        //stop taking dmg when player get hit
        IEnumerator StopTakingDmg()
        {
            playerStateList.Invi = true;
            GameObject _bloodSpurtParticles = Instantiate(bloodSpurt, transform.position, Quaternion.identity);
            Destroy(_bloodSpurtParticles, 1f);
            animator.SetTrigger("TakeDmg");
            yield return new WaitForSeconds(1f);
            playerStateList.Invi = false;
        }
        //player health calculated
        public int Health
        {
            get { return health; }
            set
            {
                if (health != value)
                {
                    health = Mathf.Clamp(value, 0, MaxHealth);
    
                    if (onHealthChangedCallback != null)
                    {
                        onHealthChangedCallback.Invoke();
                    }
                }
            }
        }
        public float Mana
        {
            get { return mana; }
            set
            {
                if (mana != value)
                {
                    mana = Mathf.Clamp(value, 0, 1);
                    manaStorage.fillAmount = Mana;
                }
            }
    
        }
        //take dmg function
        public void takeDmg(float _Dmg)
        {
            if (playerStateList.alive)
            {
                Health -= Mathf.RoundToInt(_Dmg);
                if(Health <= 0)
                {
                    Health = 0;
                    StartCoroutine(Death());
                }
                else
                {
                    StartCoroutine(StopTakingDmg());
                }
          
            } 
        }
        //time delay for player when get hit
        public void HitStopTime(float _newTimeScale, int _restoreSpeed, float _delay)
        {
            restoreTimeSpeed = _restoreSpeed;
            Time.timeScale = _newTimeScale;
            if (_delay > 0)
            {
                StopCoroutine(TimeStartAgain(_delay));
                StartCoroutine(TimeStartAgain(_delay));
            }
            else
            {
                restoreTime = true;
            }
        }
    
        void RestoreTimeScale()
        {
            if (restoreTime)
            {
                if (Time.timeScale < 1)
                {
                    Time.timeScale += Time.unscaledDeltaTime * restoreTimeSpeed;
                }
                else
                {
                    Time.timeScale = 1;
                    restoreTime = false;
                }
            }
        }
        IEnumerator TimeStartAgain(float _delay)
        {
            yield return new WaitForSecondsRealtime(_delay);
            restoreTime = true;
    
        }
    
        void FlashWhenInvi()
        {
            spriteRenderer.material.color = playerStateList.Invi ? Color.Lerp(Color.white, Color.black, Mathf.PingPong(Time.time * hitFlashspeed, 0.5f)) : Color.white;
        }
        void Heal()
        {
            if (Input.GetButton("Cast/Heal") && castOrhealTimer > 0.05f && Health < MaxHealth && Mana > 0 && !playerStateList.jumping && !playerStateList.dashing)
            {
                print("Healing: " + playerStateList.healing + ", Timer:" + healTimer + ", Mana:" + Mana);
                playerStateList.healing = true;
                animator.SetBool("Healing", true);
                healTimer += Time.deltaTime;
                if (healTimer >= timetoHeal)
                {
                    Health++;
                    healTimer = 0;
                }
    
                //using mana to heal
                Mana -= Time.deltaTime * manaDrain;
            }
            else
            {
               
                playerStateList.healing = false;
                animator.SetBool("Healing", false);
                healTimer = 0;
            }
        }
    
        void CastSpell()
        {
            if (Input.GetButtonUp("Cast/Heal") && castOrhealTimer <= 0.05f && timeSincecast >= timeBetweencast && Mana >= manaSpellcost)
    
            {
                playerStateList.castspell = true;
                timeSincecast = 0;
                StartCoroutine(CastCoroutine());
            }
            else 
            {
                timeSincecast += Time.deltaTime;
            }
    
            if (isonGround())
            {
                //cannot using skyfall if on ground
                downSpellSkyFall.SetActive(false);
            }
            //force the player to fall down if cast skyfall
            if (downSpellSkyFall.activeInHierarchy)
            {
                rbd2.velocity += skyfallForce * Vector2.down;
            }
        }
    
        IEnumerator CastCoroutine()
        {
            animator.SetBool("Casting", true);
            yield return new WaitForSeconds(0.12f);
    
            //sidecast/darkball
            if(yAxis == 0 || (yAxis < 0 && isonGround()))
            {
                GameObject _darkball = Instantiate(sideSpellDarkBall, sideAttackTransform.position, Quaternion.identity);
    
                //flip skill
                if (playerStateList.lookingRight)
                {
                    _darkball.transform.eulerAngles = Vector3.zero; // ban spell nhu bth
                }
                else 
                {
                    _darkball.transform.eulerAngles = new Vector2(_darkball.transform.eulerAngles.x, 100);
                }
    
                playerStateList.recoilingX = true;
            }
    
            //upcast/Dark Rising
            else if(yAxis > 0)
            {
                Instantiate(upSpellDarkRising, transform);
                rbd2.velocity = Vector2.zero;
            }
    
            //downcasr/ Sky Fall
            else if (yAxis < 0 && !isonGround())
            {
                downSpellSkyFall.SetActive(true);
            }
    
            Mana -= manaSpellcost;
            yield return new WaitForSeconds(0.35f);
            animator.SetBool("Casting", false);
            playerStateList.castspell = false;
        }
    
        public IEnumerator WalktonewScene(Vector2 _exitDir, float _delay)
        {
            if(_exitDir.y > 0)
            {
                rbd2.velocity = jumpForce * _exitDir;
            }
            if (_exitDir.x != 0) 
            {
                xAxis = _exitDir.x > 0 ? 1 : -1;
                Moving();
            }
            Flip();
            yield return new WaitForSeconds(_delay);
            playerStateList.incutscene = false;
        }
    
        IEnumerator Death()
        {
            playerStateList.alive = false;
            Time.timeScale = 1f;
            animator.SetTrigger("Death");
            rbd2.constraints = RigidbodyConstraints2D.FreezePosition;
            GetComponent<BoxCollider2D>().enabled = false;
            yield return new WaitForSeconds(0.9f);
            StartCoroutine(UIManager.Instance.ActiveDeathScreen());
        }
    
        public void Respawn()
        {
            if (!playerStateList.alive)
            {
                rbd2.constraints = RigidbodyConstraints2D.None;
                rbd2.constraints = RigidbodyConstraints2D.FreezeRotation;
                GetComponent<BoxCollider2D>().enabled = true;
                playerStateList.alive = true;
                Health = MaxHealth;
                Mana = 0;
                animator.Play("PlayerIdle");
    
            }
        }
    
        void OpenMap()
        {
            if (openMap)
            {
                UIManager.Instance.mapHandler.SetActive(true);
            }
            else
            {
                UIManager.Instance.mapHandler.SetActive(false);
            }
        }
    
        private bool Walled()
        {
            return Physics2D.OverlapCircle(wallCheck.position, 0.2f, wallLayer);
    
        }
    
        void WallSlide()
        {
            if (Walled() && !isonGround() && xAxis != 0)
            {
                iswallSliding = true;
                rbd2.velocity = new Vector2(rbd2.velocity.x, Mathf.Clamp(rbd2.velocity.y, -wallSlidingSpeed, float.MaxValue));
            }
            else
            {
                iswallSliding = false;
            }
        }
        void WallJump()
        {
            if (iswallSliding)
            {
                iswallJumping = false;
                wallJumpDirection = !playerStateList.lookingRight ? 1:-1;
                CancelInvoke(nameof(StopWallJumping));
            }
    
            if (Input.GetButtonDown("Jump") && iswallSliding)
            {
                iswallJumping = true;
                rbd2.velocity = new Vector2(wallJumpDirection * wallJumpPow.x, wallJumpPow.y);
                dashed = false;
                dbJumpCounter = 0;
    
                playerStateList.lookingRight =  !playerStateList.lookingRight;
                transform.eulerAngles = new Vector2(transform.eulerAngles.x, 180);
                Invoke(nameof(StopWallJumping), wallJumpingDuration);
            }
        }
    
        void StopWallJumping()
        {
            iswallJumping = false;
            transform.eulerAngles = new Vector2(transform.eulerAngles.x, 0);
        }
    }
    
    #16292
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    Try setting the player’s health to factor in the heart shards:

    Move.Instance.Health = playerHealth + Mathf.Floor(0.25f * playerHeartShards);
    #16293
    pepecry
    Level 6
    Participant
    Helpful?
    Up
    0
    ::

    When I put the code into loadPlayerData. It said Cannot implicitly convert type ‘float’ to ‘int’. An explicit conversion exists (are you missing a cast?). Should I change the playerHealth from int to float?

    #16294
    pepecry
    Level 6
    Participant
    Helpful?
    Up
    0
    ::

    I tried to fix by adding variable maxhealth
    public int playerMaxHealth;
    and in save and load player data, i add this variable to the value of the player max health like this

     public void savePlayerData()
     {
         using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(Application.persistentDataPath + "/save.player.data")))
         {
    
             playerHealth = Move.Instance.Health;
             writer.Write(playerHealth);
    
             playerMana = Move.Instance.Mana;
             writer.Write(playerMana);
    
             playerUnlockWallJump = Move.Instance.unlockWalljump;
             writer.Write(playerUnlockWallJump);
    
             playerPosition = Move.Instance.transform.position;
             writer.Write(playerPosition.x);
             writer.Write(playerPosition.y);
    
             lastScene = SceneManager.GetActiveScene().name;
             writer.Write(lastScene);
    
             playerHeartShards = Move.Instance.heartShards;
             writer.Write(playerHeartShards);
    
             
             playerMaxHealth = Move.Instance.MaxHealth;
             writer.Write(playerMaxHealth);
    
         }
     }
    public void loadPlayerData()
    {
        if (File.Exists(Application.persistentDataPath + "/save.player.data"))
        {
            using (BinaryReader reader = new BinaryReader(File.OpenRead(Application.persistentDataPath + "/save.player.data")))
            {
                playerHealth = reader.ReadInt32();
                playerMana = reader.ReadSingle();
                playerUnlockWallJump = reader.ReadBoolean();
    
                playerPosition.x = reader.ReadSingle();
                playerPosition.y = reader.ReadSingle();
    
                lastScene = reader.ReadString();
                playerHeartShards = reader.ReadInt32();
                playerMaxHealth = reader.ReadInt32();
    
                SceneManager.LoadScene(lastScene);
                Move.Instance.transform.position = playerPosition;
                Move.Instance.MaxHealth = playerMaxHealth;
                Move.Instance.Health = playerHealth;
                Move.Instance.Mana = playerMana;
                Move.Instance.unlockWalljump = playerUnlockWallJump;
                Move.Instance.heartShards = playerHeartShards;
                Debug.Log("Loaded position: " + playerPosition);
                Debug.Log("Loaded health: " + playerHealth);
                Debug.Log("Loaded mana: " + playerMana);
                Debug.Log("Loaded unlock wall jump: " + playerUnlockWallJump);
                Debug.Log("Loaded heart shards: " + playerHeartShards);
                Debug.Log("Loaded Health: " + playerHealth);
                Debug.Log("Loaded Max Health: " + playerMaxHealth);
            }
            Debug.Log("Player data loaded successfully");
        }
        else
        {
            Debug.Log("File doesn't exist");
            Move.Instance.Health = Move.Instance.MaxHealth;
            Move.Instance.heartShards = 0;
            Move.Instance.Mana = 0.5f;
            Move.Instance.unlockWalljump = false;
        }
    }

    And the game work look fine. Thank you for helping me at all

    #16296
    Terence
    Level 30
    Keymaster
    Helpful?
    Up
    0
    ::

    No, we need to do a cast. I forgot to add that in the code above:

    Move.Instance.Health = playerHealth + (int)Mathf.Floor(0.25f * playerHeartShards);
    #16298
    pepecry
    Level 6
    Participant
    Helpful?
    Up
    1
    ::

    Oh my reply has been flaged as spam (again). In the flag comment. I mada another variable name playermaxhealth and then add it same way as the other variables in the save and load playerdata. Now the game working good. Tks you for helping me all of this time.

    has upvoted this post.
Viewing 10 posts - 1 through 10 (of 10 total)
  • You must be logged in to reply to this topic.

Go to Login Page →


Advertisement below: