Unity 实现2D地面挖洞!涂抹地形(碰撞部分,方法二)

这篇具有很好参考价值的文章主要介绍了Unity 实现2D地面挖洞!涂抹地形(碰撞部分,方法二)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

老规矩先上效果图
unity 图片挖洞,涂抹地形,小鳄鱼爱洗澡,Unity挖洞,Unity涂抹地形,地面涂抹

继上一篇涂抹地形文章讲解发出后,有不少网友私信找我要原码,也有部分网友觉得太复杂了难以实现。关于原码因为这个Demo最初始的原码弄不见了,还有就是代码本身用在了公司的游戏项目中加了很多项目相关的逻辑,我不知道能不能分享所以没有直接公布原码。关于太难实现的问题,如果只是要达到涂抹地形的话这里我再分享一个更简单的方式,非常简单!

上一篇的地址:
涂抹地形碰撞部分方法一

为什么说简单呢,因为只需要用到距离计算公式,与圆形碰撞盒:
unity 图片挖洞,涂抹地形,小鳄鱼爱洗澡,Unity挖洞,Unity涂抹地形,地面涂抹

好了下面开始进入正文…


一、初始化虚拟点

初始化的时候创建检查点,用数组存起来。
需要注意的是这里的检查点只是Vector2,不需要实例化否则会非常消耗性能。切记切记…

1.1点结构:

每个点用一个结构存起来,我们需要存下
下面是点数据结构,分别是记录:1.点的位置,2.当前点的状态,3.对应的碰撞盒

private class PointData
{
    public Vector2 pos;               //点位置
    public pointStatic sta;          //点状态
    public GameObject col;          //点实例
}

1.2每个点有的状态:

1.已经废弃,这个位置已经被完全挖开
2.等待检测,这个位置还没被挖到
3.正在使用:即这个位置是挖掘的边缘,有碰撞盒

private enum pointStatic
{
    die,                        //已经废弃
    wait,                       //等待检测
    collid                      //正在使用
}

1.3生成点结构:

int line = (int)(scale.x * 100);
int row = (int)(scale.y * 100);
float distancesX = 1f / line;
float distancesY = 1f / row;
for (int j = 0; j < row; j++)
{
    for (int k = 0; k < line; k++)
    {
        Vector2 v2 = new Vector2(distancesX * k - 0.5f, distancesY * j - 0.5f);
        PointData data = new PointData();
        data.pos = v2;
        data.sta = pointStatic.wait;
        listPoint.Add(data);
    }
}

不难看出这些结构点,除了Vector2以外并没有实例化什么内容,主要是这里创建了10000个点,这样可以极大的节省性能.
其实就像如图,创建了100X100个虚拟点:
unity 图片挖洞,涂抹地形,小鳄鱼爱洗澡,Unity挖洞,Unity涂抹地形,地面涂抹


二、实例化边缘碰撞盒

为了一开始还未操作时,物体不会从方块边缘直接穿过去过,我们需要将边缘的点先实例化出碰撞盒,效果如图:
unity 图片挖洞,涂抹地形,小鳄鱼爱洗澡,Unity挖洞,Unity涂抹地形,地面涂抹

2.1计算生成边缘碰撞盒

下面方法计算出边缘位置,并生成一边缘一圈碰撞盒,并将点记录到上面的数组中,这样后面涂抹的时候才可以将碰撞盒去掉.
计算边缘位置并生成的代码:

distancesX *= 3;
distancesY *= 3;
for (float x = -0.5f; x <= 0.5; x += distancesX)
{
    CreateBianKuan(new Vector3(x, -0.5f, 0));
    CreateBianKuan(new Vector3(x, 0.5f, 0));
    CreateBianKuan(new Vector3(-0.5f, x, 0));
    CreateBianKuan(new Vector3(0.5f, x, 0));
}
下面是具体生成的代码:
public void CreateBianKuan(Vector3 v3)
{
    Object obj = Resources.Load("MousePoint3");
    GameObject go = Instantiate(obj, Vector2.zero, Quaternion.Euler(Vector3.zero), target.transform) as GameObject;
    go.transform.localPosition = v3;
    go.transform.localScale = new Vector3(ColliderSize / scale.x, ColliderSize / scale.y, ColliderSize);
    PointData data = new PointData();
    data.pos = new Vector2(v3.x, v3.y);
    data.sta = pointStatic.collid;
    data.col = go;
    listPoint.Add(data);
}

"MousePoint3"其实就是带碰撞盒的圈
unity 图片挖洞,涂抹地形,小鳄鱼爱洗澡,Unity挖洞,Unity涂抹地形,地面涂抹


三、涂抹部分

前面铺垫了那么多,终于到核心的涂抹部分了
如图:
unity 图片挖洞,涂抹地形,小鳄鱼爱洗澡,Unity挖洞,Unity涂抹地形,地面涂抹

3.1.虚拟点

图中密密麻麻的是我们未创建碰撞盒的虚拟点,

3.2.鼠标点

黑色圈是鼠标点击的位置

3.3.内圈

红色为内圈,是我们需要挖掘的位置,此圈内的点则:
1):如状态为dit废弃则不做处理,
2):如状态为collid(有碰撞盒),即有碰撞盒则,销毁碰撞盒并改为die(废弃)
3):如为wait(等待处理),则状态改为die(废弃)

3.4.外圈

蓝圈略大于红圈,此范围是我们挖掘边缘的位置,则红圈以外蓝圈以内的点则:
1):状态为dit废弃则不做处理,
2):状态为wait(等待处理)则创建碰撞盒,并改为collid(有碰撞盒)
3):状态为collid则不做处理

具体代码如下,大家参考一下:

public void WaDong()
{
    //创建一条射线一摄像机为原点
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    RaycastHit hit;
    //射线碰撞到游戏地形时
    if (Physics.Raycast(ray, out hit))
    {
        //从世界坐标转为局部坐标
        Vector2 localCenter = target.transform.InverseTransformPoint(hit.point);
        for (int i = 0; i < listPoint.Count; i++)
        {
            Vector2 centerPos = listPoint[i].pos - localCenter;
            centerPos.x *= scale.x;
            centerPos.y *= scale.y;
            float dis = Vector2.Distance(centerPos, Vector2.zero);
            if (dis < Circle1Range1 && listPoint[i].sta != pointStatic.die)
            {
                listPoint[i].sta = pointStatic.die;
                if (listPoint[i].col != null)
                {
                    GameObject.Destroy(listPoint[i].col);
                }
             
            }
            else if (dis >= Circle1Range1 && dis < Circle1Range2 && listPoint[i].sta == pointStatic.wait)
            {
                listPoint[i].sta = pointStatic.collid;
                Object obj = Resources.Load("MousePoint3");
                GameObject go = Instantiate(obj, Vector2.zero, Quaternion.Euler(Vector3.zero), target.transform) as GameObject;
                go.transform.localPosition = listPoint[i].pos;
                go.transform.localScale = new Vector3(ColliderSize / scale.x, ColliderSize / scale.y, ColliderSize);
                listPoint[i].col = go;
            }
        }
    }
}


四、关于优化

关于优化可以从几个方面着手,因为碰撞盒的数量比较多,而且创建销毁比较频繁.这一部分可以考虑对象池.
另一方面是销毁的点其实不太需要再次进行计算,因为可以考虑将废弃点的点移出表外.
进一步的优化留给大家自己思考咯…


结语:

这篇文章主要和大家分享一下实现的思路,说起来也简单.一开始创建一堆虚拟点等着检查.以点击位置为圆心进行距离计算.
小圈内为涂抹掉的位置,大圈内为边缘位置判断是否增删碰撞点.
希望对大家有帮助.如果可以帮忙点个赞,谢谢.文章来源地址https://www.toymoban.com/news/detail-735220.html

到了这里,关于Unity 实现2D地面挖洞!涂抹地形(碰撞部分,方法二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Unity】Unity碰撞检测(3D和2D)

    碰撞检测可以说时学习Unity中最重要的一个部分,以为在游戏中,想要游戏进行交互,碰撞时非常重要的,而我在网上查了很多教程,但是都没有成功,后来经过我的仔细检查代码与修改,终于成功了 简单Unity跑酷游戏 简单跑酷游戏 在 zhong_dot 和 Player 两个实体都加上 碰撞体

    2024年02月20日
    浏览(31)
  • Unity 2D视角下模拟3D环境和地形

    2D游戏若想模仿3D游戏的环境,一种很好的方案便是“2.5D”。 所谓2.5D,通常的理解是相机固定俯视的游戏视角。在此视角下,人物可以在x、y、z三个轴上移动,如此便能模仿3D游戏的环境,而美术成本要比3D低很多。 2.5D具体实现的方式也分多种,如2D角色+3D场景、3D角色+2D场

    2024年02月06日
    浏览(47)
  • Unity碰撞检测(3D和2D)

    碰撞检测可以说时学习Unity中最重要的一个部分,以为在游戏中,想要游戏进行交互,碰撞时非常重要的,而我在网上查了很多教程,但是都没有成功,后来经过我的仔细检查代码与修改,终于成功了 简单Unity跑酷游戏 简单跑酷游戏 在 zhong_dot 和 Player 两个实体都加上 碰撞体

    2024年02月10日
    浏览(42)
  • 19. Unity - 2D游戏开发小记02 --- 伪透视图、2D物体碰撞、瓦片地图碰撞、素材缩放平铺

    1. 伪视图 在2D游戏开发当中,当角色移动时,会发生物体与物体之间的前后遮挡。2D视图中的前后关系是由 Y 轴决定,y 值越小物体越靠前。unity的渲染应开启根据 y 值的大小进行渲染才能保证正确的遮挡效果,在菜单栏 Editor–project setting -- Graphic 中按照下图方式进行设置:

    2024年02月02日
    浏览(83)
  • 【Unity 2D AABB碰撞检测】铸梦之路

    视屏教程地址:https://www.taikr.com/user/192182 AABB 代表的是轴对齐碰撞盒 (Axis-aligned Bounding Box) AABB碰撞盒是指与场景基础坐标轴(2D中的是x和y轴)对齐的长方形的碰撞外形。与坐标轴对齐意味着这个长方形 没有经过旋转 并且它的边线和场景中基础坐标轴平行(例如,左右边线和

    2024年02月16日
    浏览(43)
  • [Unity学习日志]用Collider2D.IsTouchingLayers()进行碰撞检测

    复健,跟麦扣老师的教程注意到的新方法 Unity2018教程2D入门:07 跳跃动画 LayerMask_哔哩哔哩_bilibili 目的是检测玩家是否落地,然后切换动画 自己的实现就是简单的检测速度: 麦扣老师的方法:检测玩家是否与地面这个Layer产生碰撞,产生碰撞即落地 具体步骤: 1.将Tilemap图层设

    2023年04月22日
    浏览(41)
  • 关于unity中碰撞盒Collider2D中的Layer Overrides属性

    层碰撞矩阵 edit -》 project settings -》physics 2d 配置好一个GameObject之后,设置它的Layer 仅给当前Collider添加可碰撞的额外层。所以当前Collider发生碰撞or触发的层为: 层碰撞矩阵 + include layers 。 仅给当前Collider移除可碰撞的额外层。当前碰撞层级: 层碰撞矩阵 - exclude Layers 。 默

    2024年04月27日
    浏览(37)
  • Unity常用方法--Physics2D.OverlapCircleAll(获取一个圆形区域内所有碰撞器的列表)

    使用方式请直接看参考文献 使用案例 可以通过该方法判断在攻击范围内是否存在敌人,并在存在时,调用敌人组件的内部函数 代码 参考文献   https://docs.unity3d.com/cn/current/ScriptReference/Physics2D.OverlapCircleAll.html

    2024年04月10日
    浏览(34)
  • 2022版本unity-2D游戏官方案例--带视频案例(1)(层级渲染,物理碰撞,粒子动画,UI等多位基础一体化)

      👨‍💻个人主页:@元宇宙-秩沅 hallo  欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由  秩沅  原创 收录于专栏 unity实战入门  ⭐相关文章⭐ ——————————————————— -[本站最全-unity常用API大全(万字详解),不信你不收藏] -[关于游戏剧情模式中用到的

    2024年02月03日
    浏览(63)
  • Unity地面交互效果——2、动态法线贴图实现轨迹效果

    回到目录 Unity引擎动态法线贴图制作球滚动轨迹   大家好,我是阿赵。   之前说了一个使用局部UV采样来实现轨迹的方法。这一篇在之前的基础上,使用法线贴图进行凹凸轨迹的绘制。   先来回顾一下,上一篇最终我们已经绘制了一个轨迹的贴图   可以思考一下,

    2024年02月06日
    浏览(69)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包