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\$
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 Apr 12 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 Apr 12 at 13:38

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.