Unity 一些小功能(屏幕画画,)

利用 Line Renderer 实现屏幕画画并保存图片

cs 复制代码
// 当前正在绘制的 LineRenderer
    private LineRenderer currentLineRenderer;
    // 用于保存所有笔触的列表
    private List<LineRenderer> allLineRenderers = new List<LineRenderer>();
    // 当前笔触顶点计数器
    private int vertexCount = 0;
    // 鼠标是否处于按下状态
    private bool mouseDown = false;

    // 用于展示生成图片的 UI Image(需要在 Inspector 中绑定)
    public Image displayImage;

    private Color currentColor = Color.black;

    public void ChangeColor(string colorStr)
    {
        if(colorStr == "Red")
        {
            currentColor = Color.red;
        }
        else if(colorStr == "black")
        {
            currentColor = Color.black;
        }
        else if(colorStr == "blue")
        {
            currentColor = Color.blue;
        }
    }

    public void SavePicture()
    {
        StartCoroutine(CaptureAndSetSprite());
    }

    void Update()
    {
        // 鼠标左键按下时开始新的一笔
        if (Input.GetMouseButtonDown(0))
        {
            StartNewLine();
            mouseDown = true;
        }

        // 鼠标左键松开时结束当前绘制
        if (Input.GetMouseButtonUp(0))
        {
            mouseDown = false;
        }

        // 鼠标按下期间实时添加顶点
        if (mouseDown)
        {
            // 将鼠标屏幕坐标转换为世界坐标
            // 此处 z 的值决定平面距离摄像机的距离(根据实际需求调整)
            Vector3 pos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 3f);
            pos = Camera.main.ScreenToWorldPoint(pos);

            // 增加顶点到当前的 LineRenderer
            currentLineRenderer.positionCount = vertexCount + 1;
            currentLineRenderer.SetPosition(vertexCount, pos);
            vertexCount++;
        }
    }

    /// <summary>
    /// 每次开始新的一笔时,创建一个新的 LineRenderer,保证之前的绘制不会被清除
    /// </summary>
    void StartNewLine()
    {
        // 新建一个 GameObject 并添加 LineRenderer 组件
        GameObject lineObj = new GameObject("LineStroke");
        // 将新生成的对象设为当前对象的子物体,便于管理
        lineObj.transform.parent = this.transform;
        currentLineRenderer = lineObj.AddComponent<LineRenderer>();

        // 设置基本属性(宽度、材质、颜色等),可根据需求调整
        currentLineRenderer.widthCurve = AnimationCurve.Constant(0, 1, 0.05f);
        currentLineRenderer.positionCount = 0;
        currentLineRenderer.material = new Material(Shader.Find("Sprites/Default"));
        currentLineRenderer.startColor = currentColor;
        currentLineRenderer.endColor = currentColor;

        // 添加到列表中便于管理后续可能的操作
        allLineRenderers.Add(currentLineRenderer);
        // 重置当前笔触顶点计数器
        vertexCount = 0;
    }

    /// <summary>
    /// 协程:在当前帧渲染结束后,捕获屏幕内容,
    /// 并将生成的图片转为 Sprite,然后赋给 UI Image 组件进行展示
    /// </summary>
    IEnumerator CaptureAndSetSprite()
    {
        // 等待这一帧结束,确保所有渲染都完成
        yield return new WaitForEndOfFrame();

        // 获取当前屏幕尺寸
        int width = Screen.width;
        int height = Screen.height;
        // 新建一个 Texture2D,用于存储截屏数据
        Texture2D texture = new Texture2D(width, height, TextureFormat.RGB24, false);
        // 读取屏幕像素数据
        texture.ReadPixels(new Rect(0, 0, width, height), 0, 0);
        texture.Apply();

        // 创建 Sprite:Rect 表示截取的区域,锚点通常设为中心 (0.5, 0.5)
        Sprite newSprite = Sprite.Create(texture, new Rect(0, 0, width, height), new Vector2(0.5f, 0.5f));

        // 将生成的 Sprite 赋给 UI Image 组件进行展示
        if (displayImage != null)
        {
            displayImage.sprite = newSprite;
        }
        else
        {
            Debug.LogWarning("displayImage 没有绑定 UI Image 组件!");
        }
    }
相关推荐
黄思搏6 小时前
Unity坐标转换指南 - 3D与屏幕UI坐标互转
ui·3d·unity
weixin_424294677 小时前
在 Unity 游戏开发中,为视频选择 VP8 还是 H.264
unity·游戏引擎
一步一个foot-print1 天前
【Unity】Light Probe 替代点光源给环境动态物体加光照
unity·游戏引擎
@LYZY1 天前
Unity 中隐藏文件规则
unity·游戏引擎·游戏程序·vr
霜绛1 天前
C#知识补充(二)——命名空间、泛型、委托和事件
开发语言·学习·unity·c#
Sator11 天前
使用Unity ASE插件设置数值不会生效的问题
unity·游戏引擎
程序猿追1 天前
轻量级云原生体验:在OpenEuler 25.09上快速部署单节点K3s
人工智能·科技·机器学习·unity·游戏引擎
B0URNE1 天前
【Unity基础详解】(7)Unity核心:动画系统
unity·游戏引擎
我的golang之路果然有问题1 天前
mac M系列芯片 unity 安装会遇到的错误以及解决
经验分享·学习·macos·unity·游戏引擎
Hody912 天前
【XR开发系列】2025 年 XR 开发入门,我该选择 Unity 还是 Unreal Engine?
unity·xr·虚幻