Как я могу перестать добавлять этот же элемент в список в Unity C#? - PullRequest
1 голос
/ 28 февраля 2020

Я пытаюсь сделать игру с кубиками Рубика, используя единство и C#.

Но у меня проблема, когда я хочу добавить элемент в список. Проблема в том, что один и тот же элемент постоянно добавляется в список, я пытался использовать функцию Contains(), но она не работает.

List<node>[,,] _NodeLi;

Примечание : мне нужно использовать это для метода Update().

void Update()
{

    nodes = new node[3, 3, 3];
    Vector3 cubeButtonLeftDown = new Vector3((size / 2 * -1) + (size / 3), (size / 2 * -1) + (size / 3)
        , (size / 2 * -1) + (size / 3));
    for (int x = -1; x <= 1; x++)
    {
        for (int y = -1; y <= 1; y++)
        {
            for (int z = -1; z <= 1; z++)
            {
                node Node = new node(new Vector3(x, y, z), new Vector3
                   (x * size / 6,
                    y * size / 6,
                    z * size / 6));
                nodes[x + 1, y + 1, z + 1] = Node;
            }
        }
    }
    // find the faces of the cube
    //find the y faces
     foreach(node Node_ in nodes) { 
        if (Node_.InRubikCubePos.y == 1)
        {
            if (buttonYFaces.Contains(Node_))
                buttonYFaces.Remove(Node_);

            if (!topYFaces.Contains(Node_))
                topYFaces.Add(Node_);

        }
        else if (Node_.InRubikCubePos.y == -1)
        {
            if (topYFaces.Contains(Node_))
                topYFaces.Remove(Node_);

            if (!buttonYFaces.Contains(Node_))
                buttonYFaces.Add(Node_);

        }
        else
        {
            if (buttonYFaces.Contains(Node_))
                buttonYFaces.Remove(Node_);

            if (topYFaces.Contains(Node_))
            topYFaces.Remove(Node_);

        }

    }
    // find the x faces
    foreach (node Node_ in nodes)
    {
        if (Node_.InRubikCubePos.x == 1)
        {
            if (leftXFaces.Contains(Node_))
                leftXFaces.Remove(Node_);

            if (!rightXFaces.Contains(Node_))
                rightXFaces.Add(Node_);

        }
        else if (Node_.InRubikCubePos.x == -1)
        {
            if (rightXFaces.Contains(Node_))
                rightXFaces.Remove(Node_);

            if (!leftXFaces.Contains(Node_))
                leftXFaces.Add(Node_);
        }
        else
        {
            if (leftXFaces.Contains(Node_))
                leftXFaces.Remove(Node_);

            if (rightXFaces.Contains(Node_))
                rightXFaces.Remove(Node_);

        }
    }
    // find the z faces
    foreach (node Node_ in nodes)
    {
        if (Node_.InRubikCubePos.z == 1)
        {
            if (leftZFaces.Contains(Node_))
                leftZFaces.Remove(Node_);

            if (!rightZFaces.Contains(Node_))
                rightZFaces.Add(Node_);
        }
        else if (Node_.InRubikCubePos.z == -1)
        {
            if (rightZFaces.Contains(Node_))
                rightZFaces.Remove(Node_);

            if(!leftZFaces.Contains(Node_))
            leftZFaces.Add(Node_);
        }
        else
        {
            if (leftZFaces.Contains(Node_))
                leftZFaces.Remove(Node_);

            if (rightZFaces.Contains(Node_))
                rightZFaces.Remove(Node_);
        }
    }
    // find the vert positions
    if (vertPositions.Count < 8)
    {
        foreach (float x in _One)
        {
            foreach (float y in _One)
            {
                foreach (float z in _One)
                {
                    vertPositions.Add(new Vector3(x, y, z));
                }
            }
        }
    }
    foreach(Vector3 n in vertPositions)
    {
        Debug.Log(n);
    }
        Debug.Log(vertPositions.Count);
    Debug.Log("Y :" + topYFaces.Count +",,,,, :" +buttonYFaces.Count);
    }
private void OnDrawGizmos()
{
    if (nodes != null)
    {
        foreach (node n in nodes)
        {
            Gizmos.DrawWireCube(n.inWorldPos, Vector3.one * (size / 6));
        }
    }
}

И это класс узла:

public class node{
    public Vector3 InRubikCubePos;
    public Vector3 inWorldPos;
    //IRCPos mean's " InRubikCubePos " and the IWPos mean's " inWorldPos " 
    public node(Vector3 IRCPos, Vector3 IWPos)
    {
        InRubikCubePos = IRCPos;
        inWorldPos = IWPos;
    }
}

Ответы [ 2 ]

2 голосов
/ 28 февраля 2020

Я не могу комментировать, поэтому я отвечаю здесь. Вы должны переопределить метод Equals. Если вы это сделаете, не забудьте также переопределить метод GetHashCode.

[Здесь объясняется, почему] Почему важно переопределить GetHashCode при переопределении метода Equals?

Пример для переопределения Equals:

public override bool Equals(object obj)
    {
        return obj is node candidate && this.inWorldPosition.ExampleInt == candidate.ExampleInt;
    }

Вот как работает контейнерный метод:

public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value) {
        ICollection<TSource> collection = source as ICollection<TSource>;
        if (collection != null) return collection.Contains(value);
        return Contains<TSource>(source, value, null);
    }

    public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)
    {
        if (comparer == null) comparer = EqualityComparer<TSource>.Default;
        if (source == null) throw Error.ArgumentNull("source");
        foreach (TSource element in source)
            if (comparer.Equals(element, value)) return true;
        return false;
    }
0 голосов
/ 28 февраля 2020

Узел - это класс без метода equals, что означает, что будет использоваться ссылочное равенство . Тем не менее, массив 'node' создается с совершенно новыми объектами, поэтому нет никакой возможности, чтобы 'buttonYFaces' или какие-либо другие списки содержали эти же объекты.

Решение было бы переопределить метод Equals, и предпочтительно также реализовать интерфейс IEquatable<node>. Это должно заставить метод содержимого работать так, как вы ожидаете

...