Forum begins after the advertisement:


[Part 15] MissingReferenceException “RectTransform”

Home Forums Video Game Tutorial Series Creating a Rogue-like Shoot-em Up in Unity [Part 15] MissingReferenceException “RectTransform”

  • This topic has 5 replies, 2 voices, and was last updated 1 month ago by Kai.
Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #13182
    Kai
    Participant

    Hi,
    After part 15, I got this bug again in these lines from GenerateFloatingTextCoroutine
    rect.position = referenceCamera.WorldToScreenPoint(target.position + new Vector3(0, yOffset));

    rect.position += new Vector3(0, speed * Time.deltaTime, 0);

    GameManager.cs

     IEnumerator GenerateFloatingTextCoroutine(string text, Transform target, float duration = 1f, float speed = 50f)
     {
         // Start generating the floating text.
         GameObject textObj = new GameObject("Damage Floating Text");
         RectTransform rect = textObj.AddComponent<RectTransform>();
         TextMeshProUGUI tmPro = textObj.AddComponent<TextMeshProUGUI>();
         tmPro.text = text;
         tmPro.horizontalAlignment = HorizontalAlignmentOptions.Center;
         tmPro.verticalAlignment = VerticalAlignmentOptions.Middle;
         tmPro.fontSize = textFontSize;
         if (textFont) tmPro.font = textFont;
         rect.position = referenceCamera.WorldToScreenPoint(target.position);
    
         // Makes sure this is destroyed after the duration finishes.
         Destroy(textObj, duration);
    
         // Parent the generated text object to the canvas.
         textObj.transform.SetParent(instance.damageTextCanvas.transform);
    
         // Pan the text upwards and fade it away over time.
         WaitForEndOfFrame w = new WaitForEndOfFrame();
         float t = 0;
         float yOffset = 0;
         while (t < duration)
         {
             // Wait for a frame and update the time.
             yield return w;
             t += Time.deltaTime;
    
             // Fade the text to the right alpha value.
             tmPro.color = new Color(tmPro.color.r, tmPro.color.g, tmPro.color.b, 1 - t / duration);
    
             // Pan the text upwards.
             if (target)
             {
                 yOffset += speed * Time.deltaTime;
                 rect.position = referenceCamera.WorldToScreenPoint(target.position + new Vector3(0, yOffset));  
             }
             else
             {
                 // If target is dead, just pan up where the text is at.
                 rect.position += new Vector3(0, speed * Time.deltaTime, 0);
             }
         }
     }
    
     public static void GenerateFloatingText(string text, Transform target, float duration = 1f, float speed = 1f)
     {
         // If the canvas is not set, end the function so we don't
         // generate any floating text.
         if (!instance.damageTextCanvas) return;
    
         // Find a relevant camera that we can use to convert the world
         // position to a screen position.
         if (!instance.referenceCamera) instance.referenceCamera = Camera.main;
    
         instance.StartCoroutine(instance.GenerateFloatingTextCoroutine(
             text, target, duration, speed
         ));
     }
    
    #13183
    #13187
    Kai
    Participant

    Thanks, it worked but after a few minutes in game I ran into another (MissingReferenceException: The object of type ‘EnemyStats’ has been destroyed but you are trying to access it) in this line Renderer r = target.GetComponent<Renderer>(); from LightningRingWeapon.cs

    #13188
    Terence
    Keymaster

    The error is occurring because one of your bolts of lightning is attempting to strike an enemy that is no longer there. This happens because the enemies are chosen at the first lightning bolt, and between the first bolt and the subsequent bolts, some of the enemies that we can strike may have died, so we have to modify PickEnemy() to exclude enemies that have been dead.

        // Randomly picks an enemy on screen.
        EnemyStats PickEnemy()
        {
            EnemyStats target = null;
            while(!target && allSelectedEnemies.Count > 0)
            {
                int idx = Random.Range(0, allSelectedEnemies.Count);
                target = allSelectedEnemies[Random.Range(0, allSelectedEnemies.Count)idx];
    
                // If the target is already dead, remove it and skip it.
                if(!target)
                {
                    allSelectedEnemies.RemoveAt(idx);
                    continue;
                }
    
                // Check if the enemy is on screen.
                // If the enemy is missing a renderer, it cannot be struck, as we cannot
                // check whether it is on the screen or not.
                Renderer r = target.GetComponent();
                if (!r || !r.isVisible)
                {
                    allSelectedEnemies.Remove(target);
                    target = null;
                    continue;
                }
            }
    
            allSelectedEnemies.Remove(target);
            return target;
        }
    #13190
    Terence
    Keymaster

    Kai, I’ve updated the article with the fix detailed above. You can find it here. Thank you for spotting this bug!

    I’ve given you a Bug Reporter badge on your account page as well.

    Bug Reporter

    #13196
    Kai
    Participant

    It worked perfectly, thanks for your time

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

Go to Login Page →


Advertisement below: