private void DrawSizeStats() { PixelPerfectCamera myCamera = (PixelPerfectCamera)target; EditorGUI.BeginDisabledGroup(true); // Size { GUIStyle style = new GUIStyle(GUI.skin.label); style.richText = true; string width = string.Format("{0:0.00}", myCamera.cameraSize.x); string height = string.Format("{0:0.00}", myCamera.cameraSize.y); if (myCamera.contraintUsed == PixelPerfectCamera.ConstraintType.Horizontal) { width = makeBold(width); } else if (myCamera.contraintUsed == PixelPerfectCamera.ConstraintType.Vertical) { height = makeBold(height); } EditorGUILayout.LabelField("Size", string.Format("{0} x {1}", width, height), style); } // Pixels Per Unit { string ppuString = string.Format("{0:0.00}", myCamera.cameraPixelsPerUnit); string tooltipString = "The number of screen pixels a unit is rendered to."; EditorGUILayout.LabelField(new GUIContent("Pixels Per Unit", tooltipString), new GUIContent(ppuString)); } // Ratio { string ratioFormat = (myCamera.pixelPerfect) ? "{0:0}" : "{0:0.0000}"; string pixelsString = string.Format(ratioFormat + "x [{1:0.00} x {2:0.00}]", myCamera.ratio, myCamera.nativeAssetResolution.x, myCamera.nativeAssetResolution.y); string tooltipString = "The screen resolution as a multiple of 2 numbers. The first is the number of screen pixels an asset pixel will render to. The second is the camera resolution in asset pixels."; EditorGUILayout.LabelField(new GUIContent("Pixels", tooltipString), new GUIContent(pixelsString)); } // Target Coverage { string percentageUsed = string.Format("{0:P2}", myCamera.fovCoverage); string tooltipString = "How much of the targeted camera size was covered."; EditorGUILayout.LabelField(new GUIContent("Coverage", tooltipString), new GUIContent(percentageUsed)); } EditorGUI.EndDisabledGroup(); }
void OnWillRenderObject() { //Debug.Log("on will" + Camera.current); Camera cam = Camera.current; if (!cam) { return; } PixelPerfectCamera pixelPerfectCamera = cam.GetComponent <PixelPerfectCamera>(); bool retroSnap = (pixelPerfectCamera == null) ? false : pixelPerfectCamera.retroSnap; #if !REDUCE_JITTER if (!retroSnap) { return; } #endif 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.x = (cam.pixelWidth % 2 == 0) ? 0 : 0.5f; offset.y = (cam.pixelHeight % 2 == 0) ? 0 : 0.5f; // 精灵图锚点的偏移量 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 (retroSnap) { // 这里没什么可做的。主偏移量已经以资产像素为单位。 } else { float camPixelsPerAssetPixel = cameraPPU / sprite.pixelsPerUnit; pivotOffset *= camPixelsPerAssetPixel; // convert to screen pixels } } if (retroSnap) { float assetPPU = pixelPerfectCamera.assetsPixelsPerUnit; float assetUPP = 1.0f / assetPPU; float camPixelsPerAssetPixel = cameraPPU / assetPPU; offset.x /= camPixelsPerAssetPixel; // 零个或半个屏幕像素的纹理像素 offset.y /= camPixelsPerAssetPixel; // 当四舍五入时,我们不考虑轴心的偏移量,这是为了避免由于轴心的小数部分而出现两个精灵在不同时间移动的伪影。 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 { //将单位都转换为像素,四舍五入,再转换回单位。偏移量确保我们四舍五入的距离是从屏幕像素(片段)边缘到纹理元(texel)边缘。 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); }