Compare two array of Vector3 form initial to final position Gameobject

Hello everyone!

I have read dozens of discussions about compare two array, but now my brain is tilt!!

I am creating a series of basic scripts for my OGM level. In this case there is a enigma based on the game of fifteen. I managed to move and mix gameobject cubes and now I have to create a solved game.

To decide when the game is over or resolved, I thought of taking the initial position of each individual cube with a Vector3 array…

    void Start()
    {
        go = GameObject.FindGameObjectsWithTag("TileCube");
        foreach (GameObject obj in go)
        {
            goPos = obj.transform.position;
        }

        oldGopos = new Vector3[] { goPos };
    }

Also when mixing the cubes, I take their position with a vector3 array. To determine the random of the cubes I use two pseudo IDs; the first public int id; it’s used for every single cube (from 1 to 15).

The second pseudo id’s private int[] compareNumbID = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; it’s a array int used for base random.

    void RamdomPosCube()
    {
        for (int i = 0; i < compareNumbID.Length; i++)
        {
            int temp = compareNumbID[i];
            int IDIndex = Random.Range(0, compareNumbID.Length);
            compareNumbID[i] = compareNumbID[IDIndex];
            compareNumbID[IDIndex] = temp;

            if (id == temp)
            {
                xtemp = transform.localPosition.x;
                ytemp = transform.localPosition.y;
                transform.localPosition = new Vector3(slot.transform.position.x, slot.transform.position.y, 0);
                slot.transform.position = new Vector3(xtemp, ytemp, 0);
            }
        }
        newGoPos = new Vector3[] { transform.localPosition };
    }

With void OnMouseUp() I move the cubes to solve the game.

Is’t fair how I am proceeding? Now, what I just can’t come up with is how to compare this two arrays. I have tried almost all possible solutions but without success.

Is another solution possible?

Any ideas?

Thanks for any help :slight_smile:

I didn’t really get what you meant but to compare arrays I think this would work

bool compare(T[] a, T[] b) {
    if (a.length != b.lnegth) return false;
    for (int i = 0; i < a.length; i++) {
       if (a[i] != b[i]) return false;
    }
    return true;
}
1 Like

Yes, I’ve already tried this solution, but it gives me an odd mistake “CS0246”. Both “oldGopos” and “newGoPos” are declared, but in the function mentioned above it does not work …

Then try to do instead of if (a[I] != b[i]) do if (!a[I].equals(b[i))

I repeat, it doesn’t work because “oldGopos” and “newGoPos” (the two array) are not recognized (CS0246 error)…

Sorry for double post, but there is no one who can help me ? :smile:

Could you post the method you use to compare the arrays? Otherwise, we won’t know what’s causing the errors.

1 Like

Have you defined those arrays? Your own code already references one of them. What’s the complete error? CS0246 doesn’t really make sense in this case.

1 Like

Thanks for your interest guys :slight_smile:

Below the error message:
“error CS0246: The type or namespace name ‘xxx’ could not be found (are you missing a using directive or an assembly reference?)”

I’ve definite two private Vector3 (for reference object position)

private Vector3[] oldGopos;
private Vector3[] newGoPos;

The first array is defined as below and I use a Awake Invoke:

void Awake()
    {
        go = GameObject.FindGameObjectsWithTag("TileCube");
        foreach (GameObject obj in go)
        {
            goPos = obj.transform.localPosition; // create array from object tag
        }

        oldGopos = new Vector3[] { goPos }; 
    }

The second array is defined after the random position in Start function:

private void Start()
    {
        RamdomPosCube();
        newGoPos = new Vector3[] { transform.localPosition };
    }

In debugger everything works well so I’ve two position object of array Vector3: the starting position and the position after the random. I check with print(newGoPos + "-->" + transform.localPosition + "->" + id); and print (oldGopos + "<->" + transform.localPosition + "<->" + id);.

Here the idea of comparing them was born; if the two arrays are equal (i.e. the starting position) the game is solved. Now if I place these two variables in a function, the error described appears to me. Frankly I can’t understand why. For es. if I use:

    bool CheckArray(oldGopos a, newGoPos b)
    {
        if (a.Length != b.Legth) return false;
        for (int i = 0; i < a.Length; i++)
        {
            if (a[i] != b[i]) return false;
        }
        return true;
    }

anything work because the two variable are not recognized… So my question is always the same: how do I solve the game knowing the initial position of the cubes and then compare the two arrays? …or, do you have ideas on another solution?

Thanks again :slight_smile:

This is the part that is not right. Where you have oldGopos and newGoPos, those should be the type of a and b. In this case, you can use this instead:

bool CheckArray(GameObject[] a, GameObject[] b)

Then, when you want to use this function, you type

 if(CheckArray(oldGopos, newGoPos)) // Here, we pass our arrays into the function. In the debugger, you'll see that the function parameters a and b are actually these arrays
{
  // Do something
}
1 Like

Yes, now I have no errors thanks @WallaceT_MFM . :slight_smile: The right type is Vector3 bool CheckArray(Vector3[] a, Vector3[] b). Now I try to understand if I’m on the right track…

That’s incredible… every time I call the function, Unity crashes… mah…

0_o That’s impressive. My best guess is that there’s an infinite loop somewhere. Can you post updated code?

I apologize for the late reply @WallaceT_MFM !! Below I entered the whole script.

For test create a Cube 1x1 (measure default) with Tag “TileCube” and create a Empty game object named “Slot”.
Attach the script to the cube. Create a grid 3x3 with cube placed side by side with one unit length. Delete last cube and replace with Empty game object “Slot”. In the script, in the ID field assign 1,2,3 etc for each cube.(cube01 → id 1, cube02 → id 2 ecc.)

using System.Collections.Generic;
using UnityEngine;
using System.Linq;

public class MovementCube : MonoBehaviour
{
    public GameObject slot;
    float xSlot;
    float ySlot;

    private GameObject[] go;
    private Vector3 goPos;

    private Vector3[] oldGopos;
    private Vector3[] newGoPos;

    public int id;
    private int[] compareNumbID = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

    void Awake()
    {
        go = GameObject.FindGameObjectsWithTag("TileCube");
        foreach (GameObject obj in go)
        {
            goPos = obj.transform.localPosition;
        }

        oldGopos = new Vector3[] { goPos };
        print(oldGopos + "<->" + transform.localPosition + "<->" + id);
    }

    private void Start()
    {
        RamdomPosCube();
        newGoPos = new Vector3[] { transform.localPosition };
        print(newGoPos + "-->" + transform.localPosition + "->" + id);
    }


    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            RamdomPosCube();
        }
    }


    void RamdomPosCube()
    {
        for (int i = 0; i < compareNumbID.Length; i++)
        {
            int temp = compareNumbID[i];
            int IDIndex = Random.Range(0, compareNumbID.Length);
            compareNumbID[i] = compareNumbID[IDIndex];
            compareNumbID[IDIndex] = temp;

            if (id == temp)
            {
                xSlot = transform.localPosition.x;
                ySlot = transform.localPosition.y;
                transform.localPosition = new Vector3(slot.transform.position.x, slot.transform.position.y, 0);
                slot.transform.position = new Vector3(xSlot, ySlot, 0);
            }
        }

    }


   // Your test bool function 

    bool CheckArray(Vector3[] a, Vector3[] b)
    {
        if (CheckArray(oldGopos, newGoPos))

        if (a.Length != b.Length) return false;
        for (int i = 0; i < a.Length; i++)
        {
            if (a[i] != b[i]) return false;
        }
        return true;
    }
      

    void OnMouseUp()
    {
        if (Vector3.Distance(transform.localPosition, slot.transform.position) == 1)
        {
            xSlot = transform.localPosition.x;
            ySlot = transform.localPosition.y;
            transform.localPosition = new Vector3(slot.transform.position.x, slot.transform.position.y, 0);
            slot.transform.position = new Vector3(xSlot, ySlot, 0);
        }
    }

}

Now, in the above script I don’t exit the function which should be inserted into “OnMouseUp()” and must test if the arrays are equal

Thanks for any help :slight_smile:

Line 74 is an infinite recursion. You’re calling the function in itself. Try it like this:

bool CheckArray(Vector3[] a, Vector3[] b)
    { // Removed recursive call
        if (a.Length != b.Length) return false;
        for (int i = 0; i < a.Length; i++)
        {
            if (a[i] != b[i]) return false;
        }
        return true;
    }
    

    void OnMouseUp()
    {
        if (CheckArray(oldGopos, newGoPos)) // Calling our utility function from here
        {
            // do something here, maybe you want the distance check in here?
            Debug.Log("The arrays are equal!");
        }
        if (Vector3.Distance(transform.localPosition, slot.transform.position) == 1)
        {
            xSlot = transform.localPosition.x;
            ySlot = transform.localPosition.y;
            transform.localPosition = new Vector3(slot.transform.position.x, slot.transform.position.y, 0);
            slot.transform.position = new Vector3(xSlot, ySlot, 0);
        }
    }
1 Like

Thanks!!! It works fine now, but the array is not compared; only one element in it’s seen… I work on this solution and I hope that I get along!!!

Thanks again :slight_smile:

All wrong; I noticed (debug) that it always returns false moving any gameObject except the cube with the id 14! In essence I only recognize the id 14 in any position I move it, and this is what I don’t want; frankly I don’t know what to do anymore … I should completely change my solution… :frowning: