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简单几行代码让玩家水平移动更丝滑真实
可以先来看看基础的移动代码,接收玩家的输入,然后赋予刚体速度. 但是这种写法存在几个问题,下面一一纠正. 首先,如果直接改变刚体的速度,那么可能会出现穿墙的问题. 而且没有一种从速度0到缓慢加速的过程 ...
- 插件竟能如此丝滑!甚至还能查快递??
插件竟能如此丝滑!甚至还能查快递?? 1. 准备工作 1.1. 说明 1.2. 简介 1.3. 下载插件 2. 功能介绍 2.1. 整体介绍 2.2. 局部功能介绍 2.3. 快捷功能介绍 2.4. ...
- Unity技能工厂——怎样实现丝滑的角色连击动画
RPG类型的动作游戏因为其敏捷的工作动作,技能连招之间丝滑的衔接,视觉冲击感爆棚的技能释放特效,所谓"拳拳刀肉,刀刀进身"的攻击效果,吸引了一大批忠实角色类扮演游戏的忠实粉丝. 那 ...
- Unity滚动字幕如丝般顺滑
Unity滚动字幕如丝般顺滑 1,使用unity Ugui 2,将下面代码挂在到Text上 public float speed;public RectTransform maskRec;public ...
- uni-app - 电子签字板组件(签名专用写字画板,支持调整写字板 “横纵“ 方向,可调整线条粗细颜色等,Canvas 绘制非常丝滑流畅)完美兼容 H5 APP 小程序,最好用的画板签字教程插件源码
前言 网上的教程代码非常乱且都有 BUG 存在,非常难移植到自己的项目中,本文代码干净整洁注释详细. 本文实现了 全端兼容,签名专用的写字板组件,真机流畅丝滑且无 BUG, 您直接复制组件源码,按照详 ...
- 让代码丝滑般跳转,rust-analyzer,你值得拥有
1 RLS触怒了我 我是一个专一的人,从学习Rust起就在vscode中使用rls作为跳转插件(主要原因其实是懒),如果不是今天它彻底触怒了我,恐怕我还会对它继续钟情下去. 事情的原委是这样的,今天下 ...
- vs code保存自动格式化代码及eslint/tslint修复-太爽(丝滑般的感觉)
现在没有前后端分离的开发模式都不好意思跟同行交流.前后端分离的好处这里就不再赘述了. 本司开发的系统是基于Angular(ng zorro),TypeScript,后台采用Spring Boot.写前 ...
- 让你的app体验更丝滑的11种方法!冲击手机应用榜单Top3指日可待
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由WeTest质量开放平台团队 发表于云+社区专栏 一款app除了要有令人惊叹的功能和令人发指交互之外,在性能上也应该追求丝滑的要求,这 ...
- 老虎斑马“杂交”长啥样?CVPR19论文提出纹理混合器,不同花纹实现丝滑过渡 | 开源...
铜灵 发自 凹非寺 量子位 出品 | 公众号 QbitAI 如何一键减少修图时的拼接感?不如看看这篇CVPR 19论文怎么说. 来自马里兰大学.马克斯·普朗克信息学研究所.Adobe的研究人员提出了一 ...
最新文章
- 单击“登录”后,用户名和密码显示在地址栏中,不安全
- SQLServer数据库的备份/恢复的3中策略实例
- Coding中遇到的BUG集合~
- python3安装_Python 3.8.2安装教程
- 2020蓝桥杯省赛---java---A---4(七段码)
- # heapsort
- ocx在我indows7无法注册
- kettle 4.4源代码分析Transformation
- Java中的final变量、final方法和final类
- 变色龙引导启动看不到Mac分区盘符的解决办法
- JavaScript测试题
- Conflux TokenGazer AMA活动内容回顾
- 高德路径规划预估打车价格
- H3CSE园区-RRPP
- 阿里云ACP云计算对象存储OSS例题
- Android8.1 audio之compressed offload流程(四十一)
- 远光九天云平台 自主创新助力科技自强
- Linux环境java截取视频某帧另存缩略图
- 淘宝提高主图点击率怎么做?大神导航,一个神奇的网站,从此开启大神之路!
- 热带气旋强度估计——物理信息融合