〇、涂鸦与画线

  • 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的屏幕涂鸦和白板涂鸦的简单实现相关推荐

  1. 在Unity中实现基于粒子的水模拟(三:混合屏幕)

    在Unity中实现基于粒子的水模拟(三:混合屏幕) 文章目录 在Unity中实现基于粒子的水模拟(三:混合屏幕) 前言 一.着色算法介绍 1.折射 2.反射 二.准备纹理 1.获取纹理 2.模糊纹理 ...

  2. unity 给图片边缘_Unity Shader 屏幕后效果——边缘检测

    关于屏幕后效果的控制类详细见之前写的另一篇博客: 这篇主要是基于之前的控制类,实现另一种常见的屏幕后效果--边缘检测. 概念和原理部分: 首先,我们需要知道在图形学中经常处理像素的一种操作--卷积. ...

  3. 在Unity中实现基于粒子的水模拟(二:开始着色)

    在Unity中实现基于粒子的水模拟(二:开始着色) 文章目录 在Unity中实现基于粒子的水模拟(二:开始着色) 前言 一.生成顶点 二.偏移模拟 1.接收细分着色器输出的顶点 2.根据数据调用对应的 ...

  4. 手机怎么使用涂鸦?分享几个手机视频怎么添加涂鸦的妙招

    相信大家在给视频进行处理时,都会运用一些视频剪辑工具来给视频增添一些涂鸦等效果,比如把云朵涂鸦成独角兽或者与其相似的图案,让那些观看我们视频的人在视觉上增加了些许乐趣,不会显得视频画面太过于枯燥乏味. ...

  5. 在Unity中创建基于Node节点的编辑器 (二) 窗口序列化

    孙广东  2018.5.13 csdn 的产品 , 真垃圾, 不想吐槽了, 文章保存就丢!     没办法  .    怎么不满意, 还是得继续用, 哎~~~ 第二部分 在Unity中序列化基于节点的 ...

  6. 基于 ocr 的屏幕文字识别 开源

    基于 ocr 的屏幕文字识别.运行时截屏区域,进行文字识别. 下图为运行截图,识别网页内文字并输出到软件edit控件 源码下载 点击打开链接 或git https://github.com/34471 ...

  7. Unity接入ChatGPT基于Python.Runtime的实现

    目录 前言 编译Python.Runtime.dll Unity接入ChatGPT 1.第一步 准备环境 2.第二步 python代码的书写 3.第三步 C#调用python代码 前言: 相信各位游戏 ...

  8. 涂鸦模组开发(压力传感器HX711)——3. 涂鸦模组数据通信

    涂鸦模组开发_压力传感器HX711--3. 涂鸦模组数据通信 概述 视频演示 资料下载 涂鸦智能 涂鸦调试文件下载 STM32CUBEMX配置读取模块信息 读取代码配置 串口打印数据实例 匹配心跳检测 ...

  9. 基于QWidget的屏幕水印和QImage的背景水印实现

    目录 1. 基于QWidget的屏幕阅读水印的添加 1.1 平铺 1.1.1 核心代码 1.1.2  构造函数中设置透明度和鼠标穿透 1.1.3 调用 1.1.4 效果展示 1.2 指定位置添加水印 ...

最新文章

  1. 如何从NumPy直接创建RNN?
  2. Python入门100题 | 第054题
  3. C#工厂方法模式 -抽象工厂模式
  4. Django从理论到实战(part50)--使用模型来处理上传的文件
  5. 什么是Freedoc?Freedoc是什么?
  6. 开源WPF控件库MaterialDesignInXAML推荐
  7. python制作圆形按钮_C#圆形按钮,非常漂亮动态
  8. mysql数据应用从入门_MYSQL数据库应用从入门到精通----读书笔记
  9. Unity3D 渲染统计窗口
  10. 模型加速:WAE-Learning a Wavelet-like Auto-Encoder to Accelerate Deep Neural Networks
  11. 基础知识巩固五(问题)
  12. 同样是百度输入法,定制远没有原版好用
  13. 用计算机最炫民族风乐谱,最炫民族风乐谱及歌词
  14. matlab颜色直方图特征提取,灰度直方图特征提取的Matlab实现
  15. linux使用vmware虚拟机玩LOL
  16. 移动开发者的必知音视频基础知识
  17. 人工智能知识图谱研究
  18. apose-cell-22.6 excel转换pdf水印去除
  19. 网上搜索电子书的办法
  20. spring同一个类中,一个方法调用另外一个注解(@Transactional)方法时,注解失效

热门文章

  1. discuz!代码内置颜色大全(收藏)
  2. 批量下载二维码并打成zip压缩包
  3. usb usb1-port1: disabled by hub (EMI?), re-enabling
  4. 计算机二级Python——题库1知识点
  5. 阿布扎比王储支持区块链在航空业的应用
  6. uboot研读笔记 | 05 - 移植uboot 2012.04到JZ2440(支持Nand Flash读写)
  7. 一次zabbix连接不上mysql数据库的经历
  8. STP生成树协议详情
  9. 邓亚萍大手笔一掷20亿研发即刻搜索2年就倒闭带来的思考
  10. 内网渗透-Linux权限维持