Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question with matching Sprite in Sign with Sprite in Bag, if match then score is higher. Working: ❌

Discussion in '2D' started by simice, Aug 5, 2023.

  1. simice

    simice

    Joined:
    May 28, 2023
    Posts:
    7
    This game is an educational game that helps children with Arabic letters. Now instead of using TextMeshPro, I made the Arabic sprite sheet with all 28 letters. It spawns 28 random bags, all with different sprites each.

    Now, the sign displays one random sprite and it's the job of the player to catch the bag that has the same sprite as the one that the sign displays. Now, when that happens it increases your score variable by 1, else it decreases by 1. With the inclusion of a timer 1 minute and decreases and a slider. Now, that you can visualize the Unity 2021 game.

    All I want to know is that is my script possible. I have no errors but is it possible to make something like that because every time I test it out nothing happens?
    30.png

    31.png

    I displayed the scripts I used:
    SpriteClonerScript: (Works, and generates bags perfectly, however it does not know how to differentiate and find out which bag sprite matches with the sign sprite)
    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. public class SpriteClonerScript : MonoBehaviour
    4. {
    5.     public GameObject barrelPrefab; // Prefab of the Barrel(1) sprite
    6.     public Color[] arrayColors; // Array of colors to choose from
    7.     public Sprite bagSprite; // Reference to the Bag sprite
    8.     public Material unlitDefaultMaterial; // Reference to the Sprite_Unlit_Default material
    9.     public Sprite[] arabicLetterSprites; // Array of Arabic letter sprites
    10.     public float cloneProbability = 0.5f; // Probability of a bag clone (20%)
    11.     private GameManager gameManager; // Reference to the GameManager script
    12.     private void Start()
    13.     {
    14.         gameManager = FindObjectOfType<GameManager>(); // Find the GameManager script in the scene
    15.         StartCoroutine(CloneSpritesCoroutine());
    16.     }
    17.     private IEnumerator CloneSpritesCoroutine()
    18.     {
    19.         while (true)
    20.         {
    21.             // Clone the Barrel(1) sprite
    22.             GameObject cloneBarrel = Instantiate(barrelPrefab);
    23.             // Get the SpriteRenderer component from the clone (Barrel(1) sprite)
    24.             SpriteRenderer barrelSpriteRenderer = cloneBarrel.GetComponent<SpriteRenderer>();
    25.             // Set alpha to 255 (fully visible)
    26.             Color newColor = barrelSpriteRenderer.color;
    27.             newColor.a = 1f;
    28.             barrelSpriteRenderer.color = newColor;
    29.             // Set random color for the Barrel(1) sprite
    30.             int randomColorIndex = Random.Range(0, arrayColors.Length);
    31.             barrelSpriteRenderer.color = arrayColors[randomColorIndex];
    32.             // Set the Bag sprite and material for the cloned sprite
    33.             SpriteRenderer cloneSpriteRenderer = cloneBarrel.GetComponentInChildren<SpriteRenderer>();
    34.             if (cloneSpriteRenderer != null)
    35.             {
    36.                 cloneSpriteRenderer.sprite = bagSprite;
    37.                 cloneSpriteRenderer.material = unlitDefaultMaterial;
    38.             }
    39.             // Set alpha to 255 (fully visible) for the cloned sprite
    40.             newColor = cloneSpriteRenderer.color;
    41.             newColor.a = 1f;
    42.             cloneSpriteRenderer.color = newColor;
    43.             // Set the scale of the clone
    44.             cloneBarrel.transform.localScale = new Vector3(0.07123201f, 0.07123201f, 1f);
    45.             // Set the position of the clone to random x within [-5.3, 6] and y at 11.50
    46.             float randomX = Random.Range(-5.3f, 6f);
    47.             cloneBarrel.transform.position = new Vector3(randomX, 11.50f, 0f);
    48.             // Set random Arabic letter sprite for the letters inside the Barrel(1) sprite
    49.             SpriteRenderer[] letterRenderers = cloneBarrel.GetComponentsInChildren<SpriteRenderer>();
    50.             foreach (var letterRenderer in letterRenderers)
    51.             {
    52.                 if (letterRenderer.name.Contains("Letter")) // Replace "Letter" with the actual name of the letter SpriteRenderers.
    53.                 {
    54.                     int randomLetterIndex = Random.Range(0, arabicLetterSprites.Length);
    55.                     letterRenderer.sprite = arabicLetterSprites[randomLetterIndex];
    56.                 }
    57.             }
    58.             // Clone probability check
    59.             if (Random.value < cloneProbability)
    60.             {
    61.                 // Clone the Bag sprite
    62.                 GameObject cloneBag = Instantiate(barrelPrefab);
    63.                 // Set the Bag sprite and material for the cloned bag sprite
    64.                 SpriteRenderer bagSpriteRenderer = cloneBag.GetComponentInChildren<SpriteRenderer>();
    65.                 if (bagSpriteRenderer != null)
    66.                 {
    67.                     bagSpriteRenderer.sprite = bagSprite;
    68.                     bagSpriteRenderer.material = unlitDefaultMaterial;
    69.                 }
    70.                 // Set alpha to 255 (fully visible) for the cloned bag sprite
    71.                 newColor = bagSpriteRenderer.color;
    72.                 newColor.a = 1f;
    73.                 bagSpriteRenderer.color = newColor;
    74.                 // Set the scale of the cloned bag
    75.                 cloneBag.transform.localScale = new Vector3(0.07123201f, 0.07123201f, 1f);
    76.                 // Set the position of the cloned bag to the same position as the barrel
    77.                 cloneBag.transform.position = cloneBarrel.transform.position;
    78.                 // Destroy the cloned bag after 3 seconds
    79.                 Destroy(cloneBag, 3f);
    80.                 // Update the correct bag sprite to match the sign
    81.                 gameManager.UpdateCorrectBagSprite();
    82.             }
    83.             // Destroy the clone after 30 seconds
    84.             Destroy(cloneBarrel, 30f);
    85.             // Wait for 5 seconds before creating the next clone
    86.             yield return new WaitForSeconds(3f);
    87.         }
    88.     }
    89. }
    90.  
    ___________________________________________
    BagCollision script (works but never increases score to the right bag)
    Code (CSharp):
    1. using UnityEngine;
    2. public class BagCollision : MonoBehaviour
    3. {
    4.     private GameManager gameManager;
    5.     private void Start()
    6.     {
    7.         gameManager = FindObjectOfType<GameManager>();
    8.     }
    9.     private void OnTriggerEnter2D(Collider2D other)
    10.     {
    11.         if (other.CompareTag("Pickable"))
    12.         {
    13.             SpriteRenderer bagSpriteRenderer = other.GetComponentInChildren<SpriteRenderer>();
    14.             SpriteRenderer signSpriteRenderer = gameManager.sign.GetComponent<SpriteRenderer>();
    15.             if (bagSpriteRenderer != null && signSpriteRenderer != null && bagSpriteRenderer.sprite == signSpriteRenderer.sprite)
    16.             {
    17.                 // Correct bag collided
    18.                 gameManager.IncreaseScore();
    19.                 Destroy(other.gameObject);
    20.             }
    21.             else
    22.             {
    23.                 // Incorrect bag collided
    24.                 gameManager.DecreaseTimeAndScore();
    25.                 Destroy(other.gameObject);
    26.             }
    27.         }
    28.     }
    29. }
    ___________________________________________
    GameManager script (Works as intended with the timers, and time deduction; score does not increase and we want it so if score var = 0 then it does not deduct else it does and I want it to also tell apart which bag matches the sign and which does not)

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.SceneManagement;
    3. using TMPro;
    4. using UnityEngine.UI;
    5. using System.Collections;
    6. public class GameManager : MonoBehaviour
    7. {
    8.     public TMP_Text scoreText;
    9.     public TMP_Text timeText;
    10.     public GameObject gameOverPanel;
    11.     public Slider timeSlider;
    12.     public Image sliderFill; // Reference to the slider's fill image
    13.     public GameObject bagPrefab; // Reference to the Bag prefab
    14.     public Sprite[] letterSprites; // Array of letter sprites to assign to the sign
    15.     public GameObject sign; // Reference to the sign GameObject
    16.     public Gradient timeSliderGradient; // Gradient for the timer slider handle color
    17.     public float initialCloneProbability = 0.5f;
    18.     public float minCloneProbability = 0.1f;
    19.     public float cloneProbabilityDecreaseRate = 0.05f;
    20.     public float timeToDecreaseProbability = 10f;
    21.     private float currentCloneProbability;
    22.     private GameObject correctBag; // Reference to the correct bag
    23.     private int score;
    24.     private float gameTime = 60f; // Total game time in seconds
    25.     private float currentGameTime;
    26.     private void Start()
    27.     {
    28.         score = 0;
    29.         currentGameTime = gameTime;
    30.         currentCloneProbability = initialCloneProbability;
    31.         UpdateScoreText();
    32.         // Set the slider min and max values
    33.         timeSlider.minValue = 0;
    34.         timeSlider.maxValue = gameTime;
    35.         timeSlider.value = gameTime;
    36.         UpdateTimeSlider();
    37.         StartCoroutine(DecreaseTime());
    38.         GenerateCorrectBag(); // Generate the initial correct bag
    39.         // Assign a random letter sprite to the sign sprite
    40.         if (sign != null)
    41.         {
    42.             SpriteRenderer signSpriteRenderer = sign.GetComponent<SpriteRenderer>();
    43.             if (signSpriteRenderer != null && letterSprites.Length > 0)
    44.             {
    45.                 int randomIndex = Random.Range(0, letterSprites.Length);
    46.                 signSpriteRenderer.sprite = letterSprites[randomIndex];
    47.             }
    48.         }
    49.         StartCoroutine(GenerateCorrectBagWithDelay());
    50.     }
    51.     private IEnumerator GenerateCorrectBagWithDelay()
    52.     {
    53.         yield return new WaitForSeconds(1f);
    54.         GenerateCorrectBag();
    55.     }
    56.     private IEnumerator DecreaseTime()
    57.     {
    58.         while (currentGameTime > 0)
    59.         {
    60.             yield return new WaitForSeconds(1f);
    61.             currentGameTime--;
    62.             UpdateTimeSlider();
    63.             // Decrease the cloning probability over time
    64.             if (currentGameTime < timeToDecreaseProbability)
    65.             {
    66.                 currentCloneProbability = Mathf.Max(minCloneProbability, currentCloneProbability - cloneProbabilityDecreaseRate);
    67.             }
    68.         }
    69.         // Timer is 0, show the GameOver screen
    70.         gameOverPanel.SetActive(true);
    71.         CanvasGroup canvasGroup = gameOverPanel.GetComponent<CanvasGroup>();
    72.         canvasGroup.alpha = 1f; // Make the GameOver screen fully visible
    73.     }
    74.     public void IncreaseScore()
    75.     {
    76.         score++;
    77.         UpdateScoreText();
    78.     }
    79.     public void DecreaseTimeAndScore()
    80.     {
    81.         currentGameTime -= 5f;
    82.         score = Mathf.Max(0, score - 5); // Decrease the score, but ensure it doesn't go below zero
    83.         UpdateTimeSlider();
    84.         UpdateScoreText();
    85.     }
    86.     private void UpdateScoreText()
    87.     {
    88.         scoreText.text = "Score: " + score;
    89.     }
    90.     private void UpdateTimeSlider()
    91.     {
    92.         if (timeSlider != null && sliderFill != null)
    93.         {
    94.             timeSlider.value = currentGameTime;
    95.             timeText.text = "Time: " + FormatTime(currentGameTime);
    96.             // Update the slider fill color based on the time remaining
    97.             sliderFill.color = timeSliderGradient.Evaluate(timeSlider.normalizedValue);
    98.         }
    99.     }
    100.     private string FormatTime(float time)
    101.     {
    102.         int minutes = Mathf.FloorToInt(time / 60f);
    103.         int seconds = Mathf.FloorToInt(time % 60f);
    104.         return string.Format("{0:0}:{1:00}", minutes, seconds);
    105.     }
    106.     public void GenerateCorrectBag()
    107.     {
    108.         SpriteRenderer signSpriteRenderer = sign.GetComponent<SpriteRenderer>();
    109.         Sprite signSprite = signSpriteRenderer.sprite;
    110.         GameObject[] bags = GameObject.FindGameObjectsWithTag("Pickable");
    111.         GameObject foundCorrectBag = null;
    112.         string signSpriteName = signSprite.name; // Get the name of the sign sprite
    113.         foreach (GameObject bag in bags)
    114.         {
    115.             Sprite bagSprite = bag.GetComponentInChildren<SpriteRenderer>().sprite;
    116.             if (bagSprite != null && bagSprite.name == signSpriteName) // Compare sprite names
    117.             {
    118.                 foundCorrectBag = bag;
    119.                 break;
    120.             }
    121.         }
    122.         if (foundCorrectBag != null)
    123.         {
    124.             correctBag = foundCorrectBag;
    125.         }
    126.     }
    127.     public void UpdateCorrectBagSprite()
    128.     {
    129.         if (correctBag != null)
    130.         {
    131.             SpriteRenderer correctBagSpriteRenderer = correctBag.GetComponentInChildren<SpriteRenderer>();
    132.             SpriteRenderer signSpriteRenderer = sign.GetComponent<SpriteRenderer>();
    133.             correctBagSpriteRenderer.sprite = signSpriteRenderer.sprite;
    134.         }
    135.     }
    136.     private void Update()
    137.     {
    138.         // Check for game over condition
    139.         if (currentGameTime <= 0)
    140.         {
    141.             gameOverPanel.SetActive(true);
    142.             CanvasGroup canvasGroup = gameOverPanel.GetComponent<CanvasGroup>();
    143.             canvasGroup.alpha = 1f; // Make the GameOver screen fully visible
    144.         }
    145.         // Check if the correct bag is still valid
    146.         if (correctBag != null && correctBag.GetComponentInChildren<SpriteRenderer>().sprite != null)
    147.         {
    148.             // The correct bag is still valid, no action needed
    149.         }
    150.         else
    151.         {
    152.             // The correct bag was picked or destroyed, generate a new one
    153.             GenerateCorrectBag();
    154.         }
    155.     }
    156.     public float GetCloneProbability()
    157.     {
    158.         return currentCloneProbability;
    159.     }
    160. }
    ___________________________________________
    Unity 2021, 2D
    This is my hierarchy
    -Main Camera
    -Canvas
    -EventSystem
    -Animation
    -SpriteText
    -SpriteToCLone
    -Barrel (1) | Prefab
    -LetterSign [ArabicSign, Slider, SignWood, Text (TMP), Text (TMP) (1)]
    - Game Manager
    -GameOver
    ___________________________________________
    In library we got Assets > Scenes > GameOne > ArabicLetter
    Which is a multiple sprite sheet consisting of 28 letters.
    I have no error at Unity and I tried following tutorials but there is no specific matching catch game.
    Any suggestions? Thank you! :)
    Sorry if tags, or location is wrong, I'm new to the forums! :D
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    That just means you wrote a bug.

    Time to start debugging! Here is how you can begin your exciting new debugging adventures:

    You must find a way to get the information you need in order to reason about what the problem is.

    Once you understand what the problem is, you may begin to reason about a solution to the problem.

    What is often happening in these cases is one of the following:

    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is
    - you're getting an error or warning and you haven't noticed it in the console window

    To help gain more insight into your problem, I recommend liberally sprinkling
    Debug.Log()
    statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the names of the GameObjects or Components involved?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as
    Debug.Log("Problem!",this);


    If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

    You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

    You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    Visit Google for how to see console output from builds. If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer for iOS: https://forum.unity.com/threads/how-to-capturing-device-logs-on-ios.529920/ or this answer for Android: https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/

    If you are working in VR, it might be useful to make your on onscreen log output, or integrate one from the asset store, so you can see what is happening as you operate your software.

    Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

    If your problem is with OnCollision-type functions, print the name of what is passed in!

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494

    "When in doubt, print it out!(tm)" - Kurt Dekker (and many others)

    Note: the
    print()
    function is an alias for Debug.Log() provided by the MonoBehaviour class.