码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【Unity入门计划】制作RubyAdventure02-处理瓦片地图&碰撞


    目录

    3 使用TileMap瓦片地图创建世界

    4 处理游戏对象的前后遮挡关系

    5 实现碰撞

    5.1 解决碰撞BUG-碰撞范围

    5.2 解决碰撞BUG-玩家旋转

    5.3 解决碰撞BUG-碰撞抖动

    游戏引擎与物理引擎的更新帧率

    FixedUpdate() 

    处理完BUG的效果

    6 实现Tilemap的碰撞

    6.1 局部赋予碰撞体

    6.2 解决Tilemap碰撞体BUG

    Composite Collider 2D 复合碰撞体

    7 伪透视2D下碰撞和遮罩的关系

    7.1 使用素材时要有建立Prefab的习惯

    7.2 明确碰撞体范围的中心点


    已进行步骤

    制作RubyAdventure01-玩家的创建&移动

    3 使用TileMap瓦片地图创建世界

    在之前基于Game Kit的学习就涉及到了Tilemap,它是用来绘制2D游戏地图的一个很方便的工具。

    关于瓦片地图的学习,由于内容比较多我另开了两个博客专门讲了讲Tilemap:

    【Unity入门计划】基本概念(8)-瓦片地图 TileMap 01_flashinggg的博客-CSDN博客

    【Unity入门计划】基本概念(8)-瓦片地图 TileMap 02_flashinggg的博客-CSDN博客

    4 处理游戏对象的前后遮挡关系

    教程中介绍的是基于Unity自带的功能,我进行了补充,也找到了另外的处理这个问题的方法,也总结成了博客:【Unity入门计划】2D游戏中遮挡问题的处理方法&伪透视_flashinggg的博客-CSDN博客

    5 实现碰撞

    想要游戏交互更加真实,加入碰撞是必须的!

    先把玩家Ruby和加入到场景中的一个盒子,都做成预制件Prefab,以方便接下来重复使用,分别

    • 给Ruby加上一个Rigidbody 2D + Box Collider 2D
    • 给箱子加上一个Box Collider 2D 用于实现碰撞(因为盒子是静止的因此不需要刚体组件)

    直接查看效果,会出现一些怪异的BUG: 

    5.1 解决碰撞BUG-碰撞范围

    这个简单,直接编辑对应预制件碰撞体的范围就行。

     

    5.2 解决碰撞BUG-玩家旋转

    这里直接给Ruby预制件的属性中 Constraints冻结Z轴旋转即可。

    5.3 解决碰撞BUG-碰撞抖动

    抖动问题出在移动脚本和碰撞体之间的问题,挂了碰撞体组件后:

    先检测Ruby移动进入了箱子碰撞体的范围内 -> 物理引擎生效 -> 把Ruby挤出去碰撞体范围 -> Ruby再靠近盒子 -> 物理引擎再生效...这样不断重复,就造成了抖动。

    解决办法也很直接:在我们的移动脚本中,直接移动刚体本身而非游戏对象的变换组件,让物理系统将游戏对象位置同步到刚体的位置。这样,物理系统就可以在进入箱子前停止移动,也就不会在进入箱子的碰撞范围后再移动Ruby。

    游戏引擎与物理引擎的更新帧率

    参考:从零手写游戏引擎21:物理引擎基础 - 知乎 (zhihu.com)

    摘抄至参考文章:由于物理引擎中存在大量微积分运算,所以物理引擎一般会要求物理更新的时间步长,也就是dt,保持恒定。而游戏引擎的更新帧率却是不确定的,可能会根据程序运行的情况或者硬件设备的性能不同而产生波动。这就意味着,游戏引擎的更新帧率,与物理引擎的更新帧率是不一致的。假设物理引擎的更新间隔为0.02s,如果游戏引擎某一帧因为某些原因卡顿,更新耗费了0.04s,那么下一帧物理引擎有可能在一次逻辑更新之前进行了2次更新,这完全是有可能的。

    用官方教程中的话来描述,就是:每次游戏计算新一帧图像时都会调用Update(),但调用速度是由电脑的计算处理速度决定的,有可能调用速度是每秒20帧,也有可能是每秒3000帧。

    FixedUpdate() 

    为了保持物理计算的稳定, 需要定期更新,这就需要用到FixedUpdate()来实现固定时间间隔执行更新。FixedUpdate()默认是0.02次/秒,也就是每秒更新50次,也可以在Project Settings里自定。 

    修改后的脚本

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class RubyController : MonoBehaviour
    5. {
    6. //声明刚体对象
    7. Rigidbody2D rigidbody2D;
    8. //在方法外声明水平和数值量
    9. float horizontal;
    10. float vertical;
    11. private void Start()
    12. {
    13. //游戏运行前,获取当前游戏对象的刚体组件
    14. //这里用到了GetComponent获取当前所在对象的吗某个组件 - GetComponent<>()
    15. rigidbody2D = GetComponent();
    16. }
    17. // 每帧都会执行一次Update函数
    18. void Update()
    19. {
    20. //声明新变量
    21. //获取水平轴并储存在新变量中
    22. horizontal = Input.GetAxis("Horizontal");
    23. //获取垂直轴
    24. vertical = Input.GetAxis("Vertical");
    25. }
    26. void FixedUpdate()
    27. {
    28. Vector2 position = transform.position;
    29. //对x轴移动距离做了细微的更改
    30. position.x += horizontal * 3.0f * Time.deltaTime;
    31. //对y轴也做相应更改
    32. position.y += vertical * 3.0f * Time.deltaTime;
    33. rigidbody2D.position = position;
    34. }
    35. }

    处理完BUG的效果

    6 实现Tilemap的碰撞

    6.1 局部赋予碰撞体

    Tilemap有专门的碰撞体: Tilemap Collider 2D,单纯挂上一个碰撞,会发现每个格子都被约束了。

     

    需要到Tiles文件中修改Default Collider,实现局部赋予碰撞体

    • None——不赋予碰撞体
    • Sprite——赋予碰撞体

    6.2 解决Tilemap碰撞体BUG

    问题出在哪儿呢?当游戏世界很大,Tilemap范围非常大的时候,物理系统计算量变大,游戏运行会被减慢。速度如果很快,遇到带有碰撞体的Tilemap会出现直接“卡过去”的情况。

    如果改变?Unity为我们提供了复合碰撞体组件。

    Composite Collider 2D 复合碰撞体

     之前我写过一篇总结2D碰撞体的博客,里面有对复合碰撞体组件组成的介绍:

    【Unity入门计划】基本概念(3)-2D碰撞体Collider 2D

     如何使用呢?

    给Tilemap游戏对象添加一个Composite Collider 2D组件,同时会自动加入一个2D刚体组件,接着让Tilemap Collider 2D中选择:Used By Composite

    此时,场景中有碰撞体的Tile会组成一个整体,不再是单独的一个一个小格子了,可以看看前后对比:

    7 伪透视2D下碰撞和遮罩的关系

    7.1 使用素材时要有建立Prefab的习惯

    简单建立一个场景

    在搭建场景时,跟着教程会把每个素材都做成一个预制件,减少重复操作。

    7.2 明确碰撞体范围的中心点

    范围的位置是根据精灵的pivot变化而变化的,因此编辑顺序应该是:修改精灵的pivot -> 调整碰撞体的范围

    例如,给游戏对象House一个碰撞体,并挂上伪透视脚本,勾选Static,就有如下效果

     

  • 相关阅读:
    Open3D(C++) GICP算法实现点云精配准
    HummerRisk 使用场景-混合云安全治理(2)--阿里云安全最佳实践
    使用QT实现http里面的get和post
    STM32的GPIO端口的八种模式解析
    技术分享 | 详解SQL加密函数:AES_ENCRYPT()
    中小企业怎么去挑选ERP系统?
    Spring Cloud Alibaba全套笔记,几乎涵盖了所有操作
    摘茧机设计
    敞开心扉地说家人们,爬也要爬进互联网大厂
    【算法训练-贪心算法 一】买卖股票的最佳时机II
  • 原文地址:https://blog.csdn.net/qq_41835314/article/details/126123430
  • 最新文章
  • 沪漂五周年了:我越来越迷茫了
    Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
    MySQL-Seconds_behind_master的精度误差
    [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
    AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
    Agent OS :五种驯服不确定性的范式
    PortSwigger SQL注入LAB11
    数据库即时编译JIT
    [Begin]AI Learn Data Day 0
    深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号