// To be called after dropping a fragment and snapping to other fragments
    // Check and handle victory condition
    bool CheckVictory()
    {
        // A fragment group should contain all fragments, otherwise we haven't won yet
        if (fragments.Count != fragments[0].fragmentGroup.fragments.Count)
        {
            return(false);
        }

        // Victory!
        MicrogameController.instance.setVictory(victory: true, final: true);

        // Save the starting values for the victory animation
        victoryStartTime        = Time.time;
        victoryStartPosition    = fragments[0].transform.position;
        victoryStartRotation    = fragments[0].transform.eulerAngles;
        backgroundMask.position = victoryStartPosition;

        // Replace the mask fragments with the assembled model
        foreach (MaskPuzzleMaskFragment fragment in fragments)
        {
            fragment.gameObject.SetActive(false);
        }
        MaskPuzzleMaskFragment assembledMask = Instantiate(
            chosenMask.assembled,
            Vector2.zero,
            Quaternion.identity
            ).transform.GetChild(0).GetComponent <MaskPuzzleMaskFragment>();

        assembledMask.fragmentsManager = this;
        assembledMask.gameObject.layer = FIRST_MASK_LAYER;
        assembledMask.VictoryAnimation();

        return(true);
    }
Пример #2
0
    public MaskPuzzleFragmentGroup(MaskPuzzleMaskFragment initialFragment)
    {
        fragments = new List <MaskPuzzleMaskFragment>();
        fragments.Add(initialFragment);

        // Create a new camera for this group by cloning the main camera
        // A separate camera for each group is needed so they don't clip into each other
        // Drawing order is determined by the camera depth
        assignedCamera = Camera.Instantiate(Camera.main);
        assignedCamera.GetComponent <AudioListener>().enabled = false;
        assignedCamera.clearFlags  = CameraClearFlags.Depth;
        assignedCamera.cullingMask = 1 << initialFragment.gameObject.layer;
        assignedCamera.depth       = .1f;
    }
Пример #3
0
    // To be called when dropping a mask
    // Checks whether any other fragments are near the drop position
    // If yes, snaps the fragments of this group to them by making their positions equal
    // and joins their groups
    public bool SnapToOtherFragments()
    {
        bool connected = false;

        for (int i = 0; i < fragments[0].fragmentsManager.fragments.Count; i++)
        {
            MaskPuzzleMaskFragment checkedFragment = fragments[0].fragmentsManager.fragments[i];

            // Check if already connected
            if (fragments.Contains(checkedFragment))
            {
                continue;
            }

            // Check distance
            if (Vector2.Distance(fragments[0].transform.position, checkedFragment.transform.position)
                > fragments[0].fragmentsManager.maxSnapDistance)
            {
                continue;
            }

            // Check if the grabbed fragment can be connected to the i-th fragment,
            // directly or through other already connected fragments
            Debug.Log("Checking connectability; grabbed group count: " + fragments.Count + "; checked group count: "
                      + checkedFragment.fragmentGroup.fragments.Count);
            if (fragments[0].fragmentsManager.edges.areConnectable(
                    this, checkedFragment.fragmentGroup))
            {
                // Make positions equal and connect the groups
                foreach (MaskPuzzleMaskFragment fragment in fragments)
                {
                    fragment.transform.position = checkedFragment.transform.position;
                    Debug.Log("Snapped " + fragment.name + " to " + checkedFragment.name);
                }
                connectTo(checkedFragment.fragmentGroup);
                Debug.Log("Now the group contains " + fragments.Count + " fragments.");
                connected = true;
            }
        }
        return(connected);
    }
    // Handle dragging and dropping the fragments
    void HandleDragging()
    {
        // Grabbing a fragment
        if (grabbedFragmentGroup == null && Input.GetMouseButtonDown(0))
        {
            // Get an array of all the fragments under the cursor
            Ray          mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit[] hits     = Physics.RaycastAll(mouseRay, float.PositiveInfinity, 31 << 14);

            RaycastHit             topHit = new RaycastHit();
            MaskPuzzleMaskFragment fragmentHit, topHitFragment = null;
            float topHitDepth    = -1f;
            float topHitDistance = 0f;

            // There might be multiple fragments under the cursor
            // We need to determine which one is on top - that one will be grabbed
            // We pick the one whose assigned camera has the highest depth
            // In case of equal depth we pick the fragment closest to the camera
            foreach (RaycastHit hit in hits)
            {
                fragmentHit = hit.collider.GetComponent <MaskPuzzleMaskFragment>();
                if (fragmentHit.fragmentGroup.assignedCamera.depth <= topHitDepth)
                {
                    continue;
                }
                if (fragmentHit.fragmentGroup.assignedCamera.depth == topHitDepth &&
                    hit.distance >= topHitDistance)
                {
                    continue;
                }
                topHit         = hit;
                topHitFragment = fragmentHit;
                topHitDepth    = fragmentHit.fragmentGroup.assignedCamera.depth;
                topHitDistance = hit.distance;
            }

            if (topHitFragment)
            {
                grabbedFragmentGroup = topHitFragment.fragmentGroup;
                shiftGroupScale(grabbedFragmentGroup, grabScaleIncrease);
                // Grabbed fragment group should be on top
                grabbedFragmentGroup.assignedCamera.depth = (topDepth += .005f);
                // Save the grabbed point's coordinates needed for calculating position when dragging
                grabZ      = topHit.point.z;
                grabOffset = topHitFragment.transform.position
                             - CameraHelper.getCursorPosition(grabZ);
                print("Top hit=" + topHitFragment + "; depth=" + topHitDepth + "; dist=" + topHitDistance
                      + "; z=" + topHit.point.z);
                MicrogameController.instance.playSFX(
                    grabSound,
                    volume: 1f,
                    panStereo: AudioHelper.getAudioPan(topHitFragment.transform.position.x)
                    );
            }
        }

        // Dropping a fragment
        else if (grabbedFragmentGroup != null && !Input.GetMouseButton(0))
        {
            shiftGroupScale(grabbedFragmentGroup, -grabScaleIncrease);
            MicrogameController.instance.playSFX(
                dropSound,
                volume: 1f,
                pitchMult: dropPitchMult,
                panStereo: AudioHelper.getAudioPan(grabbedFragmentGroup.fragments[0].transform.position.x)
                );
            if (grabbedFragmentGroup.SnapToOtherFragments())
            {
                MicrogameController.instance.playSFX(
                    placeSound,
                    volume: 1f,
                    panStereo: AudioHelper.getAudioPan(grabbedFragmentGroup.fragments[0].transform.position.x)
                    );
                if (CheckVictory())
                {
                    MicrogameController.instance.playSFX(
                        victorySound,
                        volume: 1f,
                        panStereo: 0f
                        );
                }
            }
            grabbedFragmentGroup = null;
        }

        // Dragging fragments
        else if (grabbedFragmentGroup != null)
        {
            Vector3 position = CameraHelper.getCursorPosition(grabZ);
            position += grabOffset;
            foreach (MaskPuzzleMaskFragment fragment in grabbedFragmentGroup.fragments)
            {
                fragment.transform.position = position;
            }
        }
    }