Unity(OpenGL)实现“阴阳师画符”、划线功能
本篇博客分享了unity用OpenGL实现‘阴阳师画符’的功能,仅供参考,未经同意,严禁转载!
《阴阳师》是一部火爆的手游,众多玩家想通过画符抽取SSR,作为一位游戏开发者,当然想的是游戏的功能是怎么实现的。本篇博客我将跟大家分享一下如何用unity实现阴阳师画符的功能,下面是一个小Demo,请看一下示例
下面跟大家分享一下如何实现这个功能:
实现方法
第一步:存储在屏幕画的线条:
Input.MousePosition的点是屏幕坐标系,存储前要转化成视图坐标系,Camera.Main.ScreenToViewportPoint()即可将鼠标在屏幕坐标系的位置转化成在视图坐标系中对应的点。在将这些点实时的存储到List中。
第二步:显示所画的线条:
显示所画的线条在这里有三种思路:
1、Image:
在相机前放置一个全屏的Image,图片是由像素组成的,通过第一步找到的点找到对象的像素点,编辑后再赋给图片。
2、LineRender:
添加LineRender组件,要注意的是:LineRender连线的点是在3D世界中的点,使用时要注意World Point坐标系的转换。
3、OpenGL:
unity中有官方提供的基于OpenGL的划线方法,此连接为OpenGL划线方法的API:
https://docs.unity3d.com/ScriptReference/GL.html
官方的API是从红色到绿色的画圆
本篇博客中采用这个方法。
第三步:把画的线条映射到物体上:
更改图片其实就是更改Texture,新建一个Texture,将所画的图形存到新建的Texture中。
若是UI则改变对象中组件的属性:
若是3D物体,则改变3D物体材质中Shader中的图片:
详解:
第一步:
划线是在屏幕上完成的,最终我们要用点来操作像素,所以要将鼠标在屏幕坐标系的位置转换成视图坐标系中对应的点:
Vector2 addPoint = Camera.main.ScreenToViewportPoint(Input.mousePosition);
通过List.Add()方法来存储获取到的点,List的泛型为Vector2
第二步:
通过unity官方提供OpenGL的GL类中的方法来实现在屏幕上显示画的图形(可以将官方示例API中全部拷贝下来,修改连线代码即可,如下):
首先将官方API中投影方式更改为正交投影
// GL.MultMatrix(transform.localToWorldMatrix); 改为下面一行为正交投影
GL.LoadOrtho();
下面开始连线
相邻两点连线,要获取当前点和后一个点,防止越界,所以长度为 List.Count - 1
GL.Vertex()为GL类中的方法,参数是要连线的点
for (int i = 0; i < mousePoints.Count - 1; i++){frontPoint = mousePoints[i];backPoint = mousePoints[i + 1];GL.Vertex3(frontPoint.x, frontPoint.y, 0);GL.Vertex3(backPoint.x, backPoint.y, 0);}
由此即可在屏幕上显示出所画的点
第三步:
在把画的线条投影到物体上之前,要新建一个Texture来保存图片:
新建Texture的参数为texture的宽、高,在这里我们就让它和屏幕的宽、高一样大小,防止映射到物体上后图片变形
Texture2D texture = new Texture2D(Screen.width, Screen.height);
然后就是用 texture.SetPixel()方法来编辑像素
List中存的点是试图坐标系的点,因为像素很小,通过点来设置像素会出现两个像素点间有断点的情况,如下:
所以用Lerp方法把两个点中间的编辑的像素都编辑起来,编辑好像素后不要忘了Texture.Apply()方法来应用图片。
for (int i = 0; i < mousePoints.Count - 1; i++){for (int j = 0; j < 100; j++){frontPoint = mousePoints[i];backPoint = mousePoints[i + 1];float scaleX = Mathf.Lerp(frontPoint.x, backPoint.x, j / 100f);float scaleY = Mathf.Lerp(frontPoint.y, backPoint.y, j / 100f);int textureX = (int)(scaleX * Screen.width);int textureY = (int)(scaleY * Screen.height);// 线条加粗for (int a = textureX - painterWide; a < textureX + painterWide; a++){for (int b = textureY - painterWide; b < textureY + painterWide; b++){texture.SetPixel(a, b, painterColor);}}}}texture.Apply();
接下来就是将保存好的图片赋给物体,在本文开头,右上角是一个Quad,左下角是一个Cube,两者用的是同一个材质球,在代码中获取其材质球后,修改texture。注意:SetTexture方法中第一个参数,是shader中设置的名字,不要写错。
Material targetMaterial = gameObject.GetComponent<Renderer>().material;
targetMaterial.SetTexture("_MainTex", texture);
以上就是通过Unity用OpenGL来实现‘阴阳师画符’的示例,可以通过添加属性,来修改划线的粗细、颜色等,可自行扩展更多。
[Range(1, 10)]public int painterWide = 1;public Color painterColor = Color.black;
下面是此次分享的Demo的完整代码,仅供参考,欢迎广大读者前来交流。
完整代码
using System.Collections.Generic;
using UnityEngine;
public class Draw : MonoBehaviour
{[Range(1, 10)]public int painterWide = 1;public Color painterColor = Color.black;private List<Vector2> mousePoints;private Texture2D texture;private Material targetMaterial;private Vector2 frontPoint;private Vector2 backPoint;static Material lineMaterial;void Start(){mousePoints = new List<Vector2>();targetMaterial = gameObject.GetComponent<Renderer>().material;}static void CreateLineMaterial(){if (!lineMaterial){// Unity has a built-in shader that is useful for drawing// simple colored things.Shader shader = Shader.Find("Hidden/Internal-Colored");lineMaterial = new Material(shader);lineMaterial.hideFlags = HideFlags.HideAndDontSave;// Turn on alpha blendinglineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);// Turn backface culling offlineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);// Turn off depth writeslineMaterial.SetInt("_ZWrite", 0);}}public void OnRenderObject(){CreateLineMaterial();// Apply the line materiallineMaterial.SetPass(0);GL.PushMatrix();// 更改为正交投影GL.LoadOrtho();GL.Begin(GL.LINES);GL.Color(painterColor);// 连线for (int i = 0; i < mousePoints.Count - 1; i++){frontPoint = mousePoints[i];backPoint = mousePoints[i + 1];GL.Vertex3(frontPoint.x, frontPoint.y, 0);GL.Vertex3(backPoint.x, backPoint.y, 0);}GL.End();GL.PopMatrix();}void CreatTexture(){texture = new Texture2D(Screen.width, Screen.height);// 设置每个点的像素for (int i = 0; i < mousePoints.Count - 1; i++){for (int j = 0; j < 100; j++){frontPoint = mousePoints[i];backPoint = mousePoints[i + 1];float scaleX = Mathf.Lerp(frontPoint.x, backPoint.x, j / 100f);float scaleY = Mathf.Lerp(frontPoint.y, backPoint.y, j / 100f);int textureX = (int)(scaleX * Screen.width);int textureY = (int)(scaleY * Screen.height);// 线条加粗for (int a = textureX - painterWide; a < textureX + painterWide; a++){for (int b = textureY - painterWide; b < textureY + painterWide; b++){texture.SetPixel(a, b, painterColor);}}}}texture.Apply();targetMaterial.SetTexture("_MainTex", texture);}void Update(){// 按下鼠标记录鼠标位置if (Input.GetMouseButton(0)){Vector2 addPoint = Camera.main.ScreenToViewportPoint(Input.mousePosition);mousePoints.Add(addPoint);}// 抬起鼠标清空屏幕,并投影到对象上if (Input.GetMouseButtonUp(0)){CreatTexture();mousePoints.Clear();}}
}
其他
更多Blog请见:https://yiyuan1130.github.io/
Github地址:https://github.com/yiyuan1130
Unity(OpenGL)实现“阴阳师画符”、划线功能相关推荐
- 【游戏开发实战】TapTap物理画线游戏,教你使用Unity实现2D物理画线功能,看到我为你画的彩虹了吗
文章目录 一.前言 二.思考 三.验证我们的思考 1.创建物体挂组件 2.设置组件参数 3.运行测试 4.结论 四.撸起袖子写代码 1.Line.cs 2.LinesDrawer.cs 五.场景 六. ...
- Android opengles 实现触碰屏幕,根据运动轨迹画直线的功能
Android opengles 实现触碰屏幕,根据运动轨迹画直线的功能 目录 引言 第一步,先自己学会绘制一条固定坐标的直线 第二步,动态的绘制一条直线 第三步,坐标转换 第四步,绘制多条直线 代码 ...
- Unity使用LineRenderer组件画出菱形,长度,角度可任意调节
首先说下我的思路: 开始想的比较简单,就是先建两个空物体分别挂上脚本,一个在X轴画直线,一个与X轴成angle夹角,通过计算得出坐标,这样就能画出一个菱形的角度,下面是实例图: 最后再写个脚本通过循环 ...
- 利用Unity自带的合图切割功能将合图切割成子图
转载的,牛人无处不在,我还太渺小 虽然目前网上具有切割合图功能的工具不少,但大部分都是自动切割或者根据plist之类的合图文件切割的, 这种切割往往不可自己微调或者很难维调,导致效果不理想. 今天逛贴 ...
- [Python]阴阳师-抗检测多功能护肝辅助脚本
FK-Onmyoji 阴阳师抗检测多功能护肝辅助脚本 Github地址 https://github.com/BluePlumStudio/FK-Onmyoji 游戏多开,多种模式并发 鼠标键盘模拟输 ...
- Java编写的画图板,功能非常齐全,完整代码 附详细设计报告
今天为大家分享一个java语言编写的图书管理程序-003,目前系统功能已经很全面,后续会进一步完善.整个系统界面漂亮,有完整得源码,希望大家可以喜欢.喜欢的帮忙点赞和关注.一起编程.一起进步 开发环境 ...
- Unity 使用NavMesh实现简易的摇杆功能
Unity 使用NavMesh实现简易的摇杆功能 引言 在日常的unity项目开发中,经常会遇到角色移动的问题,在这里我们作一个建议的摇杆功能来控制角色的移动.要求如下: 摇杆在没有UI遮挡的任何位置 ...
- 在unity中内置一个查询物流信息功能
项目需求,在unity中内置查询物流信息的功能 需要用到查询物流 的API 在这选择的是快递100的API 首先需要申请快递100的API,官方会给你一个KEY,使用该KEY,就可以进行物流查询了 u ...
- Unity 相机围绕目标旋转、缩放功能实现
Unity 相机围绕目标旋转.缩放功能实现 //************************************************相机围绕物体旋转.相机缩放*************** ...
- ImageView实现画画板的功能
1,使用虚拟机加载的图片是只读的,不能对其进行其他的操作.这在上一篇文章中已介绍,要想对其进行其他操作,还是同一个方法,就是创建其副本,对副本进行操作. 2,下面通过此知识点,再介绍一个通过Image ...
最新文章
- beego 显示html文件,[Beego] 内置的模板函数(不同格式的字符串和html的互转)
- 1.4 Matplotlib:绘图
- Windows 8最值得期待的8大特性
- python操作redis用法详解
- qsort()函数详解
- java序列化深克隆_如何在内存序列化中使用Java深克隆对象
- [NOIP2016]愤怒的小鸟 状态压缩dp
- 信息学奥赛一本通(1037:计算2的幂)
- PRNet:人脸3D重建与密集对齐
- 如何写一份好的求职简历
- python 多线程 异步_python 多线程异步
- 编辑请求内容 Charles
- 淘宝客公众号京东淘宝拼多多三合一源码三级代理系统网站源码
- js获取当前url参数-通俗易懂
- 数学建模:评价性模型学习——层次分析法(AHP模型)
- python编写密码登录程序_python初学之用户登录的实现过程(实例讲解)
- python函数def无效_python自定义函数def的应用详解
- html div里里h标签居中,html之块级标签h系列,div
- 清华梦的粉碎—写给清华大学的退学申请 2005.9.22
- 安装程序配置服务器失败。参考服务器错误日志和C:/WINDOWS/sqlstp.log
热门文章
- 【LensFlare镜头光晕】Unity3D奇葩实现
- 用文字总结出计算机组装步骤,项目教学法在《计算机组装与维护》中的运用与反思(杜燕)...
- 晚还款没事,各行信用卡容时容差服务大汇总!
- 【Python笔记】pyspark.sql库
- 知识赛道悖论之年:“娱乐至死”的抗争
- 【解局】瑞幸向上,盒马向下
- 计算机桌面出现临时文件,如何删除电脑中的临时文件 电脑屏幕一键放大方法分享...
- 西门子smart200模拟量与左移右移指令
- C#,《数值算法:科学计算的艺术,Numerical Recipes: The Art of Scientific Computing》
- Ubuntu 18.04配置ORB-SLAM2+ROS实时运行ORB-SLAM2+SLAM相关库的安装 相关问题汇总(USB_CAM , ROS 编译问题)