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

Bug Supermarket List Issue (Except?, Contains?)

Discussion in 'Scripting' started by AlexNikolay, Oct 8, 2023.

  1. AlexNikolay

    AlexNikolay

    Joined:
    Mar 1, 2022
    Posts:
    27
    Hello! Im trying to make a supermarket game, but im having the same issue for a week but I cant figure how to do it. So before telling the issue, there are two lists, one is for the available products of the store and the other one are the products that the client has chosen and both of the lists are a gameobject list. So my main issue is if the client list (product list) has chosen "milk" and "meat" but the available list only has "milk", I cant make the client go only to the available product (Im using navmesh for the client) and it tells me that it doesnt contain milk in the available products, which is very weird. Here is the code that I have right now:

    Code (CSharp):
    1. if (agent != null)
    2.         {
    3.             foreach(GameObject missing in productList.Except(availableProducts).ToList())
    4.             {
    5.                 foreach(GameObject product in productList)
    6.                 {
    7.                     if (availableProducts.Count > 0)
    8.                     {
    9.                         productList.Remove(missing);
    10.                         agent.SetDestination(product.gameObject.transform.position);
    11.                     }
    12.                     else
    13.                     {
    14.                         print("There is nothing");
    15.                     }
    16.                 }
    17.             }
    18.         }
    I made this script, but it doesnt work, its telling me the same thing, that milk doesnt exists in available and the navmesh just goes forward, not to the product.
     
  2. samana1407

    samana1407

    Joined:
    Aug 23, 2015
    Posts:
    74
    First, you need the 'Intersect' method, not 'Except,' but even that is not necessary. What you need here is to create a system of waiting while the clietn goes and takes the product, then checks the list for the next one and goes to them, something like that

    Code (CSharp):
    1.  
    2. foreach (var product in clientList)
    3. {
    4.     if (storeList.Contains(product))
    5.     {
    6.         agent.SetDestination(product.gameObject.transform.position);
    7.  
    8.         // Wait until the agent arrives and collects the product.
    9.  
    10.         // Suddenly, we didn't manage to reach first
    11.  
    12.         if (storeList.Contains(product))
    13.         {
    14.             // Whoever got there first, took it
    15.             storeList.Remove(product);
    16.         }  
    17.     }
    18. }
    19.  
     
  3. AlexNikolay

    AlexNikolay

    Joined:
    Mar 1, 2022
    Posts:
    27
    Hello! Thanks for replying! but this doesnt solve my problem, I think that i didnt explain myself well, so what I meant was that if the clientList has selected "Milk" and "Meat", like an example, and the available products list, which is the available products that are in the supermarket, it has only "Meat" how can i go through all the variables inside and check if the clientList contains AT LEAST one of the product that the available product list has, which in this case would be "Meat", because with "contains" it just doesnt work, or else im doing something wrong which I dont know.
     
  4. samana1407

    samana1407

    Joined:
    Aug 23, 2015
    Posts:
    74
    You explained it perfectly in your first post. You just need the Intersect method, not the Except method.

    Code (CSharp):
    1. List<string> availableProductsList = new() { "potato", "meat", "tomato", "onion", "bread" };
    2. List<string> clientList = new() { "meat", "milk", "onion" };
    3.  
    4. // Products from the client's list, which are also in the store
    5. var whatICanBuy = clientList.Intersect(availableProductsList);
    6.  
    7. if (whatICanBuy.Count() != 0)
    8. {
    9.     // Great, I can buy something, it will be
    10.     foreach (var item in whatICanBuy)
    11.     {
    12.         print(item); // meat, onion
    13.     }
    14. }
    15. else
    16. {
    17.     // It's a pity that the store doesn't have anything I need...
    18. }
     
  5. AlexNikolay

    AlexNikolay

    Joined:
    Mar 1, 2022
    Posts:
    27
    Hey again! Thanks for repyling! I tried your code, but it just doesnt work... I think its because im using Gameobjects instead of strings, which maybe that is the reason that it wont work. I could make it with strings but if I do so, then I wont know how to search the product(gameobject), maybe using the .name of the gameobject and compare it with the string... I dont know, im lost at this moment and im trying to even use chat gpt to help me, but none of that... Thanks for trying to help!
     
  6. samana1407

    samana1407

    Joined:
    Aug 23, 2015
    Posts:
    74
    Yes, you need to somehow associate objects on the scene with the product. This can be done in various ways. Of course, you can use names or tags, but it's better to add a script for each product that contains all the information about that product. For example, you can create an enum with product categories and then create a standard MonoBehaviour script. For each object, set the appropriate product category in the inspector.

    Let's assume you have such an enum:
    Code (CSharp):
    1. public enum ProductName
    2. {
    3.     Undefined, Bread, Potato, Tomato, Cucumber, Onion, Juice, Toothbrush, Matches, Tights
    4. }
    And such a MonoBehaviour script that you'll add to all your products and set their product type:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Product : MonoBehaviour
    4. {
    5.     public ProductName Name;
    6. }
    -------------------------------------------------------
    The store should have a list of products like this:
    Code (CSharp):
    1. public List<Product> AvailableProducts;
    You need to drag and drop all the products available in the store from the scene into this list. The player should have two lists: one for the names of products (ProductName) they want to buy and another for the actual purchases (Product) where they will add their purchases.

    In general, the task is quite complex, and I can't provide a one-size-fits-all solution without knowing more about how your game is structured. There are many nuances to consider. It's not clear whether only one player will make purchases or if there are multiple customers competing for items in the store, among other details.
     
    Nad_B likes this.
  7. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,843
    Adding to the above, you could use scriptable objects to define different products in lieu of an enum. Then this scriptable object can be referenced in a monobehaviour and can be used to compare if two different game objects/monobehaviours are the 'same' product by comparing those references.

    Just wanted to suggest this as once you get to any appreciable number of products then enums stop being particularly scalable.
     
    Nad_B likes this.
  8. AlexNikolay

    AlexNikolay

    Joined:
    Mar 1, 2022
    Posts:
    27
    Thanks for replying, your help is giving me more ideas an stuff!
     
  9. AlexNikolay

    AlexNikolay

    Joined:
    Mar 1, 2022
    Posts:
    27
    Thanks for replying! I guess im going to do that, because its the best option, I guess