Unity內(nèi)部截圖功能
簡單的仿照通用截圖功能制作在unity內(nèi)部截圖導(dǎo)出。

截圖框UI
????????截圖框分為四部分,遮罩、外邊框、拖拽節(jié)點(diǎn)和一個(gè)確認(rèn)按鈕。遮罩采用UIshader做一個(gè)選中區(qū)域的透明;外邊框只在開啟截圖時(shí)啟用,作提醒功能;拖拽節(jié)點(diǎn)負(fù)責(zé)在拖拽時(shí)重置選中區(qū)域。
shader部分的代碼
Shader "UI/Default_Mask_Rect"
{
? ?Properties
? ?{
? ? ? ?[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
? ? ? ?_Color ("Tint", Color) = (1,1,1,1)
? ? ? ?_StencilComp ("Stencil Comparison", Float) = 8
? ? ? ?_Stencil ("Stencil ID", Float) = 0
? ? ? ?_StencilOp ("Stencil Operation", Float) = 0
? ? ? ?_StencilWriteMask ("Stencil Write Mask", Float) = 255
? ? ? ?_StencilReadMask ("Stencil Read Mask", Float) = 255
? ? ? ?_ColorMask ("Color Mask", Float) = 15
? ? ? ?[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
? ? ?//-------------------add----------------------
? ? ? ?_OriginPos("OriginPos", vector) = (0,0,0,0)
? ? ? ?_EndPos("EndPos", vector) = (0,0,0,0)
? ? ?_Width("Width", Float) = 1
? ? ?_Height("Height", Float) = 1
? ? ?//-------------------add----------------------
? ?}
? ?SubShader
? ?{
? ? ? ?Tags
? ? ? ?{
? ? ? ? ? ?"Queue"="Transparent"
? ? ? ? ? ?"IgnoreProjector"="True"
? ? ? ? ? ?"RenderType"="Transparent"
? ? ? ? ? ?"PreviewType"="Plane"
? ? ? ? ? ?"CanUseSpriteAtlas"="True"
? ? ? ?}
? ? ? ?Stencil
? ? ? ?{
? ? ? ? ? ?Ref [_Stencil]
? ? ? ? ? ?Comp [_StencilComp]
? ? ? ? ? ?Pass [_StencilOp]
? ? ? ? ? ?ReadMask [_StencilReadMask]
? ? ? ? ? ?WriteMask [_StencilWriteMask]
? ? ? ?}
? ? ? ?Cull Off
? ? ? ?Lighting Off
? ? ? ?ZWrite Off
? ? ? ?ZTest [unity_GUIZTestMode]
? ? ? ?Blend SrcAlpha OneMinusSrcAlpha
? ? ? ?ColorMask [_ColorMask]
? ? ? ?Pass
? ? ? ?{
? ? ? ? ? ?Name "Default"
? ? ? ?CGPROGRAM
? ? ? ? ? ?#pragma vertex vert
? ? ? ? ? ?#pragma fragment frag
? ? ? ? ? ?#pragma target 2.0
? ? ? ? ? ?#include "UnityCG.cginc"
? ? ? ? ? ?#include "UnityUI.cginc"
? ? ? ? ? ?#pragma multi_compile __ UNITY_UI_CLIP_RECT
? ? ? ? ? ?#pragma multi_compile __ UNITY_UI_ALPHACLIP
? ? ? ? #pragma multi_compile _ROUNDMODE_RECT _ROUNDMODE_DYNAMIC_RECT
? ? ? ? ? ?struct appdata_t
? ? ? ? ? ?{
? ? ? ? ? ? ? ?float4 vertex ? : POSITION;
? ? ? ? ? ? ? ?float4 color ? ?: COLOR;
? ? ? ? ? ? ? ?float2 texcoord : TEXCOORD0;
? ? ? ? ? ? ? ?UNITY_VERTEX_INPUT_INSTANCE_ID
? ? ? ? ? ?};
? ? ? ? ? ?struct v2f
? ? ? ? ? ?{
? ? ? ? ? ? ? ?float4 vertex ? : SV_POSITION;
? ? ? ? ? ? ? ?fixed4 color ? ?: COLOR;
? ? ? ? ? ? ? ?float2 texcoord ?: TEXCOORD0;
? ? ? ? ? ? ? ?float4 worldPosition : TEXCOORD1;
? ? ? ? ? ? ? ?UNITY_VERTEX_OUTPUT_STEREO
? ? ? ? ? ?};
? ? ? ? ? ?fixed4 _Color;
? ? ? ? ? ?fixed4 _TextureSampleAdd;
? ? ? ? ? ?float4 _ClipRect;
? ? ? ? //-------------------add----------------------
? ? ? ? float2 _OriginPos;
? ? ? ? float2 _EndPos;
? ? ? ? half _Width;
? ? ? ? half _Height;
? ? ? ? //-------------------add----------------------
? ? ? ? ? ?v2f vert(appdata_t v)
? ? ? ? ? ?{
? ? ? ? ? ? ? ?v2f OUT;
? ? ? ? ? ? ? ?UNITY_SETUP_INSTANCE_ID(v);
? ? ? ? ? ? ? ?UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
? ? ? ? ? ? ? ?OUT.worldPosition = v.vertex;
? ? ? ? ? ? ? ?OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
? ? ? ? ? ? ? ?OUT.texcoord = v.texcoord;
? ? ? ? ? ? ? ?OUT.color = v.color * _Color;
? ? ? ? ? ? ? ?return OUT;
? ? ? ? ? ?}
? ? ? ? ? ?sampler2D _MainTex;
? ? ? ? ? ?fixed4 frag(v2f IN) : SV_Target
? ? ? ? ? ?{
? ? ? ? ? ? ? ?half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
? ? ? ? ? ? ? ?#ifdef UNITY_UI_CLIP_RECT
? ? ? ? ? ? ? ?color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
? ? ? ? ? ? ? ?#endif
? ? ? ? ? ? ? ?#ifdef UNITY_UI_ALPHACLIP
? ? ? ? ? ? ? ?clip (color.a - 0.001);
? ? ? ? ? ? ? ?#endif
? ? ? ? ? ? ? ?float2 _CenterT = (_OriginPos + _EndPos)/2;
? ? ? ? ? ? ? ?half _SliderXT = abs(_EndPos.x - _OriginPos.x)/2;
? ? ? ? ? ? ? ?half _SliderYT = abs(_EndPos.y - _OriginPos.y)/2;
? ? ? ? ? ?//-------------------add----------------------
? ? ? ? ? ?//計(jì)算X軸方向距離
? ? ? ? ? ?float disX = distance(IN.worldPosition.x, _CenterT.x);
? ? ? ? ? ?//計(jì)算Y軸方向距離
? ? ? ? ? ?float disY = distance(IN.worldPosition.y, _CenterT.y);
? ? ? ? ? ?//計(jì)算過渡范圍內(nèi)的alpha值
? ? ? ? ? ?color.a *= (abs(disX) > _SliderXT) || (abs(disY) > _SliderYT);
? ? ? ? ? ?//-------------------add----------------------
? ? ? ? ? ? ? ?return color;
? ? ? ? ? ?}
? ? ? ?ENDCG
? ? ? ?}
? ?}
}
shader主要根據(jù)輸入的起點(diǎn)終點(diǎn)兩個(gè)坐標(biāo)確定一個(gè)需要剔除的矩形區(qū)域。
UI部分的代碼
using App.System;
using UnityEngine;
using UnityEngine.UI;
namespace App.UI.NewUI
{
? ?public class UIExperimentScreenShotMask : MonoBehaviour
? ?{
? ? ? ?public static UIExperimentScreenShotMask instance;
? ? ? ?public Image rectMask;
? ? ? ?private Vector2 opdata;
? ? ? ?private Vector2 epdata;
? ? ? ?private Vector2 originpoint;
? ? ? ?private Vector2 endpoint;
? ? ? ?public Image leftup;
? ? ? ?public Image middleup;
? ? ? ?public Image rightup;
? ? ? ?public Image leftcenter;
? ? ? ?public Image rightcenter;
? ? ? ?public Image leftdown;
? ? ? ?public Image middledown;
? ? ? ?public Image rightdown;
? ? ? ?public Button surebtn;
? ? ? ?public GameObject fullscreen;
? ? ? ?private bool candrag;
? ? ? ?private bool isdrag;
? ? ? ?public Texture2D lurd;
? ? ? ?public Texture2D ud;
? ? ? ?public Texture2D lr;
? ? ? ?public Texture2D ldru;
? ? ? ?private void Awake()
? ? ? ?{
? ? ? ? ? ?instance = this;
? ? ? ? ? ?opdata = new Vector2(-Screen.width / 2, Screen.height / 2);
? ? ? ? ? ?epdata = new Vector2(Screen.width / 2, -Screen.height / 2);
? ? ? ? ? ?originpoint = opdata;
? ? ? ? ? ?endpoint = epdata;
? ? ? ? ? ?surebtn.onClick.AddListener(SureCut);
? ? ? ? ? ?var leftup_evt = leftup.gameObject.AddComponent<UIMouseEvent>();
? ? ? ? ? ?leftup_evt.onEnter += BorderOnEnter;
? ? ? ? ? ?leftup_evt.onExit += BorderOnExit;
? ? ? ? ? ?leftup_evt.onDrag += BorderOnDrag;
? ? ? ? ? ?var middleup_evt = middleup.gameObject.AddComponent<UIMouseEvent>();
? ? ? ? ? ?middleup_evt.onEnter += BorderOnEnter;
? ? ? ? ? ?middleup_evt.onExit += BorderOnExit;
? ? ? ? ? ?middleup_evt.onDrag += BorderOnDrag;
? ? ? ? ? ?var rightup_evt = rightup.gameObject.AddComponent<UIMouseEvent>();
? ? ? ? ? ?rightup_evt.onEnter += BorderOnEnter;
? ? ? ? ? ?rightup_evt.onExit += BorderOnExit;
? ? ? ? ? ?rightup_evt.onDrag += BorderOnDrag;
? ? ? ? ? ?var leftcenter_evt = leftcenter.gameObject.AddComponent<UIMouseEvent>();
? ? ? ? ? ?leftcenter_evt.onEnter += BorderOnEnter;
? ? ? ? ? ?leftcenter_evt.onExit += BorderOnExit;
? ? ? ? ? ?leftcenter_evt.onDrag += BorderOnDrag;
? ? ? ? ? ?var rightcenter_evt = rightcenter.gameObject.AddComponent<UIMouseEvent>();
? ? ? ? ? ?rightcenter_evt.onEnter += BorderOnEnter;
? ? ? ? ? ?rightcenter_evt.onExit += BorderOnExit;
? ? ? ? ? ?rightcenter_evt.onDrag += BorderOnDrag;
? ? ? ? ? ?var leftdown_evt = leftdown.gameObject.AddComponent<UIMouseEvent>();
? ? ? ? ? ?leftdown_evt.onEnter += BorderOnEnter;
? ? ? ? ? ?leftdown_evt.onExit += BorderOnExit;
? ? ? ? ? ?leftdown_evt.onDrag += BorderOnDrag;
? ? ? ? ? ?var middledown_evt = middledown.gameObject.AddComponent<UIMouseEvent>();
? ? ? ? ? ?middledown_evt.onEnter += BorderOnEnter;
? ? ? ? ? ?middledown_evt.onExit += BorderOnExit;
? ? ? ? ? ?middledown_evt.onDrag += BorderOnDrag;
? ? ? ? ? ?var rightdown_evt = rightdown.gameObject.AddComponent<UIMouseEvent>();
? ? ? ? ? ?rightdown_evt.onEnter += BorderOnEnter;
? ? ? ? ? ?rightdown_evt.onExit += BorderOnExit;
? ? ? ? ? ?rightdown_evt.onDrag += BorderOnDrag;
? ? ? ? ? ?gameObject.SetActive(false);
? ? ? ?}
? ? ? ?public void Show()
? ? ? ?{
? ? ? ? ? ?gameObject.SetActive(true);
? ? ? ? ? ?originpoint = opdata;
? ? ? ? ? ?endpoint = epdata;
? ? ? ? ? ?RefreshMask();
? ? ? ? ? ?fullscreen.SetActive(true);
? ? ? ? ? ?candrag = true;
? ? ? ?}
? ? ? ?public void Hide()
? ? ? ?{
? ? ? ? ? ?gameObject.SetActive(false);
? ? ? ?}
? ? ? ?
? ? ? ?/// <summary>
? ? ? ?/// 檢測開始和結(jié)束框選,排除開始直接點(diǎn)擊完成按鈕的情況
? ? ? ?/// </summary>
? ? ? ?private void Update()
? ? ? ?{
? ? ? ? ? ?if (Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Escape))
? ? ? ? ? ?{
? ? ? ? ? ? ? ?Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
? ? ? ? ? ? ? ?originpoint = opdata;
? ? ? ? ? ? ? ?endpoint = epdata;
? ? ? ? ? ? ? ?RefreshMask();
? ? ? ? ? ? ? ?Hide();
? ? ? ? ? ? ? ?return;
? ? ? ? ? ?}
? ? ? ? ? ?if (candrag)
? ? ? ? ? ?{
? ? ? ? ? ? ? ?if (Input.GetMouseButtonDown(0) && Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out RaycastHit hitInfo) && hitInfo.transform != null && hitInfo.transform.name != "surebtn")
? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ?OnBeginDrag();
? ? ? ? ? ? ? ? ? ?isdrag = true;
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?if (isdrag)
? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ?OnDrag();
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?if (Input.GetMouseButtonUp(0))
? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ?OnEndDrag();
? ? ? ? ? ? ? ? ? ?isdrag = false;
? ? ? ? ? ? ? ? ? ?candrag = false;
? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?/// <summary>
? ? ? ?/// 開始框選
? ? ? ?/// </summary>
? ? ? ?public void OnBeginDrag()
? ? ? ?{
? ? ? ? ? ?originpoint = new Vector2(Input.mousePosition.x - Screen.width / 2f,
? ? ? ? ? ? ? ?Input.mousePosition.y - Screen.height / 2f);
? ? ? ? ? ?endpoint = originpoint;
? ? ? ? ? ?fullscreen.SetActive(false);
? ? ? ? ? ?RefreshMask();
? ? ? ?}
? ? ? ?/// <summary>
? ? ? ?/// 框選中
? ? ? ?/// </summary>
? ? ? ?public void OnDrag()
? ? ? ?{
? ? ? ? ? ?endpoint = new Vector2(Input.mousePosition.x - Screen.width / 2f,
? ? ? ? ? ? ? ?Input.mousePosition.y - Screen.height / 2f);
? ? ? ? ? ?RefreshMask();
? ? ? ?}
? ? ? ?/// <summary>
? ? ? ?/// 結(jié)束框選
? ? ? ?/// </summary>
? ? ? ?public void OnEndDrag()
? ? ? ?{
? ? ? ? ? ?endpoint = new Vector2(Input.mousePosition.x - Screen.width / 2f,
? ? ? ? ? ? ? ?Input.mousePosition.y - Screen.height / 2f);
? ? ? ? ? ?Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
? ? ? ? ? ?RefreshMask();
? ? ? ?}
? ? ? ?/// <summary>
? ? ? ?/// 刷新框選區(qū)域
? ? ? ?/// </summary>
? ? ? ?private void RefreshMask()
? ? ? ?{
? ? ? ? ? ?var op = new Vector4(originpoint.x, originpoint.y, 0, 0);
? ? ? ? ? ?var ep = new Vector4(endpoint.x, endpoint.y, 0, 0);
? ? ? ? ? ?rectMask.material.SetVector("_OriginPos", op);
? ? ? ? ? ?rectMask.material.SetVector("_EndPos", ep);
? ? ? ? ? ?leftup.GetComponent<RectTransform>().anchoredPosition = originpoint;
? ? ? ? ? ?middleup.GetComponent<RectTransform>().anchoredPosition =
? ? ? ? ? ? ? ?new Vector2((originpoint.x + endpoint.x) / 2, originpoint.y);
? ? ? ? ? ?rightup.GetComponent<RectTransform>().anchoredPosition = new Vector2(endpoint.x, originpoint.y);
? ? ? ? ? ?leftcenter.GetComponent<RectTransform>().anchoredPosition =
? ? ? ? ? ? ? ?new Vector2(originpoint.x, (originpoint.y + endpoint.y) / 2);
? ? ? ? ? ?rightcenter.GetComponent<RectTransform>().anchoredPosition =
? ? ? ? ? ? ? ?new Vector2(endpoint.x, (originpoint.y + endpoint.y) / 2);
? ? ? ? ? ?leftdown.GetComponent<RectTransform>().anchoredPosition = new Vector2(originpoint.x, endpoint.y);
? ? ? ? ? ?middledown.GetComponent<RectTransform>().anchoredPosition =
? ? ? ? ? ? ? ?new Vector2((originpoint.x + endpoint.x) / 2, endpoint.y);
? ? ? ? ? ?rightdown.GetComponent<RectTransform>().anchoredPosition = new Vector2(endpoint.x, endpoint.y);
? ? ? ? ? ?surebtn.GetComponent<RectTransform>().anchoredPosition = new Vector2(
? ? ? ? ? ? ? ?originpoint.x > endpoint.x
? ? ? ? ? ? ? ? ? ?? originpoint.x
? ? ? ? ? ? ? ? ? ?: endpoint.x - surebtn.GetComponent<RectTransform>().rect.width / 2,
? ? ? ? ? ? ? ?originpoint.y < endpoint.y
? ? ? ? ? ? ? ? ? ?? originpoint.y
? ? ? ? ? ? ? ? ? ?: endpoint.y + surebtn.GetComponent<RectTransform>().rect.height / 2);
? ? ? ?}
? ? ? ?/// <summary>
? ? ? ?/// 鼠標(biāo)進(jìn)入節(jié)點(diǎn)
? ? ? ?/// </summary>
? ? ? ?/// <param name="border"></param>
? ? ? ?private void BorderOnEnter(UIMouseEvent border)
? ? ? ?{
? ? ? ? ? ?if (candrag)
? ? ? ? ? ? ? ?return;
? ? ? ? ? ?switch (border.name)
? ? ? ? ? ?{
? ? ? ? ? ? ? ?case "leftup":
? ? ? ? ? ? ? ? ? ?Cursor.SetCursor(lurd, new Vector2(500, 500), CursorMode.Auto);
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case "middleup":
? ? ? ? ? ? ? ? ? ?Cursor.SetCursor(ud, new Vector2(500, 500), CursorMode.Auto);
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case "rightup":
? ? ? ? ? ? ? ? ? ?Cursor.SetCursor(ldru, new Vector2(500, 500), CursorMode.Auto);
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case "leftcenter":
? ? ? ? ? ? ? ? ? ?Cursor.SetCursor(lr, new Vector2(500, 500), CursorMode.Auto);
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case "rightcenter":
? ? ? ? ? ? ? ? ? ?Cursor.SetCursor(lr, new Vector2(500, 500), CursorMode.Auto);
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case "leftdown":
? ? ? ? ? ? ? ? ? ?Cursor.SetCursor(ldru, new Vector2(500, 500), CursorMode.Auto);
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case "middledown":
? ? ? ? ? ? ? ? ? ?Cursor.SetCursor(ud, new Vector2(500, 500), CursorMode.Auto);
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case "rightdown":
? ? ? ? ? ? ? ? ? ?Cursor.SetCursor(lurd, new Vector2(500, 500), CursorMode.Auto);
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ?}
? ? ? ? ? ?RefreshMask();
? ? ? ?}
? ? ? ?/// <summary>
? ? ? ?/// 拖拽節(jié)點(diǎn)
? ? ? ?/// </summary>
? ? ? ?/// <param name="border"></param>
? ? ? ?private void BorderOnDrag(UIMouseEvent border)
? ? ? ?{
? ? ? ? ? ?if (candrag)
? ? ? ? ? ? ? ?return;
? ? ? ? ? ?var newpos = border.GetComponent<RectTransform>().anchoredPosition;
? ? ? ? ? ?switch (border.name)
? ? ? ? ? ?{
? ? ? ? ? ? ? ?case "leftup":
? ? ? ? ? ? ? ? ? ?originpoint = newpos;
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case "middleup":
? ? ? ? ? ? ? ? ? ?originpoint = new Vector2(originpoint.x, newpos.y);
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case "rightup":
? ? ? ? ? ? ? ? ? ?originpoint = new Vector2(originpoint.x, newpos.y);
? ? ? ? ? ? ? ? ? ?endpoint = new Vector2(newpos.x, endpoint.y);
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case "leftcenter":
? ? ? ? ? ? ? ? ? ?originpoint = new Vector2(newpos.x, originpoint.y);
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case "rightcenter":
? ? ? ? ? ? ? ? ? ?endpoint = new Vector2(newpos.x, endpoint.y);
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case "leftdown":
? ? ? ? ? ? ? ? ? ?originpoint = new Vector2(newpos.x, originpoint.y);
? ? ? ? ? ? ? ? ? ?endpoint = new Vector2(endpoint.x, newpos.y);
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case "middledown":
? ? ? ? ? ? ? ? ? ?endpoint = new Vector2(endpoint.x, newpos.y);
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?case "rightdown":
? ? ? ? ? ? ? ? ? ?endpoint = newpos;
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ?}
? ? ? ? ? ?RefreshMask();
? ? ? ?}
? ? ? ?/// <summary>
? ? ? ?/// 鼠標(biāo)離開節(jié)點(diǎn)
? ? ? ?/// </summary>
? ? ? ?/// <param name="border"></param>
? ? ? ?private void BorderOnExit(UIMouseEvent border)
? ? ? ?{
? ? ? ? ? ?Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
? ? ? ? ? ?RefreshMask();
? ? ? ?}
? ? ? ?/// <summary>
? ? ? ?/// 確認(rèn)截圖
? ? ? ?/// </summary>
? ? ? ?private void SureCut()
? ? ? ?{
? ? ? ? ? ?SExperimentScreenShot.instance.ScreenShot_ReadPixelsWithCamera(Camera.main, originpoint, endpoint);
? ? ? ? ? ?Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
? ? ? ? ? ?originpoint = opdata;
? ? ? ? ? ?endpoint = epdata;
? ? ? ? ? ?RefreshMask();
? ? ? ? ? ?Hide();
? ? ? ?}
? ?}
}
這部分的功能大體上就是框選區(qū)域的邏輯和在拖拽節(jié)點(diǎn)時(shí)cursor的修改。
截圖系統(tǒng)
截圖系統(tǒng)負(fù)責(zé)開啟截圖模式和截圖之后的圖片保存。
截圖系統(tǒng)代碼
using UnityEngine;
using System.IO;
using App.UI.NewUI;
using SFB;
namespace App.System
{
? ?public class SExperimentScreenShot : MonoBehaviour
? ?{
? ? ? ?public static SExperimentScreenShot instance;
? ? ? ?
? ? ? ?private void Awake()
? ? ? ?{
? ? ? ? ? ?instance = this;
? ? ? ?}
? ? ? ?private void Update()
? ? ? ?{
? ? ? ? ? ?if (Input.GetKeyUp(KeyCode.F1))
? ? ? ? ? ?{
? ? ? ? ? ? ? ?ScreenShot_ScreenCapture();
? ? ? ? ? ?}
? ? ? ? ? ?else if (Input.GetKeyUp(KeyCode.F2))
? ? ? ? ? ?{
? ? ? ? ? ? ? ?UIExperimentScreenShotMask.instance.Show();
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?
? ? ? ?/// <summary>
? ? ? ?/// 全屏截圖
? ? ? ?/// </summary>
? ? ? ?private void ScreenShot_ScreenCapture()
? ? ? ?{
? ? ? ? ? ?ScreenCapture.CaptureScreenshot($"{Application.dataPath}/ss.png");
? ? ? ?}
? ? ? ?
? ? ? ?/// <summary>
? ? ? ?/// 根據(jù)相機(jī)截圖
? ? ? ?/// </summary>
? ? ? ?/// <param name="_camera"></param>
? ? ? ?/// <param name="cuto"></param>
? ? ? ?/// <param name="cute"></param>
? ? ? ?public void ScreenShot_ReadPixelsWithCamera(Camera _camera, Vector2 cuto, Vector2 cute)
? ? ? ?{
? ? ? ? ? ?RenderTexture rt = new RenderTexture(Screen.width, Screen.height, 16);
? ? ? ? ? ?_camera.targetTexture = rt;
? ? ? ? ? ?_camera.Render();
? ? ? ? ? ?RenderTexture.active = rt;
? ? ? ? ? ?
? ? ? ? ? ?Texture2D t = new Texture2D((int)Mathf.Abs(cute.x - cuto.x), (int)Mathf.Abs(cute.y - cuto.y));
? ? ? ? ? ?t.ReadPixels(new Rect((cuto.x < cute.x ? cuto.x : cute.x) + Screen.width/2, Screen.height/2 - (cuto.y > cute.y ? cuto.y : cute.y), t.width, t.height), 0, 0);
? ? ? ? ? ?if (t.width > 540)
? ? ? ? ? ?{
? ? ? ? ? ? ? ?t = ScaleTexture(t, 540, (int)(t.height / (float)t.width * 540));
? ? ? ? ? ?}
? ? ? ? ? ?t.Apply();
? ? ? ? ? ?_camera.targetTexture = null;
? ? ? ? ? ?RenderTexture.active = null;
? ? ? ? ? ?GameObject.Destroy(rt);
? ? ? ? ? ?
? ? ? ? ? ?//輸出圖片
? ? ? ? ? ?SavePNG(t);
? ? ? ?}
? ? ? ?/// <summary>
? ? ? ?/// 截圖縮放
? ? ? ?/// </summary>
? ? ? ?/// <param name="source">原圖</param>
? ? ? ?/// <param name="targetWidth">目標(biāo)寬度</param>
? ? ? ?/// <param name="targetHeight">目標(biāo)高度</param>
? ? ? ?/// <returns></returns>
? ? ? ?private Texture2D ScaleTexture(Texture2D source, int targetWidth, int targetHeight)
? ? ? ?{
? ? ? ? ? ?Texture2D result = new Texture2D(targetWidth, targetHeight, source.format, true);
? ? ? ? ? ?Color[] rpixels = result.GetPixels(0);
? ? ? ? ? ?float incX = ((float) 1 / source.width) * ((float) source.width / targetWidth);
? ? ? ? ? ?float incY = ((float) 1 / source.height) * ((float) source.height / targetHeight);
? ? ? ? ? ?for (int px = 0; px < rpixels.Length; px++)
? ? ? ? ? ?{
? ? ? ? ? ? ? ?rpixels[px] = source.GetPixelBilinear(incX * ((float) px % targetWidth),
? ? ? ? ? ? ? ? ? ?incY * ((float) Mathf.Floor(px / targetWidth)));
? ? ? ? ?? }
? ? ? ? ? ?result.SetPixels(rpixels, 0);
? ? ? ? ? ?result.Apply();
? ? ? ? ? ?return result;
? ? ? ?}
? ? ? ?/// <summary>
? ? ? ?/// 保存PDF
? ? ? ?/// </summary>
? ? ? ?private void SavePNG(Texture2D t)
? ? ? ?{
? ? ? ? ? ?var path = StandaloneFileBrowser.SaveFilePanel("保存截圖", "", $"", "png");
? ? ? ? ? ?if (string.IsNullOrEmpty(path))
? ? ? ? ? ?{
? ? ? ? ? ? ? ?
? ? ? ? ? ?}
? ? ? ? ? ?else
? ? ? ? ? ?{
? ? ? ? ? ? ? ?File.WriteAllBytes(path, t.EncodeToPNG());
? ? ? ? ? ?}
? ? ? ?}
? ?}
}通過快捷鍵觸發(fā)截圖UI開啟,獲取到截圖區(qū)域后,從camera的渲染上截取所需范圍的texture2D,然后進(jìn)行保存。通過以上代碼就可以實(shí)現(xiàn)簡單的unity內(nèi)部截圖。

