Ruby's Adventure: 2D Beginner - Unity Learnhttps://learn.unity.com/project/ruby-s-adventure-2d-chu-xue-zhe?uv=2019.4
目录
物理
移动时发生碰撞,为什么会抖动?
如何解决抖动?读取输入和移动的正确示范
对象暂停移动时,检测不到碰撞
只有Collider2D,没有Rigidbody2D的箱子
使用复合碰撞体(制作地形)
2D视觉处理
遮挡(排序问题)、轴点(Pivot)、碰撞体形状
动画
混合树(Blend Tree)
脚本
比较浮点数
在Start函数中获取组件的问题
UI
Canvas 的 Render Mode
Canvas Scaler
因为物理系统使用的是场景的简化副本,这个副本中仅包含碰撞体。这个物理场景可以使物理系统的计算更简化。
物理系统是如何工作的?
每当带有刚体的游戏对象在场景中移动时,在物理场景中移动自己的游戏对象副本。
施加作用力并计算碰撞。
将场景中的游戏对象移动到物理场景中计算出的新位置。
在此示例中,这会导致以下事件:
你在帧更新(Update)过程中移动角色到位置A。
物理系统将自己的游戏对象副本移到位置A。
物理系统发现:角色碰撞体现在位于另一个碰撞体(此处为箱子)内,然后将角色碰撞体移回以便不再位于箱子内(重新获得位置B)。
物理系统将 角色游戏对象 同步到位置B。
你不断移动 Ruby 到箱子内,而物理系统则将她移回。你要求代码执行的操作与物理系统执行的操作之间的这种冲突就会导致发生抖动。
(关于刚体的更多内容:)2D刚体与碰撞https://blog.csdn.net/yjy99yjy999/article/details/112839298
在类中添加两个浮点变量,以便在 Update 函数内存储当前的水平和垂直输入数据。
public class RubyController : MonoBehaviour
{
Rigidbody2D rigidbody2d;
float horizontal;
float vertical;
void Start()
{
rigidbody2d = GetComponent();
}
void Update()
{
horizontal = Input.GetAxis("Horizontal");
vertical = Input.GetAxis("Vertical");
}
void FixedUpdate()
{
Vector2 position = rigidbody2d.position;
position.x = position.x + 3.0f * horizontal * Time.deltaTime;
position.y = position.y + 3.0f * vertical * Time.deltaTime;
rigidbody2d.MovePosition(position);
}
}
解决方法:在 Rigidbody 组件中将 Sleeping Mode 设置为 Never Sleep。
为了优化资源,物理系统在刚体停止移动时会停止计算刚体的碰撞;此时刚体进入“睡眠状态”。但在你这个情况中,你希望始终进行计算,因为即使在 Ruby 停止移动时也需要检测她是否受到伤害,因此你要指示刚体永远不要进入睡眠状态。
这是正确的。这是因为不需要通过物理来移动箱子,只需要一个碰撞体即可,无论有没有刚体,游戏对象都将与箱子交互。
使用两个float值作为参数,控制动画状态的切换。直接看教程吧Sprite Animation - Unity LearnIn previous tutorials, you created a world that was full of objects, with a character that can move around and enemies to avoid. But so far, all that is very static. In this tutorial, you’ll add animation to your characters. Want to learn more about 2D Game Development with Unity? Connect with an expert Unity dev for a live 1:1 lesson.https://learn.unity.com/tutorial/jing-ling-dong-hua?uv=2019.4&projectId=5facf921edbc2a2003a58d3a#
使用 Mathf.Approximately 而不是 ==,这是因为计算机存储浮点数的方式意味着精度会有很小的损失。
检查move.x 或move.y 是否不等于0:
if(!Mathf.Approximately(move.x, 0.0f) || !Mathf.Approximately(move.y, 0.0f))
如果对象A是由其他对象的脚本实例化创建,紧接着调用对象A的某个函数, 报告了空引用的错误,需要检查Null的字段是否在对象A的 Start() 中赋值的。
这是因为在你创建对象时 Unity 不会运行 Start,而是在下一帧才开始运行。因此,要解决此问题,请在Awake()中为该字段赋值。
与 Start 刚好相反,在创建对象时(调用 Instantiate 时)就会立即调用 Awake,因此,在调用任何函数之前已正确初始化需要赋值的字段。
Screen Space - Overlay:这是默认模式,可以让 Unity 在始终在游戏的上层绘制 UI。大多数应用程序使用此模式,因为它们希望 UI 始终位于最上层以便提供所有信息。
Screen Space - Camera:这种模式在与摄像机对齐的平面上绘制 UI。平面的大小确定为始终填充整个屏幕,这样你就可以四处移动摄像机,并且平面将随摄像机一起移动,从而显示与 Overlay 图形相同的形状。
但是,由于平面是在世界中绘制的,而不是在屏幕上层绘制的,因此世界中的对象可以绘制在 UI 的上层。
World Space:这种模式可在世界中的任何位置绘制平面。例如,你可以将此平面用作游戏中的计算机屏幕,或者用作墙壁,或者放在角色的上层。这在 3D 游戏中更有用,因为 UI 会随着距离变小。