//----------------------------------------------------------------------------------------------------- // Try to find and clamp all pieces/groups public void TryToClampAllGroups() { if (enablePiecesGroups) { overlappedPieces.Clear(); for (int i = 0; i < movedPieces.Count; i++) { currentObjectTransform = pieces[movedPieces[i]].transform; foreach (int movedPieceId in movedPieces) { if (movedPieces[i] != movedPieceId) { if (currentObjectTransform.parent == thisTransform || (currentObjectTransform.parent != thisTransform && currentObjectTransform.parent != pieces[movedPieceId].transform.parent)) { if (pieces[movedPieces[i]].renderer.bounds.Intersects(pieces[movedPieceId].renderer.bounds)) { overlappedPieces.Add(pieces[movedPieceId]); } } } } for (int j = 0; j < overlappedPieces.Count; j++) { PuzzlePieceGroup.MergeGroupsOrPieces(pieces[movedPieces[i]], overlappedPieces[j], this); } overlappedPieces.Clear(); } CreateUngroupedPiecesList(); } }
public void transferPieceTo(PuzzlePieceGroup target) { var pieces = GetComponentsInChildren <PuzzlePiece>(); //轉移Child var targetTransform = target.transform; var transforms = GetComponentsInChildren <Transform>(); for (var i = 0; i < transforms.Length; i++) { var t = transforms[i]; //排除自己 if (t != transform) { t.parent = targetTransform; } } //記下Scale(因為進Pocket會改變Scale) foreach (var p in pieces) { p.memoryScale(); } Destroy(gameObject); }
//--------------------------------------------------------------------------------------------------------------------------------------------------- // Return Group object if object or its paren is group public static GameObject GetGroupObjectIfPossible(GameObject _pieceOrGroupObject) { // Is it a Group PuzzlePieceGroup pieceGroup = _pieceOrGroupObject.GetComponent <PuzzlePieceGroup>(); // Is it part of a Group if (pieceGroup == null) { if (_pieceOrGroupObject.transform.parent.GetComponent <PuzzlePieceGroup>() != null) { _pieceOrGroupObject = _pieceOrGroupObject.transform.parent.gameObject; } } return(_pieceOrGroupObject); }
//----------------------------------------------------------------------------------------------------- // Process puzzle during gameplay (including user input) public PuzzleState ProcessPuzzle(Vector3 _pointerPosition, bool _dragInput, float _rotationDirection) { if (IsAssembled()) { return(PuzzleState.PuzzleAssembled); } else { state = PuzzleState.None; } // Check is any piece clicked and get it Id if (_dragInput && currentPiece < 0) { _pointerPosition.z = 0; currentPiece = GetPointedPieceId(_pointerPosition, true); if (currentPiece >= 0) { pieceCenterOffset = pieces[currentPiece].GetPieceCenterOffset(); if (enablePiecesGroups) { currentObject = PuzzlePieceGroup.GetGroupObjectIfPossible(pieces[currentPiece].transform.gameObject); currentObjectTransform = currentObject.transform; currentGroup = currentObject.GetComponent <PuzzlePieceGroup>(); } else { currentObject = pieces[currentPiece].transform.gameObject; currentObjectTransform = pieces[currentPiece].transform; } Debug.Log(currentObject.name); SpriteRenderer render = currentObject.GetComponent <SpriteRenderer>() as SpriteRenderer; render.drawMode = SpriteDrawMode.Sliced; render.size = pieces[currentPiece].oldSize; pieces[currentPiece].transform.localScale = pieces[currentPiece].oldScale; if (!changeOnlyRotation) { if (fullyIn3D) { currentObjectTransform.position = new Vector3(_pointerPosition.x - pieceCenterOffset.x, _pointerPosition.y - pieceCenterOffset.y, currentObjectTransform.position.z - dragOffsetZ); } else { currentObjectTransform.position = new Vector3(_pointerPosition.x - pieceCenterOffset.x, _pointerPosition.y - pieceCenterOffset.y, -dragOffsetZ); } } state = PuzzleState.DragPiece; } } // If no piece is grabbed - RETURN if (currentObject == null) { return(PuzzleState.None); } // Pointer position offset for mobile #if !UNITY_EDITOR && !UNITY_STANDALONE && !UNITY_WEBPLAYER && !UNITY_WEBGL _pointerPosition.y += maxPieceSize.y * mobileDragOffsetY; #else // for desktop if (changeOnlyRotation) { _rotationDirection = 1; } #endif // Set currentObject center position to pointerPosition if (!changeOnlyRotation) { currentObjectTransform.position = new Vector3(_pointerPosition.x - pieceCenterOffset.x, _pointerPosition.y - pieceCenterOffset.y, currentObjectTransform.position.z); } // If piece rotation requested(by RMB or 2 touched) and possible - rotate piece around Z-axis if (_rotationDirection != 0 && randomizeRotation) { pieceCenterOffset = pieces[currentPiece].GetPieceCenterOffset(); currentObjectTransform.RotateAround(pieces[currentPiece].renderer.bounds.center, Vector3.forward, _rotationDirection * rotationSpeed * Time.deltaTime); state = PuzzleState.RotatePiece; } // Tilt piece according to movement direction if needed if (dragTiltSpeed > 0) { currentObjectTransform.localRotation = new Quaternion( Mathf.Lerp(currentObjectTransform.localRotation.x, (oldPointerPosition.y - _pointerPosition.y) * dragTiltSpeed, Time.deltaTime), Mathf.Lerp(currentObjectTransform.localRotation.y, (oldPointerPosition.x - _pointerPosition.x) * dragTiltSpeed, Time.deltaTime), currentObjectTransform.localRotation.z, currentObjectTransform.localRotation.w ); oldPointerPosition = _pointerPosition; } // Drop piece and assemble it to puzzle (if it close enough to it initial position/rotation) if (!_dragInput) { currentObjectTransform.localRotation = new Quaternion(0, 0, currentObjectTransform.localRotation.z, currentObjectTransform.localRotation.w); //Removes the tilt effect if (!changeOnlyRotation) { currentObjectTransform.position = new Vector3(currentObjectTransform.position.x, currentObjectTransform.position.y, currentObjectTransform.position.z + dragOffsetZ); } // Process groups if needed //if (enablePiecesGroups) //{ // bool grouping = false; // // Get list of all pieces overlapped by currentPiece // foreach (int movedPieceId in movedPieces) // if (movedPieceId != currentPiece) // if (currentGroup != null) // if dropped a group // { // if (pieces[movedPieceId].transform.parent != currentGroup.transform) // foreach (PuzzlePiece groupPiece in currentGroup.puzzlePieces) // if (groupPiece.renderer.bounds.Intersects(pieces[movedPieceId].renderer.bounds)) // overlappedPieces.Add(pieces[movedPieceId]); // } // else // if dropped a piece // if (pieces[currentPiece].renderer.bounds.Intersects(pieces[movedPieceId].renderer.bounds)) // overlappedPieces.Add(pieces[movedPieceId]); // // Try to merge overlapped pieces to groups // for (int i = 0; i < overlappedPieces.Count; i++) // grouping |= PuzzlePieceGroup.MergeGroupsOrPieces(pieces[currentPiece], overlappedPieces[i], this); // overlappedPieces.Clear(); // if (grouping) // { // UpdateUngroupedPiecesList(); // state = PuzzleState.DropPiece; // } // // Assemble grouped pieces to puzzle // if (currentGroup != null) // { // if (IsPieceInPlace(currentGroup.puzzlePieces[0], allowedDistance, allowedRotation) || (invertedRules && !IsPieceInPlace(currentGroup.puzzlePieces[0], allowedDistance, allowedRotation))) // { // int groupPieceId; // foreach (PuzzlePiece groupPiece in currentGroup.puzzlePieces) // { // groupPiece.transform.parent = thisTransform; // groupPieceId = GetPieceId(groupPiece); // if (invertedRules) // movedPieces.Remove(groupPieceId); // else // ReturnPiece(groupPieceId, movementTime); // } // Destroy(currentGroup.gameObject); // state = PuzzleState.ReturnPiece; // } // else // Just drop it // state = PuzzleState.DropPiece; // } //} //Assemble ungrouped piece to puzzle if (currentGroup == null) { if (IsPieceInPlace(currentPiece, allowedDistance, allowedRotation) || (invertedRules && !IsPieceInPlace(currentPiece, allowedDistance, allowedRotation))) { if (invertedRules) { movedPieces.Remove(currentPiece); } else { ReturnPiece(currentPiece, movementTime); } pieces[currentPiece].spriteRenderer.drawMode = SpriteDrawMode.Tiled; pieces[currentPiece].spriteRenderer.size = pieces[currentPiece].oldSize; pieces[currentPiece].spriteRenderer.drawMode = SpriteDrawMode.Simple; pieces[currentPiece].transform.localScale = pieces[currentPiece].oldScale; GameManager.Instance.numberPiece -= 1; // khi gắn xong mảnh thì trừ biến đếm đi 1, nếu hết 4 mảnh thì active các mảnh còn lại if (GameManager.Instance.numberPiece <= 0) { ActivePiece(); } state = PuzzleState.ReturnPiece; } else // Just drop it {// tra ve vi tri ban dau currentObjectTransform.position = pieces[currentPiece].targetPosition; pieces[currentPiece].spriteRenderer.drawMode = SpriteDrawMode.Tiled; pieces[currentPiece].spriteRenderer.size = new Vector3(1, 1, 1); pieces[currentPiece].spriteRenderer.drawMode = SpriteDrawMode.Simple; pieces[currentPiece].transform.localScale = GameManager.Instance.getSizePieceFake(); state = PuzzleState.DropPiece; } } currentObject = null; currentPiece = -1; } return(state); }
public void merge(HashSet <IPuzzleLayer> set, PuzzlePieceGroup group) { var layerManager = LayerMananger.GetInstance(); var layers = new List <IPuzzleLayer>(set); // print("before sort"); // foreach (var e in layers) // print(e.GetLayerIndex()); // 從depth小排到大 layers.Sort((a, b) => { return(a.GetLayerIndex() - b.GetLayerIndex()); }); // print("after sort"); // foreach (var e in layers) // print(e.GetLayerIndex()); // 取出含有最多piece的Layer,把所有piece都給它 var theChosenOne = layers[0]; // 全部set都只有1塊piece if (theChosenOne.GetPiecesCount() == 1) { var p = theChosenOne as PuzzlePiece; // 建立connectedSet,全部piece都加進來 var cs = group.createConnectedSet(p); for (var i = layers.Count - 1; i >= 0; --i) //從最上層開始 { var L = layers[i]; cs.add(L as PuzzlePiece); layerManager.remove(L); } layerManager.add(cs); return; } var nowCS = theChosenOne as ConnectedSet; // 把其他piece都加進來 for (var i = layers.Count - 1; i >= 1; --i) //從最上層開始 { var L = layers[i]; if (L.GetPiecesCount() == 1) { nowCS.add(L as PuzzlePiece); layerManager.remove(L); } else { var cs = L as ConnectedSet; nowCS.add(cs); layerManager.remove(L); Object.Destroy(cs.gameObject);//刪除connectedSet } } layerManager.update(theChosenOne); }
//--------------------------------------------------------------------------------------------------------------------------------------------------- // Main function to process grouping pieces and clamping groups public static bool MergeGroupsOrPieces(PuzzlePiece _puzzlePiece1, PuzzlePiece _puzzlePiece2, PuzzleController _puzzleController) { GameObject object1 = _puzzlePiece1.transform.gameObject; GameObject object2 = _puzzlePiece2.transform.gameObject; //Convert to group if it's not a single piece object1 = GetGroupObjectIfPossible(object1); object2 = GetGroupObjectIfPossible(object2); if (object1 == object2) { return(false); } // Get groups PuzzlePieceGroup pieceGroup1 = object1.GetComponent <PuzzlePieceGroup>(); PuzzlePieceGroup pieceGroup2 = object2.GetComponent <PuzzlePieceGroup>(); //// If both objects non-grouped if (pieceGroup1 == null && pieceGroup2 == null) { bool clamped = TryClampPieces(_puzzlePiece1, _puzzlePiece2, _puzzleController); // Create new group if (clamped) { GameObject pieceGroupObject = new GameObject("_PieceGroup".ToString()); pieceGroupObject.transform.parent = _puzzleController.transform; PuzzlePieceGroup pieceGroup = pieceGroupObject.AddComponent <PuzzlePieceGroup>(); // Include pieces in the group pieceGroup.AddNewPiece(_puzzlePiece1); pieceGroup.AddNewPiece(_puzzlePiece2); pieceGroup.RecalculateCenterAndTransformGroup(); } return(clamped); } else //// If both objects are groups if (pieceGroup1 != null && pieceGroup2 != null) { foreach (PuzzlePiece puzzlePiece1 in pieceGroup1.puzzlePieces) { foreach (PuzzlePiece puzzlePiece2 in pieceGroup2.puzzlePieces) { if (TryClampPieces(puzzlePiece1, puzzlePiece2, _puzzleController)) { // Move pieces to one group foreach (PuzzlePiece puzzlePiece in pieceGroup2.puzzlePieces) { pieceGroup1.AddNewPiece(puzzlePiece); } pieceGroup1.RecalculateCenterAndTransformGroup(); Destroy(pieceGroup2.gameObject); return(true); } } } } else //// One object is a group and another is non-grouped piece { PuzzlePieceGroup pieceGroup; PuzzlePiece puzzlePiece; // Figure out which object is group/single piece if (pieceGroup1 == null) { pieceGroup = pieceGroup2; puzzlePiece = _puzzlePiece1; } else { pieceGroup = pieceGroup1; puzzlePiece = _puzzlePiece2; } // Try to clamp each piece in group with the single piece for (int i = 0; i < pieceGroup.puzzlePieces.Count; ++i) { if (TryClampPieces(puzzlePiece, pieceGroup.puzzlePieces[i], _puzzleController)) { pieceGroup.AddNewPiece(puzzlePiece); pieceGroup.RecalculateCenterAndTransformGroup(); return(true); } } } return(false); }
// Process puzzle during gameplay (including user input) public PuzzleState ProcessPuzzle(Vector3 _pointerPosition, bool _dragInput, float _rotationDirection) { if (IsAssembled()) { return(PuzzleState.PuzzleAssembled); } else { state = PuzzleState.None; } // Check is any piece clicked and get it Id if (_dragInput && currentPiece < 0) { _pointerPosition.z = 0; currentPiece = GetPointedPieceId(_pointerPosition, true); if (currentPiece >= 0) { pieceCenterOffset = pieces[currentPiece].GetPieceCenterOffset(); if (EnablePiecesGroups) { currentObject = PuzzlePieceGroup.GetGroupObjectIfPossible(pieces[currentPiece].Transform.gameObject); currentObjectTransform = currentObject.transform; currentGroup = currentObject.GetComponent <PuzzlePieceGroup>(); } else { currentObject = pieces[currentPiece].Transform.gameObject; currentObjectTransform = pieces[currentPiece].Transform; } if (!ChangeOnlyRotation) { if (FullyIn3D) { currentObjectTransform.position = new Vector3(_pointerPosition.x - pieceCenterOffset.x, _pointerPosition.y - pieceCenterOffset.y, currentObjectTransform.position.z - dragOffsetZ); } else { currentObjectTransform.position = new Vector3(_pointerPosition.x - pieceCenterOffset.x, _pointerPosition.y - pieceCenterOffset.y, -dragOffsetZ); } } state = PuzzleState.DragPiece; } } // If no piece is grabbed - RETURN if (currentObject == null) { return(PuzzleState.None); } // Pointer position offset for mobile #if !UNITY_EDITOR && !UNITY_STANDALONE && !UNITY_WEBPLAYER && !UNITY_WEBGL _pointerPosition.y += maxPieceSize.y * mobileDragOffsetY; #else // for desktop if (ChangeOnlyRotation) { _rotationDirection = 1; } #endif // Set currentObject center position to pointerPosition if (!ChangeOnlyRotation) { currentObjectTransform.position = new Vector3(_pointerPosition.x - pieceCenterOffset.x, _pointerPosition.y - pieceCenterOffset.y, currentObjectTransform.position.z); } // If piece rotation requested(by RMB or 2 touched) and possible - rotate piece around Z-axis if (_rotationDirection != 0 && RandomizeRotation) { pieceCenterOffset = pieces[currentPiece].GetPieceCenterOffset(); currentObjectTransform.RotateAround(pieces[currentPiece].Renderer.bounds.center, Vector3.forward, _rotationDirection * rotationSpeed * Time.deltaTime); state = PuzzleState.RotatePiece; } // Tilt piece according to movement direction if needed if (dragTiltSpeed > 0) { currentObjectTransform.localRotation = new Quaternion( Mathf.Lerp(currentObjectTransform.localRotation.x, (oldPointerPosition.y - _pointerPosition.y) * dragTiltSpeed, Time.deltaTime), Mathf.Lerp(currentObjectTransform.localRotation.y, (oldPointerPosition.x - _pointerPosition.x) * dragTiltSpeed, Time.deltaTime), currentObjectTransform.localRotation.z, currentObjectTransform.localRotation.w ); oldPointerPosition = _pointerPosition; } // Drop piece and assemble it to puzzle (if it close enough to it initial position/rotation) if (!_dragInput) { currentObjectTransform.localRotation = new Quaternion(0, 0, currentObjectTransform.localRotation.z, currentObjectTransform.localRotation.w); //Removes the tilt effect if (!ChangeOnlyRotation) { currentObjectTransform.position = new Vector3(currentObjectTransform.position.x, currentObjectTransform.position.y, currentObjectTransform.position.z + dragOffsetZ); } // Process groups if needed if (EnablePiecesGroups) { bool grouping = false; // Get list of all pieces overlapped by currentPiece foreach (int movedPieceId in movedPieces) { if (movedPieceId != currentPiece) { if (currentGroup != null) // if dropped a group { if (pieces[movedPieceId].Transform.parent != currentGroup.transform) { foreach (PuzzlePiece groupPiece in currentGroup.puzzlePieces) { if (groupPiece.Renderer.bounds.Intersects(pieces[movedPieceId].Renderer.bounds)) { overlappedPieces.Add(pieces[movedPieceId]); } } } } else // if dropped a piece if (pieces[currentPiece].Renderer.bounds.Intersects(pieces[movedPieceId].Renderer.bounds)) { overlappedPieces.Add(pieces[movedPieceId]); } } } // Try to merge overlapped pieces to groups for (int i = 0; i < overlappedPieces.Count; i++) { grouping |= PuzzlePieceGroup.MergeGroupsOrPieces(pieces[currentPiece], overlappedPieces[i], this); } overlappedPieces.Clear(); if (grouping) { UpdateUngroupedPiecesList(); state = PuzzleState.DropPiece; } // Assemble grouped pieces to puzzle if (currentGroup != null) { if (IsPieceInPlace(currentGroup.puzzlePieces[0], allowedDistance, allowedRotation) || (invertedRules && !IsPieceInPlace(currentGroup.puzzlePieces[0], allowedDistance, allowedRotation))) { int groupPieceId; foreach (PuzzlePiece groupPiece in currentGroup.puzzlePieces) { groupPiece.Transform.parent = thisTransform; groupPieceId = GetPieceId(groupPiece); if (invertedRules) { movedPieces.Remove(groupPieceId); } else { ReturnPiece(groupPieceId, movementTime); } } Destroy(currentGroup.gameObject); state = PuzzleState.ReturnPiece; } else // Just drop it { state = PuzzleState.DropPiece; } } } //Assemble ungrouped piece to puzzle if (currentGroup == null) { if (IsPieceInPlace(currentPiece, allowedDistance, allowedRotation) || (invertedRules && !IsPieceInPlace(currentPiece, allowedDistance, allowedRotation))) { if (invertedRules) { movedPieces.Remove(currentPiece); } else { ReturnPiece(currentPiece, movementTime); } state = PuzzleState.ReturnPiece; } else // Just drop it { state = PuzzleState.DropPiece; } } currentObject = null; currentPiece = -1; } return(state); }
void GeneratePieceGroupAndTransferPiece(Vector3 pos, Vector3 scale, Vector2 uvScaleFactor, Vector2 uvOffsetFactor, PuzzlePieceGroup target) { var group = GameObject.Instantiate <PuzzlePieceGroup>(puzzlePieceGroup, pos, rot); group.transform.localScale = scale; group.setPieceTexture(Bootstrap.getInstance().GetMaterial().mainTexture); group.resetPieceUV(uvScaleFactor, uvOffsetFactor); group.transferPieceTo(target); }