1
\$\begingroup\$

I think it's just my eyes get blured after seen this so many hours. Maybe new ones will see the problem. I'm making a puzzle game and I need to glue parts with each others. And here's how I make it:

using System.Collections.Generic;
using UnityEngine;
using Puzzle.Helpers;  //enum RaySides are here

namespace Puzzle
{
    public class PartRayCube : MonoBehaviour
    {
        #region ========== Variables ========

        Part2D _part2DParent;
        /// <summary>
        /// List of sides and where it have glued object - true
        /// </summary>
        Dictionary<RaySide, bool> _relatives = new Dictionary<RaySide, bool>();

        #endregion ========== Variables ========

        #region ========== Unity-time ========

        private void Awake()
        {
            _part2DParent = GetComponentInParent<Part2D>();
        }

        #endregion ========== Unity-time ========

        #region ========== Methods ========

        /// <summary>
        /// Adding empty sides
        /// </summary>
        /// <param name="sides"></param>
        public void AddSides(RaySide[] sides)
        {
            foreach (var side in sides)
                _relatives.Add(side, false);
        }

        /// <summary>
        /// Adding glued part
        /// </summary>
        /// <param name="side">Adding side</param>
        /// <param name="relative">Adding Part</param>
        public void AddRelative(RaySide side, Part2D part)
        {
            _relatives[side] = true;

            // Add each other to the parents list
            _part2DParent.Relatives.Add(part);
            part.Relatives.Add(_part2DParent);

            // If THIS object have any relatives(glued parts) adding them to the part's relatives
            if(_part2DParent.Relatives.Count > 1)
            {
                foreach (var item in _part2DParent.Relatives)
                {
                    if (item == part)
                        continue;

                    part.Relatives.Add(item);
                }
            }

            // If part have relatives, add them to THIS's relatives list
            if (part.Relatives.Count > 1)
            {
                foreach (var item in part.Relatives)
                {
                    if (item == _part2DParent)
                        continue;
                                        
                    _part2DParent.Relatives.Add(item);  // Adding rel to this relList

                    item.Relatives.Add(_part2DParent);  // Adding this to item's relList
                }
            }
        }

        /// <summary>
        /// Gluing parts with each other if they fit
        /// </summary>
        public void CheckRelatives()
        {
            Dictionary<RaySide, bool> newRel = new Dictionary<RaySide, bool>();
            newRel = _relatives;

            foreach (var side in newRel.Keys)
            {
                // Skip is side is glued
                if (newRel[side])                
                    continue;                                    

                RaycastHit hit;

                switch (side)
                {
                    case RaySide.left:
                        {
                            // Ray to the left with size partSize/2
                            if (Physics.Raycast(transform.position, -transform.right, out hit, _part2DParent.RectTrans.sizeDelta.x / 2))
                            {
                                if (hit.transform.GetComponentInParent<Part2D>().id + 1 == _part2DParent.id)
                                {
                                    AddRelative(RaySide.left, hit.transform.GetComponentInParent<Part2D>());
                                }
                                else
                                    break;
                            }

                            break;
                        }
                    case RaySide.right:
                        {
                            // Ray to the right with size partSize/2
                            if (Physics.Raycast(transform.position, transform.right, out hit, _part2DParent.RectTrans.sizeDelta.x / 2))
                            {
                                if (hit.transform.GetComponentInParent<Part2D>().id - 1 == _part2DParent.id)
                                {
                                    AddRelative(RaySide.right, hit.transform.GetComponentInParent<Part2D>());
                                }
                                else
                                    break;
                            }

                            break;
                        }
                    case RaySide.up:
                        {
                            // Depending on difference take the right number
                            int i = Main.Instance.Diff.GetHashCode() / 4;

                            if (Physics.Raycast(transform.position, transform.up, out hit, _part2DParent.RectTrans.sizeDelta.y / 2))
                            {
                                if (hit.transform.GetComponentInParent<Part2D>().id + i == _part2DParent.id)
                                    AddRelative(RaySide.up, hit.transform.GetComponentInParent<Part2D>());
                                else
                                    break;
                            }

                            break;
                        }
                    case RaySide.down:
                        {
                            // Depending on difference take the right number
                            int i = Main.Instance.Diff.GetHashCode() / 4;

                            if (Physics.Raycast(transform.position, -transform.up, out hit, _part2DParent.RectTrans.sizeDelta.y / 2))
                            {
                                if (hit.transform.GetComponentInParent<Part2D>().id - i == _part2DParent.id)
                                    AddRelative(RaySide.up, hit.transform.GetComponentInParent<Part2D>());
                                else
                                    break;
                            }

                            break;
                        }
                }
            }
        }

        #endregion ========== Methods ========
    }
}

And after all I see:

InvalidOperationException: Collection was modified; enumeration operation may not execute.
System.Collections.Generic.Dictionary`2+KeyCollection+Enumerator[TKey,TValue].MoveNext () (at <eae584ce26bc40229c1b1aa476bfa589>:0)
Puzzle.PartRayCube.CheckRelatives () (at Assets/Scripts/PartRayCube.cs:88)

But sometimes it works perfect. After 2-3 repeating

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$
            Dictionary<RaySide, bool> newRel = new Dictionary<RaySide, bool>();
            newRel = _relatives;

This creates new dictionary and immediately replaces it with a reference to existing dictionary. You probably wanted to copy it, like this:

            Dictionary<RaySide, bool> newRel = new Dictionary<RaySide, bool>(_relatives);
\$\endgroup\$
2
  • \$\begingroup\$ oh. I see. I'll try it. Thanks \$\endgroup\$
    – Dead Lord
    Commented Apr 12, 2021 at 13:37
  • \$\begingroup\$ it is! OMG! Thank you! By the way I didn't even know that I can copy like that :) \$\endgroup\$
    – Dead Lord
    Commented Apr 12, 2021 at 13:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .