Esempio n. 1
0
    void OnWillRenderObject()
    {
        //Debug.Log("on will" + Camera.current);
        Camera cam = Camera.current;

        if (!cam)
        {
            return;
        }

        PixelPerfectCamera.PixelSnapMode pixelSnapMode = PixelPerfectCamera.PixelSnapMode.Off;
        PixelPerfectCamera pixelPerfectCamera          = null;

        switch (pixelSnapChoiceMode)
        {
        case PixelSnapChoiceMode.Off:
            pixelSnapMode = PixelPerfectCamera.PixelSnapMode.Off;
            break;

        case PixelSnapChoiceMode.LetCameraChoose:
            pixelPerfectCamera = cam.GetComponent <PixelPerfectCamera>();
            if (pixelPerfectCamera == null)
            {
                pixelSnapMode = PixelPerfectCamera.PixelSnapMode.Off;
                break;
            }
            pixelSnapMode = pixelPerfectCamera.pixelSnapMode;
            break;

        case PixelSnapChoiceMode.ForcePixelSnap:
            pixelSnapMode = PixelPerfectCamera.PixelSnapMode.PixelSnap;
            break;
        }

        if (pixelSnapMode == PixelPerfectCamera.PixelSnapMode.Off)
        {
            return;
        }

        shouldRestorePosition = true;
        actualPosition        = transform.position;

        float cameraPPU = (float)cam.pixelHeight / (2f * cam.orthographicSize);
        float cameraUPP = 1.0f / cameraPPU;

        Vector2 camPos = cam.transform.position.xy();
        Vector2 pos    = actualPosition.xy();
        Vector2 relPos = pos - camPos;

        Vector2 offset = new Vector2(0, 0);

        // offset for screen pixel edge if screen size is odd
        offset.x = (cam.pixelWidth % 2 == 0) ? 0 : 0.5f;
        offset.y = (cam.pixelHeight % 2 == 0) ? 0 : 0.5f;
        // offset for pivot in Sprites
        Vector2 pivotOffset = new Vector2(0, 0);

        if (sprite != null)
        {
            pivotOffset = sprite.pivot - new Vector2(Mathf.Floor(sprite.pivot.x), Mathf.Floor(sprite.pivot.y)); // the fractional part in texture pixels
            if (pixelSnapMode == PixelPerfectCamera.PixelSnapMode.RetroSnap)
            {
                // Nothing to do here. Pivot offset is already in asset pixels.
            }
            else // PixelSnap
            {
                float camPixelsPerAssetPixel = cameraPPU / sprite.pixelsPerUnit;
                pivotOffset *= camPixelsPerAssetPixel; // convert to screen pixels
            }
        }

        if (pixelSnapMode == PixelPerfectCamera.PixelSnapMode.RetroSnap)
        {
            float assetPPU = pixelPerfectCamera.assetsPixelsPerUnit;
            float assetUPP = 1.0f / assetPPU;
            float camPixelsPerAssetPixel = cameraPPU / assetPPU;

            offset.x /= camPixelsPerAssetPixel; // zero or half a screen pixel in texture pixels
            offset.y /= camPixelsPerAssetPixel;
            // We don't take into account the pivot offset when rounding to avoid the artifact where 2 sprites appear to move at different times because of the fractional part of their pivots.
            relPos.x = (Mathf.Round(relPos.x / assetUPP - offset.x) + offset.x + pivotOffset.x) * assetUPP;
            relPos.y = (Mathf.Round(relPos.y / assetUPP - offset.y) + offset.y + pivotOffset.y) * assetUPP;
        }
        else // PixelSnap
        {
            // Convert the units to pixels, round them, convert back to units. The offsets make sure that the distance we round is from screen pixel (fragment) edges to texel edges.
            relPos.x = (Mathf.Round(relPos.x / cameraUPP - offset.x) + offset.x + pivotOffset.x) * cameraUPP;
            relPos.y = (Mathf.Round(relPos.y / cameraUPP - offset.y) + offset.y + pivotOffset.y) * cameraUPP;
        }

        pos = relPos + camPos;

        transform.position = new Vector3(pos.x, pos.y, actualPosition.z);
    }
    public override void OnInspectorGUI()
    {
        // Using serialized objects requires a bit more work, but enables multi-object editing, undo, and Prefab overrides.
        // https://docs.unity3d.com/ScriptReference/Editor.html
        // https://stackoverflow.com/questions/55027410/editor-target-vs-editor-serializedobject

        serializedObject.Update();

        // Targeted Size
        PixelPerfectCamera.Dimension dimensionType = (PixelPerfectCamera.Dimension)Enum.GetValues(typeof(PixelPerfectCamera.Dimension)).GetValue(targetDimension.enumValueIndex);
        targetDimension.enumValueIndex = (int)(PixelPerfectCamera.Dimension)EditorGUILayout.EnumPopup("Target size", dimensionType);
        if (targetDimension.enumValueIndex == (int)PixelPerfectCamera.Dimension.Width)
        {
            EditorGUILayout.PropertyField(targetCameraWidth, new GUIContent("Width", "The target width of the camera in pixels."));
        }
        else
        {
            EditorGUILayout.PropertyField(targetCameraHeight, new GUIContent("Height", "The target height of the camera in pixels."));
        }
        EditorGUILayout.BeginHorizontal();
        maxCameraWidthEnabled.boolValue = EditorGUILayout.Toggle(maxCameraWidthEnabled.boolValue, GUILayout.Width(12));
        EditorGUI.BeginDisabledGroup(!maxCameraWidthEnabled.boolValue);
        EditorGUILayout.PropertyField(maxCameraWidth, new GUIContent("Max Width", "The maximum allowed width of the camera in pixels."));
        EditorGUI.EndDisabledGroup();
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.BeginHorizontal();
        maxCameraHeightEnabled.boolValue = EditorGUILayout.Toggle(maxCameraHeightEnabled.boolValue, GUILayout.Width(12));
        EditorGUI.BeginDisabledGroup(!maxCameraHeightEnabled.boolValue);
        EditorGUILayout.PropertyField(maxCameraHeight, new GUIContent("Max Height", "The maximum allowed height of the camera in pixels."));
        EditorGUI.EndDisabledGroup();
        EditorGUILayout.EndHorizontal();

        // Pixels Per Unit
        EditorGUILayout.PropertyField(assetsPixelsPerUnit);

        // Pixel Perfect toggle
        pixelPerfect.boolValue = EditorGUILayout.Toggle(new GUIContent("Pixel Perfect",
                                                                       "Makes the camera's pixels per unit to be a multiple of the assets' pixels per unit."), pixelPerfect.boolValue);

        // PixelSnap menu
        PixelPerfectCamera.PixelSnapMode pixelSnapModeSelected = (PixelPerfectCamera.PixelSnapMode)Enum.GetValues(typeof(PixelPerfectCamera.PixelSnapMode)).GetValue(pixelSnapMode.enumValueIndex);
        pixelSnapMode.enumValueIndex = (int)(PixelPerfectCamera.PixelSnapMode)EditorGUILayout.EnumPopup(new GUIContent("Pixel Snap mode",
                                                                                                                       "Off: disables Pixel Snap \n" +
                                                                                                                       "RetroSnap: Makes the objects snap to the asset's pixel grid \n" +
                                                                                                                       "PixelSnap: Makes the objects snap to the screen's pixel grid \n\n" +
                                                                                                                       "This option affects only objects that use the PixelSnap script."), pixelSnapModeSelected);

        // Show HUD toggle
        EditorGUILayout.PropertyField(showHUD);

        serializedObject.ApplyModifiedProperties();

        // Show results
        if (!((PixelPerfectCamera)target).isInitialized)
        {
            return;
        }
        GUILayout.BeginVertical();
        GUILayout.Space(5);
        DrawSizeStats();
        GUILayout.EndVertical();
    }