Unity实现3D书写功能

  • 利用LineRender实现书写功能
    • 画板的预制排版
    • 画板功能代码
  • 画笔的功能实现
  • Demo

利用LineRender实现书写功能

利用LineRender的点位功能实现画线功能

画板的预制排版

画板的脚本放置与Board上并添加BoxCollider
UICanvasTemp为临时画板层
UICanvasSave为最终画板层
UICanvasTempUICanvasSave中的Comtent采用RawImage
UICameraUICanvasTemp中的Comtent使用RenderTexture进行关联,使UICanvasTemp中的Comtent的图片始终为UICamera的图片
UICanvasSave中的Comtent的图片为LineRender的保存图片

画板的缺陷

  • 需要保证UICanvasTempUICanvasSave的大小全部占满UICamera的区间,否则会出现BUG
  • UICanvasTempLayer层需要为Default
  • UICanvasSaveLayer层需要为DrawUI
  • UICamera为画板的专用相机,只看画板层DrawUI
  • 场景中的主相机不可场景DrawUI
  • 画布CanvasRenderMode的类型必须为WorldSpace否则主相机无法查看

画板的优化

  • UICanvasSave的作用为避免LineRender中的点位过多导致程序卡死,所有每一笔画完都需要对LineRender的内容进行保存.或当LineRender的点位达到一定的数量进行临时保存.或当相邻点位的距离较小时忽略点位的写入
  • 画布CanvasRenderMode的类型可以用ScreenSpace-Camera来确保画布的大小占满UICamera的区间

画板功能代码


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.UI;public class DrawBoard : MonoBehaviour
{public Transform mRoot;public Camera mUICamera;public Canvas mUICanvasSave;public Canvas mUICanvasTemp;public RawImage mSaveDrawCanvas;public RawImage mTempDrawCanvas;Dictionary<uint, LineRenderer> mAllLine = new Dictionary<uint, LineRenderer>();List<LineRenderer> mLastLine = new List<LineRenderer>();/// <summary>/// 开始绘画参数准备/// </summary>/// <param name="varPenID">笔的ID,方便与多笔同时进行作画</param>/// <param name="size">笔的粗细</param>/// <param name="color">笔的颜色</param>public void StartDraw(uint varPenID, float size, Color color, Vector3 pos){if (mAllLine.ContainsKey(varPenID)){return;}LineRenderer Line;if (mLastLine.Count != 0){Line = mLastLine[0];mLastLine.RemoveAt(0);}else{Line = NewGameobject<LineRenderer>("Line", mRoot);Line.gameObject.layer = LayerMask.NameToLayer("DrawUI");Line.material = new Material(Shader.Find("Unlit/Color"));Line.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;}Line.material.SetColor("_Color", color);Line.widthMultiplier = size;Line.positionCount = 2;Line.SetPosition(0, pos);Line.SetPosition(1, pos);Line.gameObject.SetActive(true);mAllLine.Add(varPenID, Line);}/// <summary>/// 进行绘画/// </summary>/// <param name="varPen">笔的ID,方便与多笔同时进行作画</param>/// <param name="pos">绘画的点位</param>public void Drawing(uint varPenID, Vector3 pos){if (!mAllLine.ContainsKey(varPenID)){return;}LineRenderer Line = mAllLine[varPenID];Line.positionCount += 1;Line.SetPosition(Line.positionCount - 1, pos);}/// <summary>/// 结束绘画/// </summary>/// <param name="varPen">笔的ID,方便与多笔同时进行作画</param>public void EndDraw(uint varPenID){if (!mAllLine.ContainsKey(varPenID)){return;}LineRenderer varLine = mAllLine[varPenID];mAllLine.Remove(varPenID);//进行图画保存SaveDraw();varLine.gameObject.SetActive(false);mLastLine.Add(varLine);}/// <summary>/// 对相机渲染的图片进行存储进指定的图片中/// </summary>private void SaveDraw(){if (mSaveDrawCanvas == null || mTempDrawCanvas == null)return;foreach (var item in mAllLine){item.Value.gameObject.SetActive(false);}Texture2D screenShot = CaptureScreen(mUICamera);mSaveDrawCanvas.texture = screenShot;mSaveDrawCanvas.color = Color.white;foreach (var item in mAllLine){item.Value.gameObject.SetActive(true);}}/// <summary>/// 将相机看到的画面转换成Texture2D/// </summary>/// <param name="came"></param>/// <param name="r"></param>/// <returns></returns>public Texture2D CaptureScreen(Camera camera){camera.Render();RenderTexture.active = camera.targetTexture;Rect r = new Rect(Vector2.zero, new Vector2(camera.activeTexture.width, camera.targetTexture.height));
#if UNITY_2017Texture2D screenShot = new Texture2D((int)r.width, (int)r.height, TextureFormat.RGBA32, false);
#elif UNITY_2019Texture2D screenShot = new Texture2D((int)r.width, (int)r.height, GraphicsFormat.R32G32B32A32_SFloat, TextureCreationFlags.None);
#endifscreenShot.ReadPixels(r, 0, 0);screenShot.Apply();RenderTexture.active = null;return screenShot;}private T NewGameobject<T>(string varContent,Transform varParent) where T:Component{GameObject TempGame = new GameObject(varContent);TempGame.transform.SetParent(varParent);TempGame.transform.localPosition = Vector3.zero;TempGame.transform.localEulerAngles = Vector3.zero;TempGame.transform.localScale = Vector3.one;T TempT = TempGame.AddComponent<T>();return TempT;}
}

画笔的功能实现


using UnityEngine;public class DrawPen : MonoBehaviour
{/// <summary>/// 笔的ID/// </summary>public uint mID;/// <summary>/// 笔的输入大小/// </summary>public float mSize = 0.01f;/// <summary>/// 笔的输入颜色/// </summary>public Color mPenColor = Color.white;/// <summary>/// 笔的输入类型/// </summary>public PenType mPenType = PenType.Collider;private void Awake(){ColliderDrawInit();}#region ColliderDraw//使用碰撞实现画笔的输入功能private void ColliderDrawInit(){if (mPenType != PenType.Collider)return;BoxCollider box = this.GetComponent<BoxCollider>();if (box == null){box = this.gameObject.AddComponent<BoxCollider>();}box.isTrigger = true;Rigidbody Rig = this.GetComponent<Rigidbody>();if (Rig == null){Rig = this.gameObject.AddComponent<Rigidbody>();}Rig.isKinematic = true;Rig.useGravity = false;}private void OnTriggerEnter(Collider other){if (mPenType != PenType.Collider)return;DrawBoard board = other.GetComponent<DrawBoard>();if (board == null)return;Vector3 pos = other.ClosestPoint(this.transform.position);board.StartDraw(mID, mSize, mPenColor, pos);}private void OnTriggerStay(Collider other){if (mPenType != PenType.Collider)return;DrawBoard board = other.GetComponent<DrawBoard>();if (board == null)return;Vector3 pos = other.ClosestPoint(this.transform.position);board.Drawing(mID, pos);}private void OnTriggerExit(Collider other){if (mPenType != PenType.Collider)return;DrawBoard board = other.GetComponent<DrawBoard>();if (board == null)return;board.EndDraw(mID);}#endregion#region RayDraw//使用射线实现画笔的输入功能#endregionpublic enum PenType{Collider,Ray,}
}

Demo

百度云盘路径
提取码: x431

Unity实现3D书写功能相关推荐

  1. 虚拟现实技术应用到物流领域?Unity实现3D立体仓储可视化

    虚拟现实技术应用到物流领域?Unity实现3D立体仓储可视化 介绍 视频介绍 项目介绍 登陆验证 提升机模拟 穿梭车模拟 项目结果及应用 项目资料: 介绍 随着物流领域的发展,立体仓储技术越来越成熟. ...

  2. 软件工程第二次作业:基于Unity的3D魔方实现

    基于Unity的3D魔方实现 王化明(2012211757).吴静(2012211523)  一.背景: 魔方,英文名为Rubik's Cube,又叫魔术方块,也称鲁比克方块.是匈牙利布达佩斯建筑学院 ...

  3. Adobe Unity大战3D网游市场

    供稿/ IIEEG 假如分析师的判断无误,整个游戏行业未来五年的市场规模将达870亿美元,在线和移动游戏的份额将占据半壁江山,那么问题就来了:拿什么去抢占这块市场蛋糕? 支持开发3D浏览器游戏的先进技 ...

  4. 《Unity 4 3D开发实战详解》一6.7 物理引擎综合案例

    本节书摘来异步社区<Unity 4 3D开发实战详解>一书中的第6章,第6.7节,作者: 吴亚峰 , 杜化美 , 张月霞 , 索依娜 责编: 张涛,更多章节内容可以访问云栖社区" ...

  5. Unity网络多玩家游戏开发教程第1章Unity自带网络功能

    Unity网络多玩家游戏开发教程第1章Unity自带网络功能 Unity拥有大量的第三方插件,专门提供了对网络功能的支持.但是,大部分开发者第一次接触到的还是Unity自带的网络功能,也就是大家经常说 ...

  6. android 脸部识别之3D,2018年高通将推出整合3D脸部识别功能的Android手机芯片

    根据国外科技网站CNET的报导,手机芯片大厂高通(Qualcomm)目前打算在针对Android手机设计的处理器产品中,加入支持红外线3D传感技术.也就是说,未来Android手机从处理器方面就会支持 ...

  7. 美团推出外卖版拼多多;iOS 14 Beta 3暂禁用3D Touch功能;Rust 1.45 发布| 极客头条

    整理 | 屠敏 头图 | CSDN 下载自东方 IC 扫描二维码,即刻收听 极客头条音频版 智能播报由出门问问「魔音工坊」提供技术支持 「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上 ...

  8. 海康摄像机3D PTZ功能,拍照功能

    技术交流qq群933925017 海康摄像机3D PTZ功能 1.海康界面自带的框选自动居中缩小/放大功能 2.核心代码 /** 该结构体中的坐标值与当前预览显示框的大小有关,现假设预览显示框为352 ...

  9. iOS开发之3D Touch(快速添加3D Touch功能)

    1. 概述 在支持3D Touch的设备上,用户可以通过对触摸屏施加不同程度的压力来访问其他功能,应用程序可以通过显示上下文菜单(或支持Peek和Pop)来响应,以显示一些可供用户操作的选项或者行为. ...

最新文章

  1. C++迭代器iterator
  2. DHCP Server 故障转移实现 (结合H3C交换机)
  3. 二十个你必须知道的SEO概念
  4. 获取上传文件的后缀名
  5. 2019ICPC(银川) - Function!(数论+数学分块)
  6. 前端技术以及工程化工具
  7. 160 - 8 Andrnalin.1
  8. 自定义SSL证书实现单双向ssl认证记录
  9. Hadoop 安装部署
  10. 数据结构实验二---单链表的实现
  11. 企业直播带货如何做?第一步就是选直播平台
  12. 谱尼软件测试谱尼为网络安全护航
  13. 127.0.0.1 192.168 localhost 之间的区别
  14. python用cartopy包画地图_python – 使用Cartopy在地图上显示图像时的投影问题
  15. 【小学】再做一年级算术题
  16. 采用最大连通域算法对三维医学图像分割结果做后处理
  17. 解决方案模板(标题立问题简述)
  18. 高品质MP3制作攻略
  19. Excel公式中的countif 和 conutifs 和sumproduct
  20. python+vue高校图书借阅管理系统

热门文章

  1. webapi鉴权使用token令牌
  2. SpringBoot基础篇Bean之基本定义与使用
  3. [Java] Java九格切图 (同样支持四格, 六格, n*n格)
  4. 我现在30岁、单身、北漂、失业ing......
  5. Matlab图像频域处理
  6. Google Earth Engine(GEE)——1870年至2100年的全球城市范围数据集
  7. B.数据挖掘[一]---汽车车交易价格预测(测评指标;EDA)
  8. java中如何获取字节数组_如何从java中读取字节数组中的数据
  9. Autonomous Exploration Development Environment and the Planning Algorithms
  10. 2021牛客暑期多校训练营2「I BFS」 + 「F 计算几何」