本篇博客分享了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)实现“阴阳师画符”、划线功能相关推荐

  1. 【游戏开发实战】TapTap物理画线游戏,教你使用Unity实现2D物理画线功能,看到我为你画的彩虹了吗

    文章目录 一.前言 二.思考 三.验证我们的思考 1.创建物体挂组件 2.设置组件参数 3.运行测试 4.结论 四.撸起袖子写代码 1.Line.cs 2.LinesDrawer.cs 五.场景 六. ...

  2. Android opengles 实现触碰屏幕,根据运动轨迹画直线的功能

    Android opengles 实现触碰屏幕,根据运动轨迹画直线的功能 目录 引言 第一步,先自己学会绘制一条固定坐标的直线 第二步,动态的绘制一条直线 第三步,坐标转换 第四步,绘制多条直线 代码 ...

  3. Unity使用LineRenderer组件画出菱形,长度,角度可任意调节

    首先说下我的思路: 开始想的比较简单,就是先建两个空物体分别挂上脚本,一个在X轴画直线,一个与X轴成angle夹角,通过计算得出坐标,这样就能画出一个菱形的角度,下面是实例图: 最后再写个脚本通过循环 ...

  4. 利用Unity自带的合图切割功能将合图切割成子图

    转载的,牛人无处不在,我还太渺小 虽然目前网上具有切割合图功能的工具不少,但大部分都是自动切割或者根据plist之类的合图文件切割的, 这种切割往往不可自己微调或者很难维调,导致效果不理想. 今天逛贴 ...

  5. [Python]阴阳师-抗检测多功能护肝辅助脚本

    FK-Onmyoji 阴阳师抗检测多功能护肝辅助脚本 Github地址 https://github.com/BluePlumStudio/FK-Onmyoji 游戏多开,多种模式并发 鼠标键盘模拟输 ...

  6. Java编写的画图板,功能非常齐全,完整代码 附详细设计报告

    今天为大家分享一个java语言编写的图书管理程序-003,目前系统功能已经很全面,后续会进一步完善.整个系统界面漂亮,有完整得源码,希望大家可以喜欢.喜欢的帮忙点赞和关注.一起编程.一起进步 开发环境 ...

  7. Unity 使用NavMesh实现简易的摇杆功能

    Unity 使用NavMesh实现简易的摇杆功能 引言 在日常的unity项目开发中,经常会遇到角色移动的问题,在这里我们作一个建议的摇杆功能来控制角色的移动.要求如下: 摇杆在没有UI遮挡的任何位置 ...

  8. 在unity中内置一个查询物流信息功能

    项目需求,在unity中内置查询物流信息的功能 需要用到查询物流 的API 在这选择的是快递100的API 首先需要申请快递100的API,官方会给你一个KEY,使用该KEY,就可以进行物流查询了 u ...

  9. Unity 相机围绕目标旋转、缩放功能实现

    Unity 相机围绕目标旋转.缩放功能实现 //************************************************相机围绕物体旋转.相机缩放*************** ...

  10. ImageView实现画画板的功能

    1,使用虚拟机加载的图片是只读的,不能对其进行其他的操作.这在上一篇文章中已介绍,要想对其进行其他操作,还是同一个方法,就是创建其副本,对副本进行操作. 2,下面通过此知识点,再介绍一个通过Image ...

最新文章

  1. beego 显示html文件,[Beego] 内置的模板函数(不同格式的字符串和html的互转)
  2. 1.4 Matplotlib:绘图
  3. Windows 8最值得期待的8大特性
  4. python操作redis用法详解
  5. qsort()函数详解
  6. java序列化深克隆_如何在内存序列化中使用Java深克隆对象
  7. [NOIP2016]愤怒的小鸟 状态压缩dp
  8. 信息学奥赛一本通(1037:计算2的幂)
  9. PRNet:人脸3D重建与密集对齐
  10. 如何写一份好的求职简历
  11. python 多线程 异步_python 多线程异步
  12. 编辑请求内容 Charles
  13. 淘宝客公众号京东淘宝拼多多三合一源码三级代理系统网站源码
  14. js获取当前url参数-通俗易懂
  15. 数学建模:评价性模型学习——层次分析法(AHP模型)
  16. python编写密码登录程序_python初学之用户登录的实现过程(实例讲解)
  17. python函数def无效_python自定义函数def的应用详解
  18. html div里里h标签居中,html之块级标签h系列,div
  19. 清华梦的粉碎—写给清华大学的退学申请 2005.9.22
  20. 安装程序配置服务器失败。参考服务器错误日志和C:/WINDOWS/sqlstp.log

热门文章

  1. 【LensFlare镜头光晕】Unity3D奇葩实现
  2. 用文字总结出计算机组装步骤,项目教学法在《计算机组装与维护》中的运用与反思(杜燕)...
  3. 晚还款没事,各行信用卡容时容差服务大汇总!
  4. 【Python笔记】pyspark.sql库
  5. 知识赛道悖论之年:“娱乐至死”的抗争
  6. 【解局】瑞幸向上,盒马向下
  7. 计算机桌面出现临时文件,如何删除电脑中的临时文件 电脑屏幕一键放大方法分享...
  8. 西门子smart200模拟量与左移右移指令
  9. C#,《数值算法:科学计算的艺术,Numerical Recipes: The Art of Scientific Computing》
  10. Ubuntu 18.04配置ORB-SLAM2+ROS实时运行ORB-SLAM2+SLAM相关库的安装 相关问题汇总(USB_CAM , ROS 编译问题)