Unity涂鸦【1】——基于Vectrosity的屏幕涂鸦和白板涂鸦的简单实现
〇、涂鸦与画线
- Vectrosity的介绍
The ultimate professional line-drawing utility, continuously supported since 2010! Find out why Unity users call Vectrosity “great,” “wonderful,” and why buying it “was the smartest move I’ve made for a long time.”
以上文字用人话来讲:
Vectrosity自2010年横空出世以来——牢记使命不忘初心,迄今已成为最为高端、大气、上档次的画线工具。
特点: Vectrosity是一个非开源的商业包。
本文讨论的内容:基于Vectrosity包进行画线涂鸦
一、简单涂鸦的演示
- 屏幕涂鸦演示
- 黑板涂鸦演示
二、用到的包
asset store中的Vectrosity包。
三、涂鸦的实现
1、屏幕涂鸦
- 屏幕涂鸦的过程
【1】按下鼠标左键开始单笔涂鸦,松开鼠标左键则停止本笔涂鸦。【2】再次按下则开始画另一笔涂鸦。【3】每一笔涂鸦信息用Vectrosity中的一个line对象来保存【4】涂鸦的时候,取点的位置是屏幕鼠标位置【2D取xy,3D自动取xy同时自动加一个固定的z】【5】用Vectrosity来显示所有的line对象
- 屏幕涂鸦的代码实现
代码来自官网DrawLinesMouse.cs,略有改动
// The DrawLinesTouch script adapted to work with mouse input, with the option for 3D or 2D lines
using UnityEngine;
using Vectrosity;
using System.Collections.Generic;/// <summary>
/// 屏幕涂鸦:
/// 【1】按下鼠标左键开始单笔涂鸦,松开鼠标左键则停止本笔涂鸦。
/// 【2】再次按下则开始画另一笔涂鸦。
/// 【3】每一笔涂鸦信息用Vectrosity中的一个line对象来保存
/// 【4】涂鸦的时候,取点的位置是屏幕鼠标位置【2D取xy,3D自动取xy同时自动加一个固定的z】
/// 【5】用Vectrosity来显示所有的line对象
/// </summary>
public class DrawLinesMouseV2 : MonoBehaviour
{public Texture2D lineTex;public int maxPoints = 5000;public float lineWidth = 4.0f;public int minPixelMove = 5; // Must move at least this many pixels per sample for a new segment to be recordedpublic bool useEndCap = false;public Texture2D capLineTex;public Texture2D capTex;public float capLineWidth = 20.0f;// If line3D is true, the line is drawn in the scene rather than as an overlay. Note that in this demo, the line will look the same// in the game view either way, but you can see the difference in the scene view.public bool line3D = false;public float distanceFromCamera = 1.0f;/// <summary>/// line的对象/// </summary>private VectorLine line;/// <summary>/// 所有的线:有很多很多根线/// </summary>private List<VectorLine> lines = new List<VectorLine>();private Vector3 previousPosition;private int sqrMinPixelMove;private bool canDraw = false;/// <summary>/// line被创建了?,没被创建的话,按下鼠标左键则会创建一根线。/// </summary>private bool hasCreated;private float useLineWidth;private Texture2D tex;void Start(){if (useEndCap){VectorLine.SetEndCap("RoundCap", EndCap.Mirror, capLineTex, capTex);tex = capLineTex;useLineWidth = capLineWidth;}else{tex = lineTex;useLineWidth = lineWidth;}// Used for .sqrMagnitude, which is faster than .magnitudesqrMinPixelMove = minPixelMove * minPixelMove;}void Update(){//获取鼠标位置var newPoint = GetMousePos();// 按下鼠标左键,则开始一笔新的涂鸦(对应为一根新的线)。Mouse button clicked, so start a new lineif (Input.GetMouseButtonDown(0)){if (!hasCreated){if (line3D){line = new VectorLine("DrawnLine3D", new List<Vector3>(), tex, useLineWidth, LineType.Continuous,Joins.Weld);}else{line = new VectorLine("DrawnLine", new List<Vector2>(), tex, useLineWidth, LineType.Continuous, Joins.Weld);}line.endPointsUpdate =2; // Optimization for updating only the last couple points of the line, and the rest is not re-computedif (useEndCap){line.endCap = "RoundCap";}hasCreated = true;}if (line3D){line.points3.Clear();line.Draw3D();}else{line.points2.Clear();//line.Draw();//显示多笔涂鸦信息if(! lines.Contains(line)) lines.Add(line);lines.ForEach(line=>line.Draw());}previousPosition = Input.mousePosition;if (line3D){line.points3.Add(newPoint);}else{line.points2.Add(newPoint);}canDraw = true;}// Mouse button held down and mouse has moved far enough to make a new point//鼠标左键一直按着,并且鼠标在移动,新点与上一个点距离达到一定程度时,该点才能被取样else if (Input.GetMouseButton(0) && (Input.mousePosition - previousPosition).sqrMagnitude > sqrMinPixelMove &&canDraw){previousPosition = Input.mousePosition;int pointCount;if (line3D){line.points3.Add(newPoint);pointCount = line.points3.Count;line.Draw3D();}else{line.points2.Add(newPoint);pointCount = line.points2.Count;line.Draw();if (pointCount >= maxPoints){canDraw = false;}}}//松开鼠标左键,本次画线结束,hasCreated置空,后面再次按下的时候,可以创建新的线if (Input.GetMouseButtonUp(0)){hasCreated = false;}Vector3 GetMousePos(){var p = Input.mousePosition;if (line3D){p.z = distanceFromCamera;return Camera.main.ScreenToWorldPoint(p);}return p;}}
}
2、白板涂鸦的实现
- 白板涂鸦的实现原理
/************************************************************实现原理:* 【0】使用的包asset store 中的Vectrosity* 【1】从摄像机发射一条射线,方向指向屏幕的鼠标位置* 【2】白板Plane上设置一个BoxCollider,把BoxCollider扩大一点,* 特别是靠近相机的一边,要覆盖白板,让字显示在白板前面,而不是白板上【不然模型重叠会闪烁】* 【3】每帧刷新射线,捕捉在白板上的碰撞点* 【4】鼠标按下时开始涂鸦,弹起时完成一笔涂鸦,调用Vectrosity把该笔涂鸦的点显示出来* 【5】调用Vectrosity显示每一笔涂鸦的点***********************************************************/
- 白板涂鸦的代码脚本
using UnityEngine;
using Vectrosity; //asset store search [Vectrosity]
using System.Collections.Generic;/// <summary>
/// 白板涂鸦
/// 白板——就是一个3D Plane,增加一个BOX碰撞体包围框
/// </summary>
public class DrawOnWhiteBoard : MonoBehaviour
{/************************************************************实现原理:* 【0】使用的包asset store 中的Vectrosity* 【1】从摄像机发射一条射线,方向指向屏幕的鼠标位置* 【2】白板Plane上设置一个BoxCollider,把BoxCollider扩大一点,* 特别是靠近相机的一边,要覆盖白板,让字显示在白板前面,而不是白板上【不然模型重叠会闪烁】* 【3】每帧刷新射线,捕捉在白板上的碰撞点* 【4】鼠标按下时开始涂鸦,弹起时完成一笔涂鸦,调用Vectrosity把该笔涂鸦的点显示出来* 【5】调用Vectrosity显示每一笔涂鸦的点***********************************************************//// <summary>/// 主相机/// </summary>public Camera camera;/// <summary>/// 白板的名字/// </summary>public string whiteBoardName;public Texture2D lineTex;public int maxPoints = 5000;public float lineWidth = 4.0f;public int minPixelMove = 5; // Must move at least this many pixels per sample for a new segment to be recordedpublic bool useEndCap = false;public Texture2D capLineTex;public Texture2D capTex;public float capLineWidth = 20.0f;// If line3D is true, the line is drawn in the scene rather than as an overlay. Note that in this demo, the line will look the same// in the game view either way, but you can see the difference in the scene view.public bool line3D = false;public float distanceFromCamera = 1.0f;/// <summary>/// line的对象:单笔涂鸦的信息/// </summary>private VectorLine line;/// <summary>/// 所有的线:很多根线,多笔涂鸦信息/// </summary>private List<VectorLine> lines = new List<VectorLine>();private Vector3 previousPosition;private int sqrMinPixelMove;private bool canDraw = false;/// <summary>/// line被创建了?,没被创建的话,按下鼠标左键则会创建一根线。/// </summary>private bool hasCreated;private float useLineWidth;private Texture2D tex;// Start is called before the first frame updatevoid Start(){if (useEndCap){VectorLine.SetEndCap("RoundCap", EndCap.Mirror, capLineTex, capTex);tex = capLineTex;useLineWidth = capLineWidth;}else{tex = lineTex;useLineWidth = lineWidth;}// Used for .sqrMagnitude, which is faster than .magnitudesqrMinPixelMove = minPixelMove * minPixelMove;}// Update is called once per framevoid Update(){Vector3 newPoint = new Vector3();bool canWrite = false; //鼠标按下在白板上涂鸦时,为true//相机激发射线穿过屏幕鼠标RaycastHit hit;Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);if (Physics.Raycast(ray, out hit, Mathf.Infinity)){//鼠标【碰到】白板if (hit.transform.name == whiteBoardName){newPoint = hit.point;canWrite = true;}}//if (canWrite){// 按下鼠标左键,则开始一根新的线。if (Input.GetMouseButtonDown(0)){if (!hasCreated) //本笔涂鸦的线存在,则不创建,不然要创建新的line{if (line3D){line = new VectorLine("DrawnLine3D", new List<Vector3>(), tex, useLineWidth, LineType.Continuous,Joins.Weld);}else{line = new VectorLine("DrawnLine", new List<Vector2>(), tex, useLineWidth, LineType.Continuous, Joins.Weld);}line.endPointsUpdate =2; // Optimization for updating only the last couple points of the line, and the rest is not re-computedif (useEndCap){line.endCap = "RoundCap";}hasCreated = true;}if (line3D){line.points3.Clear();if (!lines.Contains(line)) lines.Add(line);lines.ForEach(line => line.Draw3D());}else{line.points2.Clear();if (!lines.Contains(line)) lines.Add(line);lines.ForEach(line => line.Draw());}previousPosition = Input.mousePosition;if (line3D){line.points3.Add(newPoint);}else{line.points2.Add(newPoint);}canDraw = true;}// Mouse button held down and mouse has moved far enough to make a new point//鼠标左键一直按着,并且鼠标在移动,新点与上一个点距离达到一定程度时,该点才能被取样else if (Input.GetMouseButton(0) && (Input.mousePosition - previousPosition).sqrMagnitude > sqrMinPixelMove &&canDraw){previousPosition = Input.mousePosition;int pointCount;if (line3D){line.points3.Add(newPoint);pointCount = line.points3.Count;line.Draw3D();}else{line.points2.Add(newPoint);pointCount = line.points2.Count;line.Draw();if (pointCount >= maxPoints){canDraw = false;}}}//松开鼠标左键,本笔涂鸦的画线结束,hasCreated置空,后面再次按下的时候,可以创建新一笔的涂鸦if (Input.GetMouseButtonUp(0)){hasCreated = false;}}Vector3 GetMousePos(){var p = Input.mousePosition;if (line3D){p.z = distanceFromCamera;return Camera.main.ScreenToWorldPoint(p);}return p;}}
}
五、其它
实际上,要能够愉快的涂鸦,还得增加许多功能,比如全部清屏,部分擦除,颜色设置等等。
如果单纯只是涂鸦的话,用texture的setpixels可能更“勤俭节约”。
备注:本案例只在Win10 + Unity Editor 环境中测试过
Unity涂鸦【1】——基于Vectrosity的屏幕涂鸦和白板涂鸦的简单实现相关推荐
- 在Unity中实现基于粒子的水模拟(三:混合屏幕)
在Unity中实现基于粒子的水模拟(三:混合屏幕) 文章目录 在Unity中实现基于粒子的水模拟(三:混合屏幕) 前言 一.着色算法介绍 1.折射 2.反射 二.准备纹理 1.获取纹理 2.模糊纹理 ...
- unity 给图片边缘_Unity Shader 屏幕后效果——边缘检测
关于屏幕后效果的控制类详细见之前写的另一篇博客: 这篇主要是基于之前的控制类,实现另一种常见的屏幕后效果--边缘检测. 概念和原理部分: 首先,我们需要知道在图形学中经常处理像素的一种操作--卷积. ...
- 在Unity中实现基于粒子的水模拟(二:开始着色)
在Unity中实现基于粒子的水模拟(二:开始着色) 文章目录 在Unity中实现基于粒子的水模拟(二:开始着色) 前言 一.生成顶点 二.偏移模拟 1.接收细分着色器输出的顶点 2.根据数据调用对应的 ...
- 手机怎么使用涂鸦?分享几个手机视频怎么添加涂鸦的妙招
相信大家在给视频进行处理时,都会运用一些视频剪辑工具来给视频增添一些涂鸦等效果,比如把云朵涂鸦成独角兽或者与其相似的图案,让那些观看我们视频的人在视觉上增加了些许乐趣,不会显得视频画面太过于枯燥乏味. ...
- 在Unity中创建基于Node节点的编辑器 (二) 窗口序列化
孙广东 2018.5.13 csdn 的产品 , 真垃圾, 不想吐槽了, 文章保存就丢! 没办法 . 怎么不满意, 还是得继续用, 哎~~~ 第二部分 在Unity中序列化基于节点的 ...
- 基于 ocr 的屏幕文字识别 开源
基于 ocr 的屏幕文字识别.运行时截屏区域,进行文字识别. 下图为运行截图,识别网页内文字并输出到软件edit控件 源码下载 点击打开链接 或git https://github.com/34471 ...
- Unity接入ChatGPT基于Python.Runtime的实现
目录 前言 编译Python.Runtime.dll Unity接入ChatGPT 1.第一步 准备环境 2.第二步 python代码的书写 3.第三步 C#调用python代码 前言: 相信各位游戏 ...
- 涂鸦模组开发(压力传感器HX711)——3. 涂鸦模组数据通信
涂鸦模组开发_压力传感器HX711--3. 涂鸦模组数据通信 概述 视频演示 资料下载 涂鸦智能 涂鸦调试文件下载 STM32CUBEMX配置读取模块信息 读取代码配置 串口打印数据实例 匹配心跳检测 ...
- 基于QWidget的屏幕水印和QImage的背景水印实现
目录 1. 基于QWidget的屏幕阅读水印的添加 1.1 平铺 1.1.1 核心代码 1.1.2 构造函数中设置透明度和鼠标穿透 1.1.3 调用 1.1.4 效果展示 1.2 指定位置添加水印 ...
最新文章
- 如何从NumPy直接创建RNN?
- Python入门100题 | 第054题
- C#工厂方法模式 -抽象工厂模式
- Django从理论到实战(part50)--使用模型来处理上传的文件
- 什么是Freedoc?Freedoc是什么?
- 开源WPF控件库MaterialDesignInXAML推荐
- python制作圆形按钮_C#圆形按钮,非常漂亮动态
- mysql数据应用从入门_MYSQL数据库应用从入门到精通----读书笔记
- Unity3D 渲染统计窗口
- 模型加速:WAE-Learning a Wavelet-like Auto-Encoder to Accelerate Deep Neural Networks
- 基础知识巩固五(问题)
- 同样是百度输入法,定制远没有原版好用
- 用计算机最炫民族风乐谱,最炫民族风乐谱及歌词
- matlab颜色直方图特征提取,灰度直方图特征提取的Matlab实现
- linux使用vmware虚拟机玩LOL
- 移动开发者的必知音视频基础知识
- 人工智能知识图谱研究
- apose-cell-22.6 excel转换pdf水印去除
- 网上搜索电子书的办法
- spring同一个类中,一个方法调用另外一个注解(@Transactional)方法时,注解失效
热门文章
- discuz!代码内置颜色大全(收藏)
- 批量下载二维码并打成zip压缩包
- usb usb1-port1: disabled by hub (EMI?), re-enabling
- 计算机二级Python——题库1知识点
- 阿布扎比王储支持区块链在航空业的应用
- uboot研读笔记 | 05 - 移植uboot 2012.04到JZ2440(支持Nand Flash读写)
- 一次zabbix连接不上mysql数据库的经历
- STP生成树协议详情
- 邓亚萍大手笔一掷20亿研发即刻搜索2年就倒闭带来的思考
- 内网渗透-Linux权限维持