public bool Fit(NetworkPiece p1, NetworkPiece p2, Vector2 correctRelativePositionP1toP2) { //first check relative rotation float zRot1 = p1.transform.rotation.eulerAngles.z; float zRot2 = p2.transform.rotation.eulerAngles.z; float angleOffset = Mathf.Abs(zRot1 - zRot2); if (angleOffset > rotationSnapThreshold) { return(false); } //then check distance float distance = Mathf.Abs((p2.transform.position - p1.transform.position).magnitude - correctRelativePositionP1toP2.magnitude); if (distance > positionSnapThreshold) { return(false); } //then check relative direction Vector2 relativeDir = Quaternion.AngleAxis(-zRot1, new Vector3(0, 0, 1)) * (p2.transform.position - p1.transform.position); if (Vector2.Angle(relativeDir, correctRelativePositionP1toP2) > rotationSnapThreshold) { return(false); } return(true); }
void CmdReleasePiece(NetworkInstanceId pieceId) { NetworkPiece releasedPiece = NetworkServer.FindLocalObject(pieceId).GetComponent <NetworkPiece>(); releasedPiece.cluster.grabbed = false; releasedPiece.cluster.transform.SetParent(null); Puzzle puzzle = GameObject.Find("Puzzle").GetComponent <Puzzle>(); List <Cluster> clustersThatFit = puzzle.possibleFits(releasedPiece.id); //stop here if no fits were found if (clustersThatFit.Count == 0) { return; } //find the biggest cluster Cluster biggestCluster = releasedPiece.cluster; foreach (Cluster c in clustersThatFit) { if (c.pieces.Count >= biggestCluster.pieces.Count) { biggestCluster = c; } } if (biggestCluster != releasedPiece.cluster) { clustersThatFit.Remove(biggestCluster); clustersThatFit.Add(releasedPiece.cluster); } NetworkPiece snapPiece = biggestCluster.pieces[0]; Vector3 positionalSnapOffset; float rotationalSnapOffset; //merge the clusters of the fitting pieces foreach (Cluster fittingCluster in clustersThatFit) { NetworkPiece firstPiece = fittingCluster.pieces[0]; positionalSnapOffset = GetSnapOffset(firstPiece, snapPiece); rotationalSnapOffset = snapPiece.transform.rotation.eulerAngles.z - firstPiece.transform.rotation.eulerAngles.z; fittingCluster.transform.RotateAround(firstPiece.transform.position, new Vector3(0, 0, 1), rotationalSnapOffset); fittingCluster.transform.Translate(positionalSnapOffset); List <NetworkPiece> piecesToBeMerged = new List <NetworkPiece>(); fittingCluster.pieces.ForEach(p => piecesToBeMerged.Add(p)); //change the id an a seperate loop, because changing the id results in the cluster.pieces List to be altered //and looping through a list while also altering it results in errors foreach (NetworkPiece p in piecesToBeMerged) { p.clusterID = biggestCluster.id; } } }
public Vector3 GetSnapOffset(NetworkPiece p1, NetworkPiece p2) { PieceData pD1 = puzzle.GetPieceData(p1.id); PieceData pD2 = puzzle.GetPieceData(p2.id); Vector3 relativeOffset = p2.transform.position - p1.transform.position; //make correction for current rotation relativeOffset = Quaternion.AngleAxis(-p2.transform.eulerAngles.z, new Vector3(0, 0, 1)) * relativeOffset; Vector3 correctRelativeOffset = pD2.position - pD1.position; return(relativeOffset - correctRelativeOffset); }
void CmdGrabPiece(NetworkInstanceId pieceId, NetworkInstanceId parentId) { NetworkPiece piece = NetworkServer.FindLocalObject(pieceId).GetComponent <NetworkPiece>(); //don't grab the piece if it's already grabbed by another player if (piece.cluster.grabbed) { return; } Player parent = NetworkServer.FindLocalObject(parentId).GetComponent <Player>(); piece.cluster.transform.SetParent(parent.smoothTransform); piece.cluster.grabbed = true; }
void ReleasePiece() { //tell the server to unparent this piece from this player (and check/connect if the piece fits other pieces) CmdReleasePiece(draggingPiece.GetComponent <NetworkIdentity>().netId); //re-enable the network transform of this piece's cluster so it get's updated when other players move it EnableNetworkTransform(draggingPiece.cluster.gameObject); //locally unparent this piece or its cluster draggingPiece.cluster.transform.SetParent(null); //forget that this player is dragging a piece draggingPiece.cluster.grabbed = false; //draggingPiece.grabbedByLocalPlayer = false; draggingPiece = null; }
void GrabPiece(GameObject obj) { //keep track of the piece that this player is dragging draggingPiece = obj.GetComponent <Piece>().networkPiece; //don't grab the piece if it's already grabbed by another player if (draggingPiece.cluster.grabbed) { return; } draggingPiece.cluster.grabbed = true; //draggingPiece.grabbedByLocalPlayer = isLocalPlayer; //disable the network transform for this piece (for this player only) to prevent updates from the server while dragging DisableNetworkTransform(draggingPiece.cluster.gameObject); //locally parent this piece's to the player draggingPiece.cluster.transform.SetParent(smoothTransform); //tell the server to parent this piece to the player so the other players will know CmdGrabPiece(draggingPiece.GetComponent <NetworkIdentity>().netId, netId); }
public override void OnStartServer() { List <PieceData> piecesData = puzzle.GeneratePiecesData(); foreach (PieceData data in piecesData) { GameObject clusterGameObject = Instantiate(clusterPrefab); clusterGameObject.name = "Cluster" + data.id; Cluster cluster = clusterGameObject.GetComponent <Cluster>(); cluster.id = data.id; GameObject networkPieceGameObject = Instantiate(networkPiecePrefab); NetworkPiece networkPiece = networkPieceGameObject.GetComponent <NetworkPiece>(); networkPiece.Setup(data); networkPieceGameObject.transform.position = data.position; networkPieceGameObject.name = "NetworkPiece" + data.id; networkPiece.clusterID = cluster.id; NetworkServer.Spawn(clusterGameObject); NetworkServer.Spawn(networkPieceGameObject); } }
public List <Cluster> possibleFits(int droppedPieceId) { List <Cluster> clustersThatFit = new List <Cluster>(); NetworkPiece droppedPiece = GetNetworkPiece(droppedPieceId); // go through all neighbours of pieces that have to be checked and check if anything fits foreach (NetworkPiece pieceToCheck in droppedPiece.cluster.pieces) { foreach (Neighbour neighbourOfPieceToCheck in GetPieceData(pieceToCheck.id).neighbours) { //continue if this 'neighbour' is the outer edge of the puzzle or if it is already connected if (neighbourOfPieceToCheck.id == -1 || neighbourOfPieceToCheck.connected) { continue; } NetworkPiece neighbourPiece = GetNetworkPiece(neighbourOfPieceToCheck.id); //skip this piece if it's part of cluster that is already being merged or part of the same cluster if (clustersThatFit.Contains(neighbourPiece.cluster) || neighbourPiece.cluster == droppedPiece.cluster) { continue; } if (Fit(pieceToCheck, neighbourPiece, neighbourOfPieceToCheck.correctRelativePosition)) { //create mutual connection in neighbours (so connected neighbours won't be checked again) Neighbour pieceToCheckAsNeighbour = GetPieceData(neighbourPiece.id).GetNeigbourWithID(pieceToCheck.id); pieceToCheckAsNeighbour.connected = true; neighbourOfPieceToCheck.connected = true; clustersThatFit.Add(neighbourPiece.cluster); } } } return(clustersThatFit); }
public void addNetworkPiece(NetworkPiece p) { networkPieces.Add(p); }