unity 一个拼图demo(七巧板)和一个切割demo_untiy开发七巧板-程序员宅基地

技术标签: 网格  shader的编写  格子类型的游戏  

   好久没更新博客了,那么今天就来装一下b吧。还是先上一波图,看看我们到底要做什么。


前面2张是切割的的demo,后面的这个是拼图,但是我们看到材质,这里的解释一下2个demo用的都是一个网格构建代码,所以才会出现这种情况,正确的做法应该是把添加uv的代码做个判断一下,把这个变量放到这个方法参数列表中,同时把它变成一个对外的方法。这里顺便给大家提一下封装的思想,厉害的程序员他们其实大部分的时间都在思考,思考如何把一个系统变得扩展性越高,这样软件的腐蚀就会越慢了。同样如果一个游戏能做成这样同样也便于我们维护和理解。这2个demo都用到了这个类,那么就将其定义为MeshBuilder。这个类他应该提供一个基本的方法就是我们给你一组点的数据,你给我们返回一个网格或者一个物体。但是如果我们需要给网格贴uv的话,我们的传进去一个网格的材质,网格的原始宽度和高度(便于我们计算点的uv信息),同样我们可以把材质,网格的原始宽度和高度放到构造函数或者用一个初始化方法,这样都是可以(我个人建议用后者,其实都一样),至于你这个meshbuilder类中怎么写,我其实都不怎么关心的,我只需要我想要的就是返回一个网格或者游戏物体。如果我们将这个方法约束成为一个行为的话,就是这个类它可以给我们提供生产网格而其他的类都没有这个功能。这个时候就是接口了。接口的表现更倾向于CanDo,能干什么行为而继承倾向于IS A,是什么东西这样的行为。言归正传吧。其实我是先做的后面那个demo,做的差不多的时候再去做切割的,所以在做切割的时候把前面的代码删掉了。先从第一个将吧,我们知道要做上面一个正方形的网格其实是很简单的。同时我们还需要在正方形的网格周围做一圈描边,这里还是画图从一般的情况进行分析这个border该怎么来添加吧。

我们就2中情况分析,一种是基本的凸多边形一种凹多边形。我们就凸多边形分析一波。如果我们想要做成上图的那种效果,首先我们通过b1点求得对应的b点,依次次类推求得剩下的2个点。根据基本的需求得出相应的规律,就是b1c1到bc之间的距离和a1c1到ac之间的距离及a1b1到ab之间的距离是相等的。所以b1到ab的距离等于b1到bc的距离,所以b这个点在a1b1和b1c1的平分线上,依次类推到c点和a点。我们可以轻松的求得b1a1向量和b1c1向量之间的和向量,然后通过一个反向量求得b的位置,当然没玩还得通过2条直线的距离求得这个斜线的距离就是bb1的距离,最后即可求得b点依次类推就可以求出所有的点,当然这只是仅限于我们的凸多边形,我们应该还需要讨论我们的凹多边形的情况。大家可以随便画个图就可以知道如果我们仍用凸的情况来讨论肯定是不对的。反正我们知道最后求得的那个点肯定在脚平分线上,只不过我们只是不知道是在角平分线的哪头罢了。如果我们把为负的所有情况都讨论出来了,然后我们取一下反不就为正的情况了么。那么我们用设定一个乘数,当在某种情况下该乘数为-1,我们最开始的时候为1,这样就可以轻松的解决这个问题了。那么问题来 怎么样的情况下我们需要将乘数是设为-1呢?当然这个结论同样也需要大家去思考。外人只能引导,自己理解了,将问题抽象为规律,那么你就可以轻松的解决这个问题了(这个问题我就不讲了,大家自己可以去总结一下他们之间的规律)。首先我们还是从最开始的网格生成类开始做起吧

public class MeshBuilder
{ 
}
定义一个功能类似于构造函数的方法。

    private Material _meshMaterial;
    private Material _borderMaterial;
    private Transform _parentTransform;
    public void Intilized(Material mat,Material bmat,Transform parent)
    {
        _meshMaterial = mat;
        _borderMaterial = bmat;

        _parentTransform = parent;
    }
初始化网格所需要的材质资源和基本的位置信息。添加一个对外的方法。

    public GameObject CreateMeshObj(List<Vector3> verticleList,float width,float height)
    {
        GameObject ob=new GameObject("sb");
        Mesh mesh=new Mesh();

        List<Vector3> templist = GetTriangulateByPoint.GetInsiderBorderList(verticleList,0.1f);


        if (GetTriangulateByPoint.Area(templist) > 0)
        {
            templist.Reverse();
            verticleList.Reverse();
        }

        mesh.vertices = templist.ToArray();
        mesh.triangles = GetTriangulateByPoint.GetTriByPoins(templist);

        var col = ob.AddComponent<MeshCollider>();
        col.sharedMesh = mesh;
        ob.AddComponent<MeshFilter>().mesh = mesh;

        var child = CreateBorderObj(templist, verticleList);
        child.transform.parent = ob.transform;
        return ob;
    }
这里就是根据点的信息来创建网格,这些点的信息我们通过我们去读json文件中存储点的基本信息,这些json我是通过写一个编辑器来编辑不同的图案。接着添加一个私有方法

CreateBorderObj。

 private GameObject CreateBorderObj(List<Vector3> inside,List<Vector3> outside)
 {
        int count = inside.Count;
        GameObject border=new GameObject("Border");
        Mesh mesh=new Mesh();

        List<Vector3> veritcles = new List<Vector3>(count*2);
        List<int> indicats=new List<int>();

        veritcles.AddRange(outside);
        veritcles.AddRange(inside);
        for (int i = 0; i < count; i++)
        {
            indicats.Add(i); indicats.Add((i + 1) % count); indicats.Add((i + 1) % count+count);
            indicats.Add(i); indicats.Add((i + 1) % count + count); indicats.Add(i + count);
        }
        mesh.vertices = veritcles.ToArray();
        mesh.triangles = indicats.ToArray();

        border.AddComponent<MeshFilter>().mesh = mesh;
        border.AddComponent<MeshRenderer>().material = _borderMaterial;
        return border;
 }
因为我们操作中还需要一个画线操作,这里我们仍需要通过网格来动态控制大下和方向了,如果我们鼠标滑动的当前点和上一帧的点的距离判断及当前点和鼠标按下点与上一帧的点和鼠标按下的点的夹角大于一定角度的时候我们将其定义一次有效的移动。所以我们还需要通过2个点来创建的一个长方边形的网格。

    public GameObject CreateLineMeshObj(Vector3 start, Vector3 end, Material mat)
    {
        GameObject ob = new GameObject("sd");
        Mesh mesh = new Mesh();

        List<Vector3> verticles = new List<Vector3>();
        List<int> indicats = new List<int>();
        List<Vector2> uv = new List<Vector2>();

        Vector3 dir = (end - start).normalized;
        Vector3 normal = Quaternion.Euler(0, 0, 90) * dir;

        var start1 = start + normal.normalized * 0.1f;
        var end1 = end + normal.normalized * 0.1f;
        verticles.Add(start); verticles.Add(start1); verticles.Add(end); verticles.Add(end1);

        indicats.Add(0); indicats.Add(1); indicats.Add(3);
        indicats.Add(0); indicats.Add(3); indicats.Add(2);
        uv.Add(new Vector2(0, 0)); uv.Add(new Vector2(0, 1));
        uv.Add(new Vector2(1, 0)); uv.Add(new Vector2(1, 1));
        mesh.vertices = verticles.ToArray();
        mesh.triangles = indicats.ToArray();
        mesh.uv = uv.ToArray();
        ob.AddComponent<MeshFilter>().mesh = mesh;
        ob.AddComponent<MeshRenderer>().material = mat;

        return ob;
    }
写完这些其实也跑不起来,因为查几个引用方法。今天就现讲到这里,下节再讲。如果有什么问题的随时qq联系讨论。qq:1850761495。小节再讲编辑器和这2个demo的制作。










版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u012565990/article/details/52098008

智能推荐

Prometheus + Grafana 图形化监控实践_prometheus图形化监控-程序员宅基地

文章浏览阅读1k次。本文将详细介绍Prometheus和Grafana的快速搭建,并实现JVM、Mysql等实时监控。本文将在Windows环境搭建Demo。_prometheus图形化监控

全球十大农业大数据经典案例-程序员宅基地

文章浏览阅读4.2k次。基于物联网等技术的应用,农业领域积累了大量的数据,为大数据应用于农业奠定了基础。从国内国际的发展来看,大数据正在驱动农业发展路径发生变化,以提高农业效率,保障食品安全,实..._农业大数据应用案例

Mac在Dock程序坞上添加分割线,分割APP图标_mac程序坞分割线-程序员宅基地

文章浏览阅读9.9k次。遗憾分割线无法添加,我们只能添加一个空白的透明图标,来充当分割线,效果如下:添加方法按下F4,打开“其他”文件夹,打开“终端” 输入以下两行命令,回车 defaults write com.apple.dock persistent-apps -array-add '{ "tile-type" = "spacer-tile"; }'killall Dock 拖动空白的图标到需要的地方 完成..._mac程序坞分割线

git revert 撤销中间的某次提交_git revert --continue-程序员宅基地

文章浏览阅读5.9k次。使用场景如下:首先看一下我的提交(commit1这种都是指的是提交的commit-id)commit1commit2commit3commit4commit5commit6现在想把commit4扔掉,只需git log 从这里拿到commit4的id(当然咱们这里已经拿到了,coomit4就是)git revert commit4 正常情况下就撤销成功了..._git revert --continue

机器学习数据集之鸢尾花-程序员宅基地

文章浏览阅读1.4k次。Iris数据集是常用的分类实验数据集,由Fisher, 1936收集整理。Iris也称鸢尾花卉数据集,是一类多重变量分析的数据集, 它包含150个数据集,分为3类,每类50个数据,每个数据包含4个属性。自变量 feature 特性petal length 花瓣长度petal width 花瓣宽度sepal length 花萼长度sepal width 花萼宽度因变量..._book7_ch08_核技巧__机器学习__鸢尾花书__从加减乘除到机器学习.pdf

R in action 读书笔记(1)--第五章:高级数据管理-程序员宅基地

文章浏览阅读149次。5.2.1数学函数函数描述abs(x)绝对值sqrt(x)平方根ceiling(x)不小于x的最小整数floor(x)不大于x的最大整数trunc(x)向0的方向截取的X中的整数部分..._r in action 学习笔记:第五章

随便推点

计算机专业程序员单词分享含Anki牌组版_anki 牌组 单词-程序员宅基地

文章浏览阅读2.6k次,点赞17次,收藏8次。许多对计算机或者编程感兴趣的小伙伴都苦于英语脱了后腿所以特在此分享自己整理和和网络整合的计算机基础1500词分享Anki版为自己手动制作,以下为预览界面如果觉得不好看或者不想使用Anki的可以把文档导入到背单词软件,当然有的软件像有道、百词斩没有针对计算机的解释,所以推荐用欧陆你掌握这1500词之后相信日常编程,软件使用都可以应付了,但有的同学就是对自己要求高,就不想用百度,想在谷歌进行搜索,或者使用GitHub啊,Stack Overflow社区啊,可能这些单词就不够用了,所以这里还准备了一个_anki 牌组 单词

麻雀算法极限学习机(SSA-ELM)回归预测及其MATLAB代码实现-程序员宅基地

文章浏览阅读112次。SSA-ELM通过结合麻雀算法和极限学习机,能够优化ELM的隐层神经元数量和激活函数的选择,从而提高回归预测的性能。通过使用麻雀算法搜索的方式,SSA-ELM能够找到最佳的隐层神经元数量和激活函数,从而提高ELM的预测性能。极限学习机(ELM)是一种单隐层前馈神经网络模型,其特点是随机初始化输入层到隐层之间的连接权重和隐层的偏置,然后通过解析解的方式快速求解输出层到隐层之间的连接权重。麻雀算法极限学习机(SSA-ELM)是一种基于麻雀算法和极限学习机(ELM)的回归预测方法。极限学习机(ELM)简介。_ssa-elm

LaTeX 日语_setcjkmainfont{ipamincho}-程序员宅基地

文章浏览阅读3.6k次。有许许多多的包支持在不同 LaTeX 编译环境下的日语的输入,但它们并不是都支持特定的日语输入习惯,例如垂直方向的文字。本文简要介绍如何使用 pdfLaTeX、XeLaTeX、pTeX 和 LuaLaTeX 来输入日语。_setcjkmainfont{ipamincho}

Windows下查看端口占用情况_查看8080端口被哪个进程占用-程序员宅基地

文章浏览阅读5k次,点赞2次,收藏15次。编程的时候经常发现我们需要使用的端口被别的程序占用,这个时候需要清楚查看是哪个程序占用了端口,用且清除了这个进程!,回车,查看是哪个进程或者程序占用了2668端口,结果是:TIM.exe。注:后两步可以使用任务管理器,因为看的比较直观而且方便。,回车,记下最后一位数字,即PID,这里是2668。,点击查看—>选择列,_查看8080端口被哪个进程占用

hive中生成从1到n的连续数字的UDTF方法_hive生成连续数字-程序员宅基地

文章浏览阅读9.3k次。之前在博客中分享了个生成从1到n的连续数字的transform或map方法,最近研究了一下UDTF,发现用UDTF写出来的函数用起来更方便,语法更接近于普通的函数。而且在JAVA中对参数的个数、类型等进行校验也更容易。 ORACLE中生成从1到n的连续数字的方法很多,最简单的一种是:select level from dual connect by level _hive生成连续数字

解决阿里云Tomcat8080端口拒绝访问_阿里云8080拒绝连接请求-程序员宅基地

文章浏览阅读878次。解决阿里云Tomcat8080端口拒绝访问_阿里云8080拒绝连接请求

推荐文章

热门文章

相关标签