/// <inheritdoc /> public override void MoveEnd(GridLayout gridLayout, GameObject brushTarget, BoundsInt position) { if (brushTarget.layer == 31) { base.MoveEnd(gridLayout, brushTarget, position); return; } if (IsInvalid(brushTarget, out var mapPart)) { return; } // when moving items, we may overlap the start region, in which case, we can't blindly erase the // objects at the given position. Therefore, keep track of all of the items we're moving // and if we encounter them when needing to erase objects, don't erase them (they'll simply // move position) var itemsToKeep = new HashSet <GameObject>(_moveData.OfType <GameObject>().Where(it => it != null)); // destroy the given object if it's not in our keep list void DestroyIfNeeded(GameObject it) { if (it != null && !itemsToKeep.Contains(it)) { Undo.DestroyObjectImmediate(it); } } // iterate through all of the new positions foreach (var childPosition in position.allPositionsWithin) { // if there's something already there, delete it var existingInstance = GetObjectInCell(gridLayout, brushTarget.transform, childPosition); DestroyIfNeeded(existingInstance); // and then move the old object over to the new position var newInstance = _moveData[childPosition.x - position.xMin, childPosition.y - position.yMin]; if (newInstance != null) { if (mapPart.IsValidPosition(childPosition)) { MoveInstanceToCellPosition(gridLayout, brushTarget, childPosition, newInstance); } else { Undo.DestroyObjectImmediate(newInstance); } } } // clear our existing move data so that we don't accidentally do anything with it later _moveData = null; }