Forum begins after the advertisement:


[Part 4] Cast and Heal problem

Home Forums Video Game Tutorial Series Creating a Metroidvania in Unity [Part 4] Cast and Heal problem

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

    Hello everyone. I just finish the skill system and when testing out, I got some problem.
    First problem that is after casting the skill, the mana container doesn’t update. I must hit the enemy to update it.
    Second problem is when i change the input system like the part 5 to using casting spell and heal to right mouse, event when I not input any direction button, the heal function doesn’t work. When I release the mouse, it auto cast the fireball.
    Here is the input system

    Input system

    and here is my healing code

    
    void Heal()
    {
        if (Input.GetButtonDown("Cast/Heal") && castOrhealTimer > 0.05f && Health < MaxHealth && Mana > 0 && !playerStateList.jumping && !playerStateList.dashing)
        {
            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;
        }
    }

    And another problem is the fireball instance kill the enemy althought the enemy hp is higher than the skill damaged

    fireball information

    Can you guys help me to fix this?

    #15907
    Chloe Lim
    Level 9
    Moderator
    Helpful?
    Up
    1
    ::

    Hi, for the Heal issue theres some things that should be checked, as the inputs in your project is not the issue
    – In Update() function, if (playerStateList.healing) return; is not above Heal()
    – Send in the entire PlayerController.cs script so that we know whether there actually is a problem with his update or not.

    For the fireball, I’ll suggest also checking this:
    – The collision function is OnTriggerEnter2D, if its OnTriggerStay2D, the function may be called repeatedly and one fireball might do damage repeatedly
    – send the DarkBullet.cs script for the fireball as well.

    has upvoted this post.
    #15908
    pepecry
    Level 6
    Participant
    Helpful?
    Up
    0
    ::

    Here is the player controller

    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")]
        private 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;
        float healTimer;
        [SerializeField] float timetoHeal;
        [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)]
    
        bool restoreTime;
        float restoreTimeSpeed;
        private SpriteRenderer spriteRenderer;
        public static Move Instance;
        private float gravity;
        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;
        }
    
        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()
        {
            getInput();
            UpdateJump();
            if (playerStateList.dashing) return;
            Flip();
            Moving();
            Jump();
            StartDash();
            Attack();
            RestoreTimeScale();
            FlashWhenInvi();
            Heal();
            CastSpell();
        }
    
        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);
            }
            else
            {
                castOrhealTimer = 0;
            }
        }
    
        private void FixedUpdate()
        {
            if (playerStateList.dashing) return;
            Recoil();
        }
    
        void getInput()
        {
            xAxis = Input.GetAxisRaw("Horizontal");
            yAxis = Input.GetAxisRaw("Vertical");
            attk = Input.GetButtonDown("Attack");
    
            if (Input.GetButton("Cast/Heal"))
            {
                castOrhealTimer = Time.deltaTime;
            }
        }
        //player Attack
        void Attack()
        {
            timeSinceattk += Time.deltaTime;
            if (attk && timeSinceattk >= timeBetweenattck)
            {
                timeSinceattk = 0;
                animator.SetTrigger("Attacking");
    
                if (yAxis == 0 || yAxis < 0 && isonGround())
                {
                    Hit(sideAttackTransform, sideAttackArea, ref playerStateList.recoilingX, recoilXSpeed);
                }
                else if (yAxis > 0)
                {
                    Hit(upAttackTransform, upAttackArea, ref playerStateList.recoilingY, recoilYSpeed);
                }
                else if (yAxis < 0 && !isonGround())
                {
                    Hit(downAttackTransform, downAttackArea, ref playerStateList.recoilingY, recoilYSpeed);
                }
            }
        }
    
        //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 _recoilDir, float _recoilStrenght)
        {
            Collider2D[] objecttoHit = Physics2D.OverlapBoxAll(_attackTransform.position, _attackArea, 0, attackableLayer);
            List<Enemy> hitonEnemies = new List<Enemy>();
            if (objecttoHit.Length > 0)
            {
                _recoilDir = true;
            }
    
            for (int i = 0; i < objecttoHit.Length; i++)
            {
                Enemy e = objecttoHit[i].GetComponent<Enemy>();
                if (e && !hitonEnemies.Contains(e))
                {
                    e.EnemyHit(playerDmg, (transform.position - objecttoHit[i].transform.position).normalized, _recoilStrenght);
                    hitonEnemies.Add(e);
                    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()
        {
            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();
                    }
                }
            }
        }
        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)
        {
            Health -= Mathf.RoundToInt(_Dmg);
            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.GetButtonDown("Cast/Heal") && castOrhealTimer > 0.05f && Health < MaxHealth && Mana > 0 && !playerStateList.jumping && !playerStateList.dashing)
            {
                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;
        }
    }
    

    and this is the skill script

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class DarkBullet : MonoBehaviour
    {
    
        [SerializeField] float Damaged;
        [SerializeField] float hitForce;
        [SerializeField] float Lifetime = 1;
        [SerializeField] int Speed;
        // Start is called before the first frame update
        void Start()
        {
            Destroy(gameObject, Lifetime);
        }
    
        private void FixedUpdate()
        {
            transform.position += Speed*transform.right;
        }
        private void OnTriggerEnter2D(Collider2D _other)
        {
            if(_other.tag == "Enemy")
            {
                _other.GetComponent<Enemy>().EnemyHit(Damaged,(_other.transform.position - transform.position).normalized, -hitForce);
            }
        }
    }
    

    As you said, should I make the update in the player controller like this?

        private void Update()
        {
            getInput();
            UpdateJump();
            if (playerStateList.dashing) return;
            Flip();
            Moving();
            Heal();
            CastSpell();
            if(playerStateList.healing) return;
            Jump();
            StartDash();
            Attack();
            RestoreTimeScale();
            FlashWhenInvi();
        }
    #15911
    Chloe Lim
    Level 9
    Moderator
    Helpful?
    Up
    0
    ::

    Hi, the code for Heal looks fine to me, it might be the inspector values?
    – Check that time to heal is set and Mana to heal is set

    Do add print codes before and after some of the lines of code to see if they execute during play, if it fires then it works, if the print code after the lines does not fire, it means one of the lines failed. Something like this:

        void Heal()
        {
            if (Input.GetButtonDown("Cast/Heal") && castOrhealTimer > 0.05f && Health < MaxHealth && Mana > 0 && !playerStateList.jumping && !playerStateList.dashing)
            {
                print("Healing");
                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;
            }
        }

    Do sort that Update() function in that manner as well, but some should be rearranged, like this:

            if (pState.dashing) return;
            RestoreTimeScale();
            FlashWhileInvincible();
            Move();
            Heal();
            CastSpell();
    
            if (pState.healing) return;
            Flip();
            Jump();
            StartDash();
            Attack();

    For the fireball script. it looks fine to me, the issue might be either in the enemy script or the inspector components. Do check these things
    – Fireball has a trigger collider
    – Enemy has the enemy tag
    – Do send your enemy script as well

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

    So i check and change the code as you said like this

    void Heal()
    {
        if (Input.GetButtonDown("Cast/Heal") && castOrhealTimer > 0.05f && Health < MaxHealth && Mana > 0 && !playerStateList.jumping && !playerStateList.dashing)
        {
            print("Healing");
            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;
        }
    }

    and the update is

    private void Update()
    {
        if (playerStateList.dashing) return;
        RestoreTimeScale();
        FlashWhenInvi();
        Moving();
        Heal();
        CastSpell();
    
        if (playerStateList.healing) return;
        Flip();
        Jump();
        StartDash();
        Attack();
    }

    My character cannot moving or attack anymore. But i still can cast the spell. Yes it’s spell not healing. the console do not feedback anything. And I still oneshot the enemy
    This is my Enemy controller

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Enemy : MonoBehaviour
    {
        [SerializeField] protected float health;
        [SerializeField] protected float recoilLength;
        [SerializeField] protected float recoilFactor;
        [SerializeField] protected bool isRecoilling = false;
    
        protected float recoinTimer;
        protected Rigidbody2D rb;
        [SerializeField] protected Move player;
        [SerializeField] protected float speed;
    
        [SerializeField] protected float dmgMake;
    
        // Start is called before the first frame update
    
        protected virtual void Start()
        {
            rb = GetComponent<Rigidbody2D>();
            player = Move.Instance;
        }
    
        // Update is called once per frame
        protected virtual void Update()
        {
            if (health <= 0)
            {
                Destroy(gameObject);
            }
            if (isRecoilling)
            {
                if (recoinTimer < recoilLength)
                {
                    recoinTimer += Time.deltaTime;
                }
                else
                {
                    isRecoilling = false ;
                    recoinTimer = 0 ;
                }
            }
            
        }
        public virtual void EnemyHit(float _DmgDone, Vector2 _hitDirection, float _hitForce)
        {
            health -= _DmgDone;
            if (!isRecoilling) 
            {
                rb.AddForce(-_hitForce * recoilFactor * _hitDirection);
                isRecoilling=true ;
            }
        }
    
        protected void OnTriggerStay2D(Collider2D _other)
        {
            if (_other.CompareTag("Player") && !Move.Instance.playerStateList.Invi)
            {
                Attack();
                Move.Instance.HitStopTime(0, 2, 0.5f);
            }
        }
        protected virtual void Attack()
        {
            Move.Instance.takeDmg(dmgMake);
        }
    }
    

    For the img about the health and mana drain. Yes i did set the value. Here is it
    Health setting
    Mana setting
    I has tick the is trigger box
    box collider for bullet
    the box collider
    And my enemy has the enemy tag
    Enemy inspector

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

    Hi, your Heal() method should use GetButton() instead of GetButtonDown().
    When you use only GetButtonDown(), the method is only triggered by you pressing the heal button once.

    void Heal()
    {
        if (Input.GetButtonDown("Cast/Heal") Input.GetButton("Cast/Heal") && castOrhealTimer > 0.05f && Health < MaxHealth && Mana > 0 && !playerStateList.jumping && !playerStateList.dashing)
        {
            print("Healing");
            playerStateList.healing = true;
            animator.SetBool("Healing", true);
            ...
        }
        else
        {
            ...
        }
    }

    For your fireball killing the enemy instantly, in your picture you set your “Damaged” variable to “10”, which is most likely the damage you deal to enemies.

    fireball information

    That means that it will deal 10 damage to enemies. So try reducing it to 1 or 5 or any value below the enemies’ health.


    As for you not being able to move or attack, could you tell us when it happens? What did you do before the issue occurs?

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

    Hello. For the damage of the bullet, i set it at 10 because i set the enemy health is 20 as you can see as the picture below.
    enemy health
    and for the bug can not moving. I have no idea why it happen. Maybe because i change the update function like Choloe said of my player controller and change some function as the video part 5 start.

    #15920
    Chloe Lim
    Level 9
    Moderator
    Helpful?
    Up
    0
    ::

    Hi, here’s a few things i suggest to try out to see what is causing the issue

    1. From the update script youve sent, I think GetInputs(); and UpdateJumpVariables(); are not being called in the update, thats why the player might not be moving
    2. Put a print in Move() to see if the move function is working correctly
    3. Check if Heal() has a code to that could be freezing the player’s rigidbody velocity or transform
    4. Put the damage value for the spell at 1, then put a print in your ontriggerenter2d for the fireball, this is to check if the cause of the fireball instakill is due to the fireball constantly colliding and pushing back the enemy
    5. After that, send a recording of you trying this out or send screenshots of the console, then we can observe what might be the issue

    Thr full Update function should look like this

         void Update()
        {
            
    
            GetInputs();
            UpdateJumpVariables();
    
            if (pState.dashing) return;
            RestoreTimeScale();
            FlashWhileInvincible();
            Move();
            Heal();
            CastSpell();
            if (pState.healing) return;
            Flip();
            Jump();
            StartDash();
            Attack();
        } 
    #15921
    pepecry
    Level 6
    Participant
    Helpful?
    Up
    0
    ::

    Hi. So after i change the Update function like your recommend, it now work normally. for the healing. Now my function change to getbutton like joseph said. Here is the code

    void Heal()
    {
        if (Input.GetButton("Cast/Heal") && castOrhealTimer > 0.05f && Health < MaxHealth && Mana > 0 && !playerStateList.jumping && !playerStateList.dashing)
        {
            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;
        }
    }

    But it still not healing my character even if i hold the button longer.
    For the buttet, i put the print at the trigger2d like you said

     private void OnTriggerEnter2D(Collider2D _other)
     {
         if(_other.tag == "Enemy")
         {
             print("GetHit");
             _other.GetComponent<Enemy>().EnemyHit(Damaged,(_other.transform.position - transform.position).normalized, -hitForce);
         }
     }

    When the bullet hit the enemy, nothing print out of my console.The enemy is just disapear and i realise that it instance kill the enemy because the dmg is multiply by 2. which mean when i hit the enemy with skill set at 10dmg. it will make 20dmg. and when i set at 1, it just 2 dmg.
    I just stop the unity, open it, test it again and now the console is print 2 line of get hit. Which mean the enemy take dame 2 times. I dont now why. Maybe because of the box collider.
    And another problem that is not solving that i mentioned it from start of the topic that is the mana container doesn’t update after using skill. It only update after i hit the enemy with my attack. Do you have any idea to fix this?

    #15922
    Chloe Lim
    Level 9
    Moderator
    Helpful?
    Up
    1
    ::

    Hi, for the mana drain issue, after looking through the playercontroller script you’ve sent, the issue might be calling the wrong mana variable which is being deducted by the mana spell cost

     mana -= manaSpellcost; 

    it should be changed to this instead

     Mana -= manaSpellcost; 

    as Mana is the one that is affecting the fillAmount in the UI

    For the healing, test this out first
    – When you have a full Mana meter and heal the player, does it still not heal? Looking at the values in your inspector, each successful attack will gain 0.1 mana while a heal will need 0.2 mana
    – Add prints to your heal function:
    – If your console returns the prints but it’s not restoring health, meaning the if statement has an issue.
    – If the console does not print, then there is an issue with calling Heal()

    For the bullet, possible issues is that
    – Theres 2 box colliders in the enemy, the enemy should have 1 trigger box collider and one box collider
    – Theres 2 trigger box collider on the fireball
    – Try to lower the damage to the enemy to check if its only a double hit
    I’ll also suggest that if the porblem persists after that, you can try to use the same piece of code that the playercontroller uses in the hit function to ensure that the enemy will only take one damage at a time, which is in this link https://blog.terresquall.com/community/topic/part-3-missing-video-content-common-issues-fixes/

    has upvoted this post.
    #15924
    pepecry
    Level 6
    Participant
    Helpful?
    Up
    0
    ::

    I change my mana function like u said and it now can update after i using the skill.
    And for the healing, i add the print into code like this

    playerStateList.healing = true;
    animator.SetBool("Healing", true);
    healTimer += Time.deltaTime;
    if (healTimer >= timetoHeal)
    {
        Health++;
        print("Healing");
        healTimer = 0;
    }

    but nothing print to the console even if i have full mana. it only print the get hit i put into the enemy code because i hold the mouse button and release and it cast the spell
    console
    for the enemy box collider. Yes it has 2 box collider but 1 is trigger and 1 is not as you can see the img below
    enemy box collider

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

    Hi, could you do the following for us to assist you further?

    IF POSIBLE, do take a video of your player’s inspector, the DarkBullet hitting the enemy, the console and prints, and you healing or any other bugs.
    This will help us discern what is the possible issues efficiently.

    1. Post your Player script, DarkBullet script again.

    2. Reduce your DarkBullet Damage to “1” and leave your Enemy at “20” health. Please do this so we can affirm if the enemy is still being killed by it or only being hit two times maximum.

    3. Put a print into your Heal() method to see at what variables fail to work correctly:

    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
        {
            print("Stopped Healing");
            playerStateList.healing = false;
            animator.SetBool("Healing", false);
            healTimer = 0;
        }
    }
    #15926
    pepecry
    Level 6
    Participant
    Helpful?
    Up
    0
    ::

    Ok so i recording it to you. Here is the video. Sorry because the imgur only take the video under 1 minute so i need to divide it to 2 videos. And i will also give 1 link and 1 img url of imgur for sure
    The first video is change the code of the heal function and check the inspector
    check inspector and code
    Inspector video
    the second video is when i test the game
    test game function
    test function
    For the scripts. here is player scripts

    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")]
        private 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;
        float healTimer;
        [SerializeField] float timetoHeal;
        [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)]
    
        bool restoreTime;
        float restoreTimeSpeed;
        private SpriteRenderer spriteRenderer;
        public static Move Instance;
        private float gravity;
        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;
        }
    
        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()
        {
            getInput();
            UpdateJump();
            if (playerStateList.dashing) return;
            RestoreTimeScale();
            FlashWhenInvi();
            Moving();
            Heal();
            CastSpell();
            if (playerStateList.healing) return;
            Flip();
            Jump();
            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);
            }
            else
            {
                castOrhealTimer = 0;
            }
        }
    
        private void FixedUpdate()
        {
            if (playerStateList.dashing) return;
            Recoil();
        }
    
        void getInput()
        {
            xAxis = Input.GetAxisRaw("Horizontal");
            yAxis = Input.GetAxisRaw("Vertical");
            attk = Input.GetButtonDown("Attack");
    
            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())
                {
                    Hit(sideAttackTransform, sideAttackArea, ref playerStateList.recoilingX, recoilXSpeed);
                }
                else if (yAxis > 0)
                {
                    Hit(upAttackTransform, upAttackArea, ref playerStateList.recoilingY, recoilYSpeed);
                }
                else if (yAxis < 0 && !isonGround())
                {
                    Hit(downAttackTransform, downAttackArea, ref playerStateList.recoilingY, recoilYSpeed);
                }
            }
        }
    
        //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 _recoilDir, float _recoilStrenght)
        {
            Collider2D[] objecttoHit = Physics2D.OverlapBoxAll(_attackTransform.position, _attackArea, 0, attackableLayer);
            List<Enemy> hitonEnemies = new List<Enemy>();
            if (objecttoHit.Length > 0)
            {
                _recoilDir = true;
            }
    
            for (int i = 0; i < objecttoHit.Length; i++)
            {
                Enemy e = objecttoHit[i].GetComponent<Enemy>();
                if (e && !hitonEnemies.Contains(e))
                {
                    e.EnemyHit(playerDmg, (transform.position - objecttoHit[i].transform.position).normalized, _recoilStrenght);
                    hitonEnemies.Add(e);
                    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();
                    }
                }
            }
        }
        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)
        {
            Health -= Mathf.RoundToInt(_Dmg);
            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
            {
                print("Stopped Healing");
                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;
        }
    }
    

    and here is dark bullet script

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class DarkBullet : MonoBehaviour
    {
    
        [SerializeField] float Damaged;
        [SerializeField] float hitForce;
        [SerializeField] float Lifetime = 1;
        [SerializeField] int Speed;
        // Start is called before the first frame update
        void Start()
        {
            Destroy(gameObject, Lifetime);
        }
    
        private void FixedUpdate()
        {
            transform.position += Speed*transform.right;
        }
        private void OnTriggerEnter2D(Collider2D _other)
        {
            if(_other.tag == "Enemy")
            {
                print("GetHit");
                _other.GetComponent<Enemy>().EnemyHit(Damaged,(_other.transform.position - transform.position).normalized, -hitForce);
            }
        }
    }
    

    If you need me to provide anything else. i will give it asap

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

    Sorry, But i’m going to need you to try something else then.

    1. Delete only the else statement print code since It will keep playing no matter what.

        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
            {
                print("Stopped Healing");
                playerStateList.healing = false;
                animator.SetBool("Healing", false);
                healTimer = 0;
            }
        }

    2. When you try to Heal, HOLD Down the Cast/Heal button.

    From what i’ve seen, you’ve been casting which requires you to tap the button and not healing, either this was intentional to show the cast and not the healing, or you did not heal properly since it’s supposed to be held down instead of tapping.


    3. Get rid of this part in your PlayerController.cs of OnTriggerEnter2D(), you won’t need to reset the timer here.

        private void OnTriggerEnter2D(Collider2D _other)
        {
            if (_other.GetComponent() != null && playerStateList.castspell)
            {
                _other.GetComponent().EnemyHit(spellDmg, (_other.transform.position - _other.transform.position).normalized, -recoilYSpeed);
            }
            else
            {
                castOrhealTimer = 0;
            }
        }

    4. Make sure you only use Mana with a capital M instead of mana when referring to the variable.

    Here’s the only other value in your Player script that refers to it incorrectly.

        void CastSpell()
        {
            if (Input.GetButtonUp("Cast/Heal") && castOrhealTimer <= 0.05f && timeSincecast >= timeBetweencast && mana 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;
            }
        }

    5. Don’t worry about the double damage from the DarkBullet, after checking,
    Follow Part 6 as that will be when we create enemies with only one boxcollider2D.

    Note that even though one of the boxes of the Enemy is a Trigger, the OnTriggerEnter2D() of the DarkBullet is just checking for BoxCollider2D’s to enter the trigger of the DarkBullet, not the enemy. Therefore both boxes of the Enemy touching the DarkBullet is causing the double damage.


    Finally,

    Please take another video again after following this, while you have all of these:
    1. Console in view
    2. Looking at the Players Health Inspector value
    3. Holding the Heal button down and not letting it go, while having missing health to be healed and mana to heal.

    We need to do this to confirm if:
    > You are actually healing as your Health will increase in the inspector if you are. Also meaning that your UI is a problem
    > Your Heal method is functioning
    > Your Heal variables are working as intended.

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

    Sorry for replying late. I got some stuff to do.
    SO step by step. I has do what you said. Delete the print and change the mana to Mana. But there is some misunderstanding here. I holding the button in the test video i send you before. But for sure I will record another video of test after following your guide. My new video has the audio in it. If you want i’ll upload it to my youtube channel for better resolution and updating the link if you want.
    test video

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

Go to Login Page →


Advertisement below: