예제 #1
0
    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);
    }
예제 #2
0
    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;
            }
        }
    }
예제 #3
0
    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);
    }
예제 #4
0
    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;
    }
예제 #5
0
    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;
    }
예제 #6
0
    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);
    }
예제 #7
0
    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);
        }
    }
예제 #8
0
    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);
    }
예제 #9
0
 public void addNetworkPiece(NetworkPiece p)
 {
     networkPieces.Add(p);
 }