Forum begins after the advertisement:


[Part 16] Gravity not working and Enemy Null Reference

Home Forums Video Game Tutorial Series Creating a Rogue-like Shoot-em Up in Unity [Part 16] Gravity not working and Enemy Null Reference

Viewing 10 posts - 1 through 10 (of 10 total)
  • Author
    Posts
  • #15227
    Silvian
    Participant
    Helpful?
    Up
    0
    ::

    After following Part 16 and implemented the axe I’ve noticed that the axe just goes up to infinity:

    https://imgur.com/axe-without-gravity-rPPK7Gd

    Then I saw the comment on Youtube to check the project Settings and enable gravity. I’ve downloaded the project file and I’ve noticed you set gravity on Y at around -10, so I did the same. But these happened:

    Gems and pots falling out of the scene on the Title Scene:

    https://imgur.com/titlescreen-R1E4evE

    Axes are now correctly thrown, but they fall to infinity if they do not meet the number of enemies equal to their piercing:

    https://imgur.com/axe-ztI6hn0

    Gems/Pots are extremely fast when picking them up in-game and they can miss the player (caused by the gravity settings):

    https://imgur.com/experience-gems-An1ry2H

    I’ve been looking through my files and the part 16 files from patreon, but I’m not really sure what’s causing these.

    One more thing I’ve noticed is that I get null references caused by the enemies that are alive when I stop the game:

    https://imgur.com/enemy-null-QODgznZ

    Let me know if you need more screenshots or I need to provide some scripts.

    #15228
    Terence
    Keymaster
    Helpful?
    Up
    0
    ::

    Silvian, after setting your Gravity to a non-zero value, make sure that Gravity Scale for all of your prefabs and GameObjects with a Rigidbody2D are set to 0. This will prevent gravity from affecting all of them. The only object you don’t want to turn off Gravity Scale for is the Axe.

    As for the Axe falling forever, make sure that the Lifespan in its weapon data is set to a non-zero value.

    For the null references, I’ll need a screenshot or a text dump of the error.

    #15229
    Silvian
    Participant
    Helpful?
    Up
    0
    ::

    First of all thanks for the help with the gravity and axe lifespan (forgot to give it a value). That fixed the problems related to the gravity prefabs and axe. Also sorry for flagging the topic as spam (tried again to post the imgur pictures, but they still do not appear, there should have been images/pictures in the post since the beginning).

    Now for the null reference, I’ll post a pic below (let’s hope this time the imgur works):

    https://imgur.com/4THxEcU

    #15230
    Silvian
    Participant
    Helpful?
    Up
    0
    ::

    I have no idea why the pictures/videos from imgur don’t want to show here. I just post the link of them and there are not here. Am I doing something wrong?

    #15231
    Terence
    Keymaster
    Helpful?
    Up
    0
    ::

    No worries, you didn’t do anything wrong. It’s just that the Imgur link you generated is not how the links are generated. They are usually in the format imgur.com/a/[IMGUR_CODE], and you are missing the /a/ part.

    I will need to see your EnemyStats script, because the NullReferenceException is happening at a specific part. Can you post your script here and bold line 114 for me?

    In the meantime, here is a useful video that you can watch to learn more about NulLReferenceExceptions and how to fix them.

    #15232
    Silvian
    Participant
    Helpful?
    Up
    0
    ::

    Sure, I’ve posted the code. Not sure how to highlight, but hope I did it right.

    
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    [RequireComponent(typeof(SpriteRenderer))]
    public class EnemyStats : MonoBehaviour
    {
        public EnemyScriptableObject enemyData;
    
        // Current stats
        [HideInInspector]
        public float currentHealth;
        [HideInInspector]
        public float currentDamage;
        [HideInInspector]
        public float currentMoveSpeed;
    
        public float despawnDistance = 20f;
        Transform player;
    
        [Header("Damage Feedback")]
        public Color damageColor = new Color (1, 0, 0, 1);
        public float damageFlashDuration = 0.2f;
        public float deathFadeTime = 0.6f;
        Color originalColor;
        SpriteRenderer sr;
        EnemyMovement movement;
    
        void Awake()
        {
            currentHealth = enemyData.MaxHealth;
            currentDamage = enemyData.AttackDamage;
            currentMoveSpeed = enemyData.MoveSpeed;
        }
    
        void Start()
        {
            player = FindObjectOfType<PlayerStats>().transform;
            sr = GetComponent<SpriteRenderer>();
            originalColor = sr.color;
    
            movement = GetComponent<EnemyMovement>();
        }
    
        public void TakeDamage(float damage, Vector2 sourcePosition, float knockbackForce = 5f, float knockbackDuration = 0.2f)
        {
            currentHealth -= damage;
            StartCoroutine(DamageFlash());
    
            if (damage > 0)
                GameManager.GenerateFloatingText(Mathf.FloorToInt(damage).ToString(), transform);
    
            if(knockbackForce > 0)
            {
                Vector2 dir = (Vector2)transform.position - sourcePosition;
                movement.KnockBack(dir.normalized * knockbackForce, knockbackDuration);
            }
    
            if (currentHealth <= 0)
            {
                Kill();
            }
        }
    
        IEnumerator DamageFlash()
        {
            sr.color = damageColor;
            yield return new WaitForSeconds(damageFlashDuration);
            sr.color = originalColor;
        }
    
        void Update()
        {
            if (Vector2.Distance(transform.position, player.position) >= despawnDistance)
            {
                ReturnEnemy();
            }
        }
    
        public void Kill()
        {
            StartCoroutine(KillFade());
        }
    
        IEnumerator KillFade()
        {
            WaitForEndOfFrame w = new WaitForEndOfFrame();
            float t = 0;
            float origAlpha = sr.color.a;
    
            while(t < deathFadeTime)
            {
                yield return w;
                t += Time.deltaTime;
    
                sr.color = new Color(sr.color.r, sr.color.g, sr.color.b, (1 - t / deathFadeTime) * origAlpha);
            }
    
            Destroy(gameObject);
        }
    
        private void OnCollisionStay2D(Collision2D collision)
        {
            if (collision.gameObject.CompareTag("Player"))
            {
                PlayerStats player = collision.gameObject.GetComponent<PlayerStats>();
                player.TakeDamage(currentDamage);
            }
        }
    
        private void OnDestroy()
        {
            EnemySpawner es = FindObjectOfType<EnemySpawner>();
            <strong>es.OnEnemyKilled();</strong>
        }
    
        void ReturnEnemy()
        {
            EnemySpawner es = FindObjectOfType<EnemySpawner>();
            transform.position = player.position + es.relativeSpawnPositions[Random.Range(0, es.relativeSpawnPositions.Count)].position;
        }
    }
    

    If it isn’t highlighted, the line 114 is es.OnEnemyKilled(); .

    #15233
    Terence
    Keymaster
    Helpful?
    Up
    0
    ::

    Oh yeah. I see it. The null reference is happening because es is null, which means your FindObjectByType() function isn’t finding an EnemySpawner. Did you disable it?

    If you intentionally disabled it, you can change your code this way:

    private void OnDestroy()
    {
        EnemySpawner es = FindObjectOfType<EnemySpawner>();
        if(es) es.OnEnemyKilled();
    }

    So it doesn’t fire for when the Enemy Spawner is turned off or missing.

    #15235
    Silvian
    Participant
    Helpful?
    Up
    0
    ::

    Is this where you’re referring to it being disabled? Because it is not. And I don’t remember if I disabled something. Does it need to be disabled?

    EnemySpawner

    #15236
    Silvian
    Participant
    Helpful?
    Up
    0
    ::

    Also, would it be better to just try to update the enemy spawner when I get to part 21 since you’re addressing this there?

    #15237
    Terence
    Keymaster
    Helpful?
    Up
    0
    ::

    Ah, it looks like yours is not disabled, but it’s ok. The errors are popping likely because when you stop the game, the GameObjects get destroyed sequentially and your EnemySpawner gets removed before the enemies, which is why you get the errors when the enemies get removed and OnDestroy() triggers.

    If you want to remove the error, my suggested code above for OnDestroy() should stop the error.

    Also, would it be better to just try to update the enemy spawner when I get to part 21 since you’re addressing this there?

    Part 21 changes the way that enemies are counted and removes that part of OnDestroy(), so you can wait for that too, but this is a simple fix for the current enemy spawner script as well.

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: