Forum begins after the advertisement:


[Part 8] My orbShards cannot works

Home Forums Video Game Tutorial Series Creating a Metroidvania in Unity [Part 8] My orbShards cannot works

Viewing 15 posts - 1 through 15 (of 23 total)
  • Author
    Posts
  • #13884
    #13885
    #13886
    Elvin Sim
    Participant

    When I start the game, it will come out the above errors

    #13887
    #13888
    Elvin Sim
    Participant

    and also after add the orbShards things and code, I cannot get mana by hitting the enemies

    #13889
    Elvin Sim
    Participant

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class AddManaOrb : MonoBehaviour
    {
    [SerializeField] GameObject particles;
    [SerializeField] GameObject canvasUI;

    [SerializeField] OrbShard orbShard;

    bool used;

    // Start is called before the first frame update
    void Start()
    {
    if (PlayerController.Instance.manaOrbs >= 3)
    {
    Destroy(gameObject);
    }
    }

    private void OnTriggerEnter2D(Collider2D _collision)
    {
    if (_collision.CompareTag(“Player”) && !used)
    {
    used = true;
    StartCoroutine(ShowUI());
    }
    }

    IEnumerator ShowUI()
    {
    GameObject _particles = Instantiate(particles, transform.position, Quaternion.identity);
    Destroy(_particles, 0.5f);
    yield return new WaitForSeconds(0.5f);

    canvasUI.SetActive(true);
    orbShard.initialFillAmount = PlayerController.Instance.orbShard * 0.34f;
    PlayerController.Instance.orbShard++;
    orbShard.targetFillAmount = PlayerController.Instance.orbShard * 0.34f;

    StartCoroutine(orbShard.LerpFill());

    yield return new WaitForSeconds(2.5f);
    SaveData.Instance.SavePlayerData();
    canvasUI.SetActive(false);
    Destroy(gameObject);
    }
    }

    #13890
    Elvin Sim
    Participant

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;

    public class OrbShard : MonoBehaviour
    {
    public Image fill;

    public float targetFillAmount;
    public float lerpDuration = 1.5f;
    public float initialFillAmount;
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }

    public IEnumerator LerpFill()
    {
    float elapsedTime = 0f;

    while (elapsedTime < lerpDuration)
    {
    elapsedTime += Time.deltaTime;
    float t = Mathf.Clamp01(elapsedTime / lerpDuration);

    float lerpedFillAmount = Mathf.Lerp(initialFillAmount, targetFillAmount, t);
    fill.fillAmount = lerpedFillAmount;

    yield return null;
    }

    fill.fillAmount = targetFillAmount;

    if (fill.fillAmount == 1)
    {
    PlayerController.Instance.manaOrbs++;
    PlayerController.Instance.orbShard = 0;
    }
    }
    }

    #13891
    Elvin Sim
    Participant

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;

    public class ManaOrbsHandler : MonoBehaviour
    {
    public bool usedMana;
    public List<GameObject> manaOrbs;
    public List<Image> orbFills;

    public float countDown = 3f;
    float totalManaPool;

    // Start is called before the first frame update
    void Start()
    {
    for(int i = 0; i < PlayerController.Instance.manaOrbs; i++)
    {
    manaOrbs[i].SetActive(true);
    }
    CashInMana();
    }

    // Update is called once per frame
    void Update()
    {
    for (int i = 0; i < PlayerController.Instance.manaOrbs; i++)
    {
    manaOrbs[i].SetActive(true);
    }
    }

    public void UpdateMana(float _manaGainFrom)
    {
    for(int i = 0; i < manaOrbs.Count; i++)
    {
    if (manaOrbs[i].activeInHierarchy && orbFills[i].fillAmount < 1)
    {
    orbFills[i].fillAmount += _manaGainFrom;
    break;
    }
    }
    }

    void CashInMana()
    {
    if(usedMana && PlayerController.Instance.Mana <= 1)
    {
    countDown -= Time.deltaTime;
    }

    if(countDown <= 0)
    {
    usedMana = false;
    countDown = 3;

    totalManaPool = (orbFills[0].fillAmount += orbFills[1].fillAmount += orbFills[2].fillAmount) * 0.33f;
    float manaNeeded = 1 – PlayerController.Instance.Mana;

    if(manaNeeded > 0)
    {
    if(totalManaPool >= manaNeeded)
    {
    PlayerController.Instance.Mana += manaNeeded;
    for(int i = 0;i < orbFills.Count; i++)
    {
    orbFills[i].fillAmount = 0;
    }

    float addBackTotal = (totalManaPool – manaNeeded) / 0.33f;
    while(addBackTotal > 0)
    {
    UpdateMana(addBackTotal);
    addBackTotal -= 1;
    }
    }
    else
    {
    PlayerController.Instance.Mana += totalManaPool;
    for (int i = 0; i < orbFills.Count; i++)
    {
    orbFills[i].fillAmount = 0;
    }
    }
    }
    }
    }
    }

    #13892
    Elvin Sim
    Participant

    [Header(“Mana Settings:”)]
    [SerializeField] UnityEngine.UI.Image manaStorage;
    [SerializeField] float mana;
    [SerializeField] float manaDrainSpeed;
    [SerializeField] float manaGain;
    public bool halfMana;

    public ManaOrbsHandler manaOrbsHandler;
    public int orbShard;
    public int manaOrbs;
    [Space(5)]

    // Start is called before the first frame update
    void Start()
    {
    pState = GetComponent<PlayerStateList>();

    rb = GetComponent<Rigidbody2D>();
    sr = GetComponent<SpriteRenderer>();

    anim = GetComponent<Animator>();
    manaOrbsHandler = FindObjectOfType<ManaOrbsHandler>();

    SaveData.Instance.LoadPlayerData();
    if (halfMana)
    {
    UIManager.Instance.SwitchMana(UIManager.ManaState.HalfMana);
    }

    gravity = rb.gravityScale;

    Mana = mana;
    manaStorage.fillAmount = Mana;

    Health = maxHealth;
    Debug.Log(transform.position);
    }

    void Hit(Transform _attackTransform, Vector2 _attackArea, ref bool _recoilBool, Vector2 _recoilDir, float _recoilStrength)
    {
    Collider2D[] objectsToHit = Physics2D.OverlapBoxAll(_attackTransform.position, _attackArea, 0, attackableLayer);

    if(objectsToHit.Length > 0)
    {
    _recoilBool = true;
    }
    for(int i = 0; i < objectsToHit.Length; i++)
    {
    if (objectsToHit[i].GetComponent<Enemy>() != null)
    {
    objectsToHit[i].GetComponent<Enemy>().EnemyGetsHit(damage, _recoilDir, _recoilStrength);

    if (objectsToHit[i].CompareTag(“Enemy”))
    {
    if(Mana >= 1 || (halfMana && Mana >= 0.5))
    {
    Mana += manaGain;
    }
    else
    {
    manaOrbsHandler.UpdateMana(manaGain * 3);
    }
    }
    }
    }
    }

    void Heal()
    {
    if(Input.GetButton(“Cast/Heal”) && castOrHealtimer > 0.05f && Health < maxHealth && Mana > 0 && !pState.jumping && !pState.dashing)
    {
    pState.healing = true;
    anim.SetBool(“Healing”, true);

    //healing
    healTimer += Time.deltaTime;
    if(healTimer >= timeToHeal)
    {
    Health++;
    healTimer = 0;
    }

    //drain mana
    manaOrbsHandler.usedMana = true;
    manaOrbsHandler.countDown = 3f;
    Mana -= Time.deltaTime * manaDrainSpeed;
    }
    else
    {
    pState.healing = false;
    anim.SetBool(“Healing”, false);
    healTimer = 0;
    }
    }

    public float Mana
    {
    get { return mana; }
    set
    {
    //if mana stats change
    if(mana != value)
    {
    if (!halfMana)
    {
    mana = Mathf.Clamp(value, 0, 1);
    }
    else
    {
    mana = Mathf.Clamp(value, 0, 0.5f);
    }

    manaStorage.fillAmount = Mana;
    }
    }
    }

    IEnumerator CastCoroutine()
    {
    //side cast
    if((yAxis == 0 || (yAxis < 0 && Grounded())) && unlockedSideCast)
    {
    anim.SetBool(“Casting”, true);
    yield return new WaitForSeconds(0.15f);
    GameObject _fireBall = Instantiate(sideSpellFireball, SideAttackTransform.position, Quaternion.identity);

    //flip fireball
    if (pState.lookingRight)
    {
    _fireBall.transform.eulerAngles = Vector3.zero; //if facing right, fireball continues as per normal
    }
    else
    {
    _fireBall.transform.eulerAngles = new Vector2(_fireBall.transform.eulerAngles.x, 180);
    //if not facing right, rotate the fireball 180 deg
    }
    pState.recoilingX = true;

    Mana -= manaSpellCost;
    manaOrbsHandler.usedMana = true;
    manaOrbsHandler.countDown = 3f;
    yield return new WaitForSeconds(0.35f);
    }

    //up cast
    else if(yAxis > 0 && unlockedUpCast)
    {
    anim.SetBool(“Casting”, true);
    yield return new WaitForSeconds(0.15f);

    Instantiate(upSpellExplosion, transform);
    rb.velocity = Vector2.zero;

    Mana -= manaSpellCost;
    manaOrbsHandler.usedMana = true;
    manaOrbsHandler.countDown = 3f;
    yield return new WaitForSeconds(0.35f);
    }

    //down cast
    else if((yAxis < 0 && !Grounded()) && unlockedDownCast)
    {
    anim.SetBool(“Casting”, true);
    yield return new WaitForSeconds(0.15f);

    downSpellFireball.SetActive(true);

    Mana -= manaSpellCost;
    manaOrbsHandler.usedMana = true;
    manaOrbsHandler.countDown = 3f;
    yield return new WaitForSeconds(0.35f);
    }

    anim.SetBool(“Casting”, false);
    pState.casting = false;
    }

    #13894
    Joseph Tang
    Moderator

    After looking through the images and your scripts, I can tell you how to solve the mana issue.
    However, regarding the console error, I will need some more testing to figure out.
    So far, we can see that it is a NullReferenceException error, meaning something is not assigned or doesn’t exist. Secondly, i presume both line 183 & 111 in your SaveData.cs relates to PlayerController.instance.manaOrbsHandler.orbFills[0]? If so, then something is wrong with the manaorbshandler or the player prefab.
    Could you try to get the same errors, then click on both errors to see where they redirect + check the Player controller inspector & the manaHandler inspector in the scene with the error?.

    Side Note: In your ManaOrbsHandler.cs, your CashInMana is in Start(), instead of Update()

    Back to solving the mana issue with enemies:
    In your PlayerController.cs, change your Hit() to this:

    void Hit(Transform _attackTransform, Vector2 _attackArea, ref bool _recoilBool, Vector2 _recoilDir, float _recoilStrength)
        {
            Collider2D[] objectsToHit = Physics2D.OverlapBoxAll(_attackTransform.position, _attackArea, 0, attackableLayer);
    
            if (objectsToHit.Length > 0)
            {
                _recoilBool = true;
            }
            for(int i = 0; i < objectsToHit.Length; i++)
            {
                if (objectsToHit[i].GetComponent() != null)
                {
                    objectsToHit[i].GetComponent().EnemyHit
                        (damage,  _recoilDir, _recoilStrength);
    
                    if (objectsToHit[i].CompareTag("Enemy"))
                    {
                        if(Mana >= 1 || (halfMana && Mana >= 0.5))
                        if (Mana < 1)
                        {
                            Mana += manaGain;
                        }
                        else
                        {
                            manaOrbsHandler.UpdateMana(manaGain * 3);
                        }
                    }
                }
            }
        }

    This should help fix the issue of not gaining mana as the if statement parameter was incorrect (you assigned the parameter to activate only if you had more or equal to the maximum mana capacity at fullmana and halfmana).

    #13897
    #13898
    #13899
    Elvin Sim
    Participant

    For :check the Player controller inspector & the manaHandler inspector in the scene with the error?. I have sent them in the previous screenshot

    #13900
    Elvin Sim
    Participant

    The code you tell me to fix I have fix them, just error for the nullexception

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

Go to Login Page →


Advertisement below: