admin 管理员组文章数量: 1184232
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();}
}
本文标签: unity 不用插件实现丝滑绘画
版权声明:本文标题:unity 不用插件实现丝滑绘画 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.roclinux.cn/p/1698021821a283020.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论