Search Unity

Question Text doesn't popup

Discussion in 'Scripting' started by Unitkiv, Feb 1, 2024.

  1. Unitkiv

    Unitkiv

    Joined:
    Jun 14, 2022
    Posts:
    71
    Hi,
    I want the units (workers) go to the nearest resources, wait there till 5 seconds, then return to nearest resourcebox. For this, I used the switch statement like this:
    Code (CSharp):
    1.     private void Start()
    2.     {
    3.         AllObjects = GameObject.FindGameObjectsWithTag("OBJ");
    4.         resourceBox = GameObject.FindGameObjectsWithTag("ResourceBox");  
    5.     }
    6.  
    7.     private void Awake()
    8.     {
    9.         state = State.Idle;
    10.     }
    11.     private void Update()
    12.     {
    13.         switch (state)
    14.         {
    15.             case State.Idle:
    16.                 state = State.MovingToResource;
    17.                 break;
    18.             case State.MovingToResource:
    19.  
    20.                 float step = speed * Time.deltaTime;
    21.  
    22.                 for (int i = 0; i < AllObjects.Length; i++)
    23.                 {
    24.                     distance = Vector3.Distance(this.transform.position, AllObjects[i].transform.position);
    25.  
    26.                     if (distance < nearestDistance)
    27.                     {
    28.                         nearestOBJ = AllObjects[i];
    29.                         nearestDistance = distance;
    30.                         transform.position = Vector3.MoveTowards(transform.position, AllObjects[i].transform.position, step);
    31.                        
    32.                         state = State.GatheringResource;
    33.                     }
    34.                 }
    35.                
    36.                 break;
    37.             case State.GatheringResource:
    38.                 timer -= Time.deltaTime;
    39.  
    40.                 if (timer <= 0)
    41.                 {
    42.                     state = State.MovingToStorage;
    43.                 }
    44.                  break;
    45.             case State.MovingToStorage:
    46.                
    47.                 float stepR = speed * Time.deltaTime;          
    48.  
    49.                     for (int i = 0; i < resourceBox.Length; i++)
    50.                     {
    51.                         distance_R = Vector3.Distance(this.transform.position, resourceBox[i].transform.position);
    52.                    
    53.                         if (distance_R < nearestDistance_R)
    54.                         {
    55.                        
    56.                         nearestOBJ = resourceBox[i];
    57.                             nearestDistance_R = distance_R;
    58.                      
    59.                             transform.position = Vector3.MoveTowards(transform.position, resourceBox[i].transform.position, stepR);
    60.                        
    61.                             goldInventoryAmount = 0;
    62.                             state = State.Idle;
    63.                          
    64.                         }
    65.                     }
    66.                 break;
    67.         }
    68.     }
    69. }
    70.  
    Though I've defined the timer at State.GatheringResource: , at start, the workers wait for 5 seconds before they head to resources and stay put at the resources.
     
  2. samana1407

    samana1407

    Joined:
    Aug 23, 2015
    Posts:
    227
    I am a bit concerned not so much about the five-second issue but rather want to clarify overall whether your code is currently functioning correctly, and if workers indeed go to resources and back?

    Because judging by the code of several cases, for example, this one
    Code (CSharp):
    1. case State.MovingToResource:
    2.  
    3.     float step = speed * Time.deltaTime;
    4.  
    5.     for (int i = 0; i < AllObjects.Length; i++)
    6.     {
    7.         distance = Vector3.Distance(this.transform.position, AllObjects[i].transform.position);
    8.  
    9.         if (distance < nearestDistance)
    10.         {
    11.             nearestOBJ = AllObjects[i];
    12.             nearestDistance = distance;
    13.             transform.position = Vector3.MoveTowards(transform.position, AllObjects[i].transform.position, step);
    14.  
    15.             state = State.GatheringResource;
    16.         }
    17.     }
    18.  
    19.     break;
    or that one

    Code (CSharp):
    1. case State.MovingToStorage:
    2.  
    3.     float stepR = speed * Time.deltaTime;
    4.  
    5.     for (int i = 0; i < resourceBox.Length; i++)
    6.     {
    7.         distance_R = Vector3.Distance(this.transform.position, resourceBox[i].transform.position);
    8.  
    9.         if (distance_R < nearestDistance_R)
    10.         {
    11.  
    12.             nearestOBJ = resourceBox[i];
    13.             nearestDistance_R = distance_R;
    14.  
    15.             transform.position = Vector3.MoveTowards(transform.position, resourceBox[i].transform.position, stepR);
    16.  
    17.             goldInventoryAmount = 0;
    18.             state = State.Idle;
    19.  
    20.         }
    21.     }
    22.     break;
    it seems that the worker iterates through all resources and takes a step towards the one that is closer within a certain distance. HOWEVER, in principle, each resource from the list could be closer than a certain distance, and the worker would take a step towards one resource first, then towards another resource, i.e., moving back and forth. Moreover, I see that after the first step, another case immediately follows. So, the implementation of the worker's movements is somewhat unclear... Well, never mind.
     
  3. samana1407

    samana1407

    Joined:
    Aug 23, 2015
    Posts:
    227
    I see that your problem is still unresolved; you created a similar topic a little while ago. Perhaps my previous response deterred you, so I'll try to refine the idea behind your code a bit.

    In fact, this approach is not very flexible, but based on using a switch statement, it might look something like this:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Unitkiv : MonoBehaviour
    4. {
    5.     public float nearestDistance = 5f;
    6.     public float speed = 1f;
    7.     public float gatheringTime = 2f;
    8.  
    9.     private Transform nearestResource;
    10.     private Transform nearestStorage;
    11.     private float gatheringElapsedTimer;
    12.  
    13.     private State state;
    14.  
    15.     enum State
    16.     {
    17.         Idle,
    18.         MovingToResource,
    19.         GatheringResource,
    20.         MovingToStorage
    21.     }
    22.  
    23.     private void Awake()
    24.     {
    25.         state = State.Idle;
    26.     }
    27.  
    28.     private void Update()
    29.     {
    30.         switch (state)
    31.         {
    32.             case State.Idle:
    33.                 nearestResource = FindNearestResource();
    34.  
    35.                 if (nearestResource != null)
    36.                 {
    37.                     state = State.MovingToResource;
    38.                 }
    39.                 else
    40.                 {
    41.                     Debug.Log("No nearby resources were found.");
    42.                 }
    43.  
    44.                 break;
    45.  
    46.  
    47.             case State.MovingToResource:
    48.  
    49.                 bool hasReachedResource = MoveTo(nearestResource);
    50.  
    51.                 if (hasReachedResource)
    52.                 {
    53.                     nearestResource = null;
    54.  
    55.                     gatheringElapsedTimer = 0;
    56.                     state = State.GatheringResource;
    57.                 }
    58.  
    59.                 break;
    60.  
    61.  
    62.             case State.GatheringResource:
    63.  
    64.                 gatheringElapsedTimer += Time.deltaTime;
    65.  
    66.                 if (gatheringElapsedTimer >= gatheringTime)
    67.                 {
    68.                     nearestStorage = FindNearestStorage();
    69.  
    70.                     if (nearestStorage != null)
    71.                     {
    72.                         state = State.MovingToStorage;
    73.                     }
    74.                     else
    75.                     {
    76.                         Debug.Log("No nearby storages were found.");
    77.                     }
    78.                 }
    79.  
    80.                 break;
    81.  
    82.  
    83.             case State.MovingToStorage:
    84.  
    85.                 bool hasReachedStorage = MoveTo(nearestStorage);
    86.  
    87.                 if (hasReachedStorage)
    88.                 {
    89.                     nearestStorage = null;
    90.                     state = State.Idle;
    91.                 }
    92.  
    93.                 break;
    94.         }
    95.     }
    96.  
    97.     private Transform FindNearestResource() => FindNearestByTag("ResourceBox");
    98.     private Transform FindNearestStorage() => FindNearestByTag("OBJ");
    99.  
    100.  
    101.     // Select the closest target among those that can be reached.
    102.     private Transform FindNearestByTag(string tag)
    103.     {
    104.         float minDist = float.MaxValue;
    105.         Transform nearestTransform = null;
    106.  
    107.         foreach (GameObject resource in GameObject.FindGameObjectsWithTag(tag))
    108.         {
    109.             float dist = (resource.transform.position - transform.position).sqrMagnitude;
    110.  
    111.             if (dist < nearestDistance * nearestDistance && dist < minDist)
    112.             {
    113.                 minDist = dist;
    114.                 nearestTransform = resource.transform;
    115.             }
    116.         }
    117.  
    118.         return nearestTransform;
    119.  
    120.     }
    121.  
    122.     // Move towards the target. Returns true if reached the target and false if not yet reached.
    123.     private bool MoveTo(Transform target)
    124.     {
    125.         transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
    126.  
    127.         return (transform.position - target.position).sqrMagnitude == 0;
    128.     }
    129. }
    130.  
     
    Unitkiv likes this.
  4. Unitkiv

    Unitkiv

    Joined:
    Jun 14, 2022
    Posts:
    71
    I would examine your code... Thank you for your time and thanks a lot:)
     
    samana1407 likes this.
  5. Unitkiv

    Unitkiv

    Joined:
    Jun 14, 2022
    Posts:
    71
    I want it to popup with a text that says how many resources left as the worker return to Storage. For this, made a script which holds the resource (I used the Codemonkey's Utility for popping up the text as the worker return on the way) :
    Code (CSharp):
    1. using CodeMonkey;
    2.  
    3. public class ResourceNode
    4. {
    5.     private Transform resourceNodeTransform;
    6.     private int resourceAmount;
    7.  
    8.     public ResourceNode(Transform resourceNodeTransform)
    9.     {
    10.         this.resourceNodeTransform = resourceNodeTransform;
    11.         resourceAmount = 3;
    12.     }
    13.  
    14.     public Vector3 GetPosition()
    15.     {
    16.         return resourceNodeTransform.position;
    17.     }
    18.  
    19.     public void GrabResource()
    20.     {
    21.         resourceAmount -= 1;
    22.         CMDebug.TextPopupMouse("resourceAmount: " + resourceAmount);
    23.     }
    24.  
    25.     public bool HasResource()
    26.     {
    27.         return resourceAmount > 0;
    28.     }
    29. }
    30.  
    And in the UnitMove script I've changed the script like this:
    Code (CSharp):
    1.   case State.MovingToResource:
    2.    
    3.       bool hasReachedResource = MoveTo(nearestResource);
    4.    
    5.       if (hasReachedResource)
    6.       {
    7.           gatheringElapsedTimer = 0;
    8.        
    9.           state = State.GatheringResource;
    10.               // the changes that is made
    11.           resourceNode.GetPosition();
    12.       }
    13.  
    14.       break;
    15.  
    16.   case State.GatheringResource:
    17.    
    18.       gatheringElapsedTimer += Time.deltaTime;
    19.    
    20.       if (gatheringElapsedTimer >= gatheringTime)
    21.       {
    22.           nearestStorage = FindNearestStorage();
    23.        
    24.           if (nearestStorage != null)
    25.           {
    26.               state = State.MovingToStorage;
    27.               // the changes that is made
    28.               resourceNode.GetPosition();
    29.               resourceNode.GrabResource();
    30.           }
    31.           else
    32.           {
    33.               Debug.Log("No nearby storages were found.");
    34.           }
    35.       }
    36.    
    37.       break;
    But the text won't popup.
     
  6. samana1407

    samana1407

    Joined:
    Aug 23, 2015
    Posts:
    227
    Your calls to the GetPosition() method on lines 11 and 28 are entirely nonsensical. This method simply returns a Vector3, yet you don't store its value anywhere. Additionally, the rationale behind calling this method is unclear, and it's unclear what you expected to achieve.

    As for displaying the popup window using CMDebug.TextPopupMouse, I'm unable to provide guidance as I'm not familiar with its operational nuances. It's possible that some preliminary setup may be required.
     
    Unitkiv likes this.