0
\$\begingroup\$

I'm trying to add a sort of manager to handle all objects in a list and increase a float value that each individual member of the list has given a condition every single frame. I'm having some trouble wrapping my head around the actual code I need though.

So say I've got an OverlapCircleAll or trigger checking for tagged objects in a certain radius. These objects are then added to a List (foo).

Then, I go through foo with a for loop and declare a float value x for each object.

What I need is for each object's x to increase when the object is also on another list, bar.

So something like this:

for (int i = 0; i < foo.Count; i++)
{
     float x;
     //or float x = 0;?

     if (bar.Contains(foo[i]))
     {
          x += 1f;
     }
}

The problem is, I can't figure out how to make the value of x persist each loop. This function is called in Update() so the idea is that the longer an object is in both foo and bar, the higher its value of x is. I don't know how to save the value of x for the next loop though. Ideally something like:

for (int i = 0; i < foo.Count; i++)
{
     float x;

     if (lastX != null)
     {
          x = lastX;
     }
     else
     {
          x = 0;
     }

     if (bar.Contains(foo[i]))
     {
          x += 1f;
     }

     float lastX = x;
}

But I don't know a) how to save lastX for each object in the list and b) set x to lastX (because for each loop it creates a lastX).

I thought about storing each x in an array of floats and calling the corresponding array[i] to foo[i] to get x, but if I remove something from the list then the array will become desynchronised with the list and all the x values will get muddled up.

What is the correct way to go about this?

\$\endgroup\$
0
\$\begingroup\$

The correct way is very different at times.

Change variable scope

In the first part of the code you use float x; inside the for loop. This means x is in the scope of the for loop block, it is recreated every loop.

You can change the scope by declaring x outside of the loop, then it is recreated each (assumed) Update call. Since you would want x to persist between calls to Update you need to move it outside of it (change scope). This makes x a class variable (there are different names for that too) and looks like this:

public class Example : MonoBehaviour
{
    private float x = 0f;

    void Update()
    {
        for(...) {...}
    }
}

Keeping values where they belong to

Your second problem is a different story. For each element in your list you need a value x bounded to that element. This strongly suggests that x is part of that element. A good way to solve this is to add the float x to whatever type your elements are. If the elements are objects of one of your own classes, you can just add a new variable x to this class. Then access it using

foo[i].x

If the elements are objects of built in unity classes you can create a Wrapper class along the lines of:

public class MyElements
{
    public float x;
    public GameObject originalElement; // assumption...
}

Then when filling your list/array you fill it with MyElements.

All in all this is a basic C#/programming problem which is not related to game development. You can learn how to do this in various tutorials/books or other resources. If you need assistance, update your question or post a new one (preferrably on a suitable stackexchange site).

Final note

As you realized, it is difficult to properly handle a parallel list of x. No question it can be done but it is very error prone.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks a ton, this helped a lot. I made a wrapper class and everything's working exactly how I want it to. Thanks for the in-depth response! I realise now I probably should have put this on StackOverflow or something, my bad ahaha \$\endgroup\$
    – Cube ok
    Apr 26 '20 at 6:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.