unity實(shí)現(xiàn)繪畫功能
本文實(shí)例為大家分享了unity實(shí)現(xiàn)繪畫功能的具體代碼,供大家參考,具體內(nèi)容如下
直接先上效果:

gif里面有些顏色不一樣是gif功能導(dǎo)致的,繪制出來(lái)的都是同一個(gè)顏色。
原理其實(shí)也簡(jiǎn)單,通過(guò)一些列的坐標(biāo)轉(zhuǎn)換得到當(dāng)前繪制的坐標(biāo),然后根據(jù)畫筆的寬度計(jì)算像素?cái)?shù)量,最后填充像素塊顏色。
備注:
紋理必須在導(dǎo)入設(shè)置中設(shè)置了 Is Readable 標(biāo)志
Texture2D.SetPixels :設(shè)置像素顏色塊。
Texture2D.Apply :實(shí)際應(yīng)用任何先前的 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();
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于Silverlight打印的使用詳解,是否為微軟的Bug問(wèn)題
本篇文章對(duì)Silverlight打印的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
windows中使用C# 調(diào)用 C語(yǔ)言生成的dll
本文給大家介紹的是在Windows系統(tǒng)中使用C#調(diào)用C語(yǔ)言生成的DLL文件的一種思路,非常的簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下2016-11-11
C#的File類實(shí)現(xiàn)文件操作實(shí)例詳解
這篇文章主要介紹了C#的File類實(shí)現(xiàn)文件操作的方法,非常實(shí)用,需要的朋友可以參考下2014-07-07
C#連接加密的Sqlite數(shù)據(jù)庫(kù)的方法
對(duì)數(shù)據(jù)加密分兩種,一種是對(duì)數(shù)據(jù)庫(kù)本身進(jìn)行加密,另一種是對(duì)數(shù)據(jù)表中的數(shù)據(jù)進(jìn)行加密,下面通過(guò)本文給大家介紹C#連接加密的Sqlite數(shù)據(jù)庫(kù)的方法,感興趣的朋友一起看看吧2017-08-08
深入c# 類和結(jié)構(gòu)的區(qū)別總結(jié)詳解
本篇文章是對(duì)c#中類和結(jié)構(gòu)的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05

