Search code examples
c#unity-game-engineunity-webgl

UNITY 2D and WebGL: 3D-TextMeshPro NOT SHOWING on build and run


The Problem:

  1. Play Mode - the spawning of asteroids with words (3d TMP) is good and it shows the tmp.

  2. Build and Run - On the WebGL browser from the build and run, the asteroids spawns with only its image, the TMP is not shown (the associated word of the asteroid).

This is for our school capstone and I'm not a very expert programmer, please don't hurt me. We're planning to build a 2D typing game with a theme of asteroids using UNITY 2D. You type the word of an asteroid correctly, you destroy it. Here is the problem. I have a prefab with a game object (parent, sprite renderer, to show asteroid sprite) with a child game object (3D - TextMeshPro, to show word). In their script, I decrement their ordering layer so that the earlier spawned asteroids will block in view the new ones. The ordering layer of the Parent is of course not greater so it won't block the Child.

Here are the codes in C#:

This is a script to instantiate the prefab. (spawning an asteroid with word)

public class TutorialWordSpawner : MonoBehaviour
{
    public GameObject wordPrefab; 
    public Canvas canvas; 
    public Sprite[] asteroidSprites;

    public TutorialWordDisplay SpawnWord()
    {
        //References
        GameObject wordObj = Instantiate(wordPrefab, canvas.transform);
        TutorialWordDisplay wordDisplay = wordObj.GetComponentInChildren<TutorialWordDisplay>();

        SpriteRenderer asteroidSpriteRenderer = wordObj.GetComponent<SpriteRenderer>();
        RectTransform canvasRectTransform = canvas.GetComponent<RectTransform>(); 
        RectTransform wordRectTransform = wordObj.GetComponent<RectTransform>(); 

        //Assignments and Functionalities.
        //Randomizes the position within the canvas (the spawning area's limit).
        float x = Random.Range(0, canvasRectTransform.rect.width) - canvasRectTransform.rect.width / 2;
        float y = Random.Range(0, canvasRectTransform.rect.height) - canvasRectTransform.rect.height / 2;
        wordRectTransform.anchoredPosition = new Vector2(x, y);

        asteroidSpriteRenderer.sprite = asteroidSprites[Random.Range(0, asteroidSprites.Length)];

        return wordDisplay;
    }
}

the script that is attached to the instantiated prefab's child which has a 3d textmeshpro component

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

public class TutorialWordDisplay : MonoBehaviour
{
    public GameObject asteroidExplosion;
    public TextMeshPro tmpWord;

    public float scaleSpeed = 1f; // Speed at which the asteroid scales up
    public int spawnIndex;

    public TutorialWordManager wordManager;
    public TutorialWord word;
    public CampaignAudioScript campaignAudio;

    private RectTransform asteroidRectTransform;
    private SpriteRenderer asteroidSpriteRenderer;

    private void Start()
    {
        asteroidRectTransform = GetComponent<RectTransform>();
        asteroidSpriteRenderer = GetComponent<SpriteRenderer>();

        tmpWord = GetComponentInChildren<TextMeshPro>();

        campaignAudio = GameObject.FindGameObjectWithTag("Audio").GetComponent<CampaignAudioScript>();

        asteroidSpriteRenderer.sortingLayerName = "Foreground";
        asteroidSpriteRenderer.sortingOrder = spawnIndex-1;

        tmpWord.sortingLayerID = SortingLayer.NameToID("Foreground");
        tmpWord.sortingOrder = spawnIndex;
    }

    public void SetWord(string _word)
    {
        tmpWord.text = _word;
    }

    public void RemoveLetter()
    {
        tmpWord.text = tmpWord.text.Remove(0, 1);
        tmpWord.color = Color.cyan;
    }

    public void RemoveTypedAsteroid()
    {
        DestroyAsteroidExplosion();
        Destroy(gameObject);
    }

    public void RemoveMissedAsteroid()
    {
        wordManager.RemoveMissedAsteroid(word);
        Destroy(gameObject);
    }

    private void Update()
    {
        ScaleAsteroid();
    }

    private void ScaleAsteroid()
    {
        // Increase the scale of the asteroid over time
        asteroidRectTransform.localScale += Vector3.one * scaleSpeed * Time.deltaTime;

        // Optionally, remove the object if it gets too large
        if (asteroidRectTransform.localScale.x > 10f) // Adjust the threshold as needed
        {
            DestroyAsteroidExplosion();
            RemoveMissedAsteroid();
        }
    }
    private void DestroyAsteroidExplosion()
    {
        // Instantiate the explosion prefab
        GameObject explosion = Instantiate(asteroidExplosion, transform.position, transform.rotation);

        // Get the current scale of the asteroid
        float asteroidScale = asteroidRectTransform.localScale.x; // Assuming uniform scaling

        // Define the scaling factors for the explosion sizes
        float mainExplosionScaleFactor = 0.8f; // Main explosion size (80% of the asteroid's size)
        float childExplosionScaleFactor = 0.2f; // Child particles size (20% of the asteroid's size)

        // Scale the main explosion particle system
        ParticleSystem explosionParticleSystem = explosion.GetComponent<ParticleSystem>();
        ParticleSystem.MainModule mainModule = explosionParticleSystem.main;
        mainModule.startSize = asteroidScale * mainExplosionScaleFactor;

        // If the explosion has child particles, scale them as well
        ParticleSystem[] childParticleSystems = explosion.GetComponentsInChildren<ParticleSystem>();
        foreach (ParticleSystem child in childParticleSystems)
        {
            ParticleSystem.MainModule childMainModule = child.main;
            childMainModule.startSizeMultiplier = asteroidScale * childExplosionScaleFactor;
        }

        // Destroy the explosion after it plays
        Destroy(explosion, explosionParticleSystem.main.duration);

        // Play explosion sound effect
        campaignAudio.PlaySFX(campaignAudio.asteroidExplosion);
    }

}

Solution

  • I only looked for the Console on the browser when I published and ran it, and there I saw the error. A script (TutorialWordSpawner) isn't initialized. The script was responsible, as the name suggests, spawning the asteroids and packing it with words (which was the TextMeshPro). I modified my code in order for it to be initialized.

    In short, always peek at the browser's console if you run into errors.

    it's [F12] or you can see it on inspect element.