Unity は QQ スクリーンショットを模倣しており、ホット アップデート環境で利用できます。

以前のスクリーンショット スクリプトはホット アップデート シナリオでは使用できなかったため、私は非常に無力で、問題を解決するために複数のテストを実行する必要がありました。
プレハブ構造図画像の説明を追加してください
画像の説明を追加してください
画像の説明を追加してください

オリジナルのスクリプトはホットアップデートなしで使用できます。どのボスが書いたか忘れました。オリジナルではありません。ボスに感謝します。

using UnityEngine;
using System.Collections;
using System.IO;
using System;
using System.Runtime.InteropServices;


[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class OpenFileName
{
    
    
    public int structSize = 0;
    public IntPtr dlgOwner = IntPtr.Zero;
    public IntPtr instance = IntPtr.Zero;
    public String filter = null;
    public String customFilter = null;
    public int maxCustFilter = 0;
    public int filterIndex = 0;
    public String file = null;
    public int maxFile = 0;
    public String fileTitle = null;
    public int maxFileTitle = 0;
    public String initialDir = null;
    public String title = null;
    public int flags = 0;
    public short fileOffset = 0;
    public short fileExtension = 0;
    public String defExt = null;
    public IntPtr custData = IntPtr.Zero;
    public IntPtr hook = IntPtr.Zero;
    public String templateName = null;
    public IntPtr reservedPtr = IntPtr.Zero;
    public int reservedInt = 0;
    public int flagsEx = 0;
}
public class SelectFileDialog
{
    
    
    //指定系统函数  
    [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
    public static extern bool GetSaveFileName([In, Out] OpenFileName ofn);
    public static bool GetSFN([In, Out] OpenFileName ofn)
    {
    
    
        return GetSaveFileName(ofn);
    }
}
public class CutUI : MonoBehaviour
{
    
    
    Vector2 StartPos,TempPos;  //画布内位置
    Vector3 StMsPos, EdMsPos;  //屏幕内位置
    public RectTransform SelImg;
    private RectTransform Canvas;
    public GameObject CutBtns,StartCut;

    bool isCutting = false, isPressed = false;

    private void Start()
    {
    
    
        CutBtns.SetActive(false);
        SelImg.gameObject.SetActive(false);
        Canvas = GameObject.Find("Canvas").GetComponent<RectTransform>();
    }

    // Update is called once per frame
    void Update()
    {
    
    
        if (isCutting && Input.GetMouseButtonDown(0))
        {
    
    
            isPressed = true;
            CutBtns.SetActive(false);
            SelImg.gameObject.SetActive(true);
            StMsPos = Input.mousePosition;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(Canvas, StMsPos, null, out StartPos);
            SelImg.anchoredPosition = StartPos;
        }
        if (isCutting && Input.GetMouseButton(0))
        {
    
    
            RectTransformUtility.ScreenPointToLocalPointInRectangle(Canvas, Input.mousePosition, null, out TempPos);
            SelImg.pivot = new Vector2(TempPos.x >= StartPos.x ? 0 : 1, TempPos.y >= StartPos.y ? 0 : 1);
            SelImg.sizeDelta = new Vector2(Mathf.Abs(TempPos.x - StartPos.x), Mathf.Abs(TempPos.y - StartPos.y));
        }
        if (isCutting && isPressed  && Input.GetMouseButtonUp(0))
        {
    
    
            isPressed = false;
            isCutting = false;
            EdMsPos = Input.mousePosition;
            CutBtns.SetActive(true);
        }
    }
    
    Rect CutRect;
    private Texture2D Tex;
    IEnumerator CutImage()
    {
    
    
        string Name = DateTime.Now.ToString("yyyyMMddHHmmss");

        Tex = new Texture2D((int)Mathf.Abs(StMsPos.x - EdMsPos.x), (int)Mathf.Abs(StMsPos.y - EdMsPos.y), TextureFormat.RGB24, true);

        CutRect = new Rect(StMsPos.x> EdMsPos.x? EdMsPos.x: StMsPos.x,
           StMsPos.y > EdMsPos.y ? EdMsPos.y : StMsPos.y,
           Mathf.Abs(EdMsPos.x - StMsPos.x), 
           Mathf.Abs(EdMsPos.y - StMsPos.y));

        yield return new WaitForEndOfFrame();
        Tex.ReadPixels(CutRect, 0, 0, true);
        Tex.Apply();
        yield return Tex;
        byte[] bytes = Tex.EncodeToPNG();

        string path = Application.dataPath + "/" + Name + ".png";

        OpenFileName file = new OpenFileName();
        file.structSize = Marshal.SizeOf(file);
        file.filter = "文件(*.png)";
        file.file = new string(new char[256]);
        file.maxFile = file.file.Length;
        file.fileTitle = new string(new char[64]);
        file.maxFileTitle = file.fileTitle.Length;
        file.initialDir = Application.streamingAssetsPath.Replace('/', '\\');//默认路径
        file.title = "保存文件";
        file.templateName = Name;
        file.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000008;

        if (SelectFileDialog.GetSaveFileName(file))
        {
    
    
            path = file.file + ".png";
        }
        File.WriteAllBytes(path, bytes);
    }

    public void ClickCut() {
    
    
        CutBtns.SetActive(false);
        SelImg.gameObject.SetActive(false);
        StartCoroutine(CutImage());
        StartCut.SetActive(true);
    }

    public void ClickCancel()
    {
    
    
        CutBtns.SetActive(false);
        SelImg.gameObject.SetActive(false);
        StartCut.SetActive(true);
    }

    public void ClickStartCut() {
    
    
       
        isCutting = true;
    }
}

アリババクラウドディスク: https://www.aliyundrive.com/s/qCFon9eLtTD

ホット アップデート後にスクリプトを変更しても、プレハブは変更されていません。

using UnityEngine;
using System.Collections;
using System.IO;
using System;

public class CutUI : MonoBehaviour
{
    
    
    Vector2 StartPos, TempPos;  // 画布内位置
    Vector3 StMsPos, EdMsPos;  // 屏幕内位置
    public RectTransform SelImg;
    private RectTransform Canvas;
    public GameObject CutBtns, StartCut;

    bool isCutting = false, isPressed = false;

    private void Start()
    {
    
    
        CutBtns.SetActive(false);
        SelImg.gameObject.SetActive(false);
        Canvas = GameObject.Find("Canvas").GetComponent<RectTransform>();
    }

    // Update is called once per frame
    void Update()
    {
    
    
        if (isCutting && Input.GetMouseButtonDown(0))
        {
    
    
            isPressed = true;
            CutBtns.SetActive(false);
            SelImg.gameObject.SetActive(true);
            StMsPos = Input.mousePosition;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(Canvas, StMsPos, null, out StartPos);
            SelImg.anchoredPosition = StartPos;
        }
        if (isCutting && Input.GetMouseButton(0))
        {
    
    
            RectTransformUtility.ScreenPointToLocalPointInRectangle(Canvas, Input.mousePosition, null, out TempPos);
            SelImg.pivot = new Vector2(TempPos.x >= StartPos.x ? 0 : 1, TempPos.y >= StartPos.y ? 0 : 1);
            SelImg.sizeDelta = new Vector2(Mathf.Abs(TempPos.x - StartPos.x), Mathf.Abs(TempPos.y - StartPos.y));
        }
        if (isCutting && isPressed && Input.GetMouseButtonUp(0))
        {
    
    
            isPressed = false;
            isCutting = false;
            EdMsPos = Input.mousePosition;
            CutBtns.SetActive(true);
        }
    }

    Rect CutRect;
    private Texture2D Tex;

    IEnumerator CutImage()
    {
    
    
        yield return new WaitForEndOfFrame();

        string Name = DateTime.Now.ToString("yyyyMMddHHmmss");

        // 截取选中区域的像素数据
        Vector2Int size = new Vector2Int((int)Mathf.Abs(StMsPos.x - EdMsPos.x), (int)Mathf.Abs(StMsPos.y - EdMsPos.y));
        Vector2Int position = new Vector2Int(Mathf.RoundToInt(Mathf.Min(StMsPos.x, EdMsPos.x)), Mathf.RoundToInt(Mathf.Min(StMsPos.y, EdMsPos.y)));
        Texture2D screenTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
        screenTexture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
        screenTexture.Apply();
        Color[] pixels = screenTexture.GetPixels(position.x, position.y, size.x, size.y);

        // 创建新的Texture2D来保存截图
        Tex = new Texture2D(size.x, size.y, TextureFormat.RGB24, false);
        Tex.SetPixels(pixels);
        Tex.Apply();

        // 将Texture2D转换为PNG字节数组
        byte[] bytes = Tex.EncodeToPNG();

        // 保存截图到文件
        string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        string filePath;

        if (Directory.Exists(desktopPath))
        {
    
    
            filePath = Path.Combine(desktopPath, Name + ".png");
        }
        else
        {
    
    
            string streamingAssetsPath = Application.streamingAssetsPath;
            filePath = Path.Combine(streamingAssetsPath, Name + ".png");
        }

        File.WriteAllBytes(filePath, bytes);
        Debug.Log("截图已保存至:" + filePath);
    }

    public void ClickCut()
    {
    
    
        CutBtns.SetActive(false);
        SelImg.gameObject.SetActive(false);
        StartCoroutine(CutImage());
        StartCut.SetActive(true);
    }

    public void ClickCancel()
    {
    
    
        CutBtns.SetActive(false);
        SelImg.gameObject.SetActive(false);
        StartCut.SetActive(true);
    }

    public void ClickStartCut()
    {
    
    
        isCutting = true;
    }
}

必要に応じてスクリプトを置き換えます

おすすめ

転載: blog.csdn.net/weixin_44047050/article/details/130923620