文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

unity实现绘画功能

2024-04-02 19:55

关注

本文实例为大家分享了unity实现绘画功能的具体代码,供大家参考,具体内容如下

直接先上效果:

gif里面有些颜色不一样是gif功能导致的,绘制出来的都是同一个颜色。
原理其实也简单,通过一些列的坐标转换得到当前绘制的坐标,然后根据画笔的宽度计算像素数量,最后填充像素块颜色。

备注:

纹理必须在导入设置中设置了 Is Readable 标志
Texture2D.SetPixels :设置像素颜色块。
Texture2D.Apply :实际应用任何先前的 SetPixels 更改。

直接上代码吧:


using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Draw : MonoBehaviour
{
    public static Color Pen_Colour = Color.red;
    public static int Pen_Width = 3;
     
    public LayerMask Drawing_Layers;
     
    private Sprite drawable_sprite;
    private Texture2D drawable_texture;
     
    private Vector2 previous_drag_position;
    private Color[] clean_colours_array;
    private Collider2D[] rayResult = new Collider2D[2];
    private Color32[] cur_colors;
     
    private bool no_drawing_on_current_drag = false;
    private bool mouse_was_previously_held_down = false;
     
    void Awake()
    {
        drawable_sprite = this.GetComponent<SpriteRenderer>().sprite;
        drawable_texture = drawable_sprite.texture;
 
        clean_colours_array = new Color[(int)drawable_sprite.rect.width * (int)drawable_sprite.rect.height];
        clean_colours_array = drawable_texture.GetPixels();
    }
     
    void Update()
    {
        bool mouse_held_down = Input.GetMouseButton(0);
        if (mouse_held_down && !no_drawing_on_current_drag)
        {
            Vector2 mouse_world_position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
 
            Collider2D hit = Physics2D.OverlapPoint(mouse_world_position, Drawing_Layers.value);
            if (hit != null && hit.transform != null)
            {
                PenBrush(mouse_world_position);
                //current_brush(mouse_world_position);
            }
            else
            {
                previous_drag_position = Vector2.zero;
                if (!mouse_was_previously_held_down)
                {
                    no_drawing_on_current_drag = true;
                }
            }
        }
        else if (!mouse_held_down)
        {
            previous_drag_position = Vector2.zero;
            no_drawing_on_current_drag = false;
        }
        mouse_was_previously_held_down = mouse_held_down;
    }
     
    protected void OnDestroy()
    {
        ResetCanvas();
    }
     
    /// <summary>
    ///  重置画布
    /// </summary>
    private void ResetCanvas()
    {
        drawable_texture.SetPixels(clean_colours_array);
        drawable_texture.Apply();
    }
     
    /// <summary>
    ///  笔刷
    /// </summary>
    public void PenBrush(Vector2 world_point)
    {
        Vector2 pixel_pos = WorldToPixelCoordinates(world_point);
         
        cur_colors = drawable_texture.GetPixels32();
         
        if (previous_drag_position == Vector2.zero)
        {
            MarkPixelsToColour(pixel_pos, Pen_Width, Pen_Colour);
        }
        else
        {
            ColourBetween(previous_drag_position, pixel_pos, Pen_Width, Pen_Colour);
        }
        ApplyMarkedPixelChanges();
        
        previous_drag_position = pixel_pos;
    }
     
    private Vector2 WorldToPixelCoordinates(Vector2 world_position)
    {
        Vector3 local_pos = transform.InverseTransformPoint(world_position);
 
        float pixelWidth = drawable_sprite.rect.width;
        float pixelHeight = drawable_sprite.rect.height;
        float unitsToPixels = pixelWidth / drawable_sprite.bounds.size.x * transform.localScale.x;
 
        float centered_x = local_pos.x * unitsToPixels + pixelWidth / 2;
        float centered_y = local_pos.y * unitsToPixels + pixelHeight / 2;
 
        Vector2 pixel_pos = new Vector2(Mathf.RoundToInt(centered_x), Mathf.RoundToInt(centered_y));
 
        return pixel_pos;
    }
     
    private void ColourBetween(Vector2 start_point, Vector2 end_point, int width, Color color)
    {
        float distance = Vector2.Distance(start_point, end_point);
        Vector2 direction = (start_point - end_point).normalized;
 
        Vector2 cur_position = start_point;
        float lerp_steps = 1 / distance;
 
        for (float lerp = 0; lerp <= 1; lerp += lerp_steps)
        {
            cur_position = Vector2.Lerp(start_point, end_point, lerp);
            MarkPixelsToColour(cur_position, width, color);
        }
    }
     
    private void MarkPixelsToColour(Vector2 center_pixel, int pen_thickness, Color color_of_pen)
    {
        int center_x = (int)center_pixel.x;
        int center_y = (int)center_pixel.y;

        for (int x = center_x - pen_thickness; x <= center_x + pen_thickness; x++)
        {
            if (x >= (int)drawable_sprite.rect.width || x < 0)
                continue;
 
            for (int y = center_y - pen_thickness; y <= center_y + pen_thickness; y++)
            {
                MarkPixelToChange(x, y, color_of_pen);
            }
        }
    }
    private void MarkPixelToChange(int x, int y, Color color)
    {
        int array_pos = y * (int)drawable_sprite.rect.width + x;
 
        if (array_pos > cur_colors.Length || array_pos < 0)
            return;
 
        cur_colors[array_pos] = color;
    }
     
    private void ApplyMarkedPixelChanges()
    {
        drawable_texture.SetPixels32(cur_colors);
        drawable_texture.Apply();
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯