Surface Effector 2D
Platform Effector 2D
向上跳跃穿过天花板的功能
平台效应器不用变Trigger,因为本来就是要有碰撞的
use one way grouping是让所有相关联的碰撞器都可以单面跳墙
默认不勾选,左右两边没有摩擦力和弹力,要自己先设置side arc,表示你要生效的范围
在平台的两侧使用摩擦力和弹力 ,防止卡墙上不走(因为两个碰撞器之间默认有摩擦力),不设置确实可以贴在墙上不走
Point Effector 2D
|--------------------|----------------------------------------------------------|
| Distance Scale | 应用于源和目标之间距离的缩放。在计算此距离时,按该比值对距离进行缩放,因此可以改变有效距离,从而控制施力的大小。 |
Force Mode有三种,两种吸力的不同算法而已,
constant一直保持一个力
linear就是线性减少,inverse就是曲线指数减少
Buoyancy Effector 2D
Area Effector 2D
恒定力用的比较少
relative force是相对刚体挂载的对象的坐标系加力
torque是旋转力
复合碰撞器
- 物理材质:不同的物理材质(如摩擦系数和弹性系数)会影响碰撞后的行为。确保物体使用适当的材质可以改善效果。
为了获得更好的碰撞效果,可以:
- 使用简单的碰撞体来代替复杂的Mesh Collider。
- 定期检查并调整物理材质的设置。
- 考虑物体的移动速度,确保不会因运动过快而导致穿透或不自然的碰撞响应。
复合碰撞器 (Composite Collider 2D) 独有的可以生成"空心"效果。具体来说,复合碰撞器 配合 Geometry Type
设置为 Outlines
,可以让碰撞器只在外边缘起作用,而内部是空的。
在 Unity 中,单独的 BoxCollider2D 、CircleCollider2D 、PolygonCollider2D 等通常是实心的,它们没有类似的设置来直接生成"空心"的效果。只有复合碰撞器 通过组合其他碰撞器(如 BoxCollider2D、PolygonCollider2D)并设置 Geometry Type
才能创建空心的几何结构。
实现空心碰撞器的步骤:
- 给对象添加多个基础碰撞器,比如 BoxCollider2D 或 PolygonCollider2D。
- 添加 Composite Collider 2D 组件,Unity 会自动将这些基础碰撞器组合成一个整体。
- 在 Composite Collider 2D 中,将
Geometry Type
设置为Outlines
,这样碰撞器只在边缘生效,内部将是空心的。
这样就可以模拟出一个空心的物体,其他物体可以在它内部自由移动,只有当它们接触到外边的轮廓时才会发生碰撞。
Trigger
物理材质
所有 2D 碰撞器 都可以通过设置 isTrigger
属性来控制它们是作为实心的物理碰撞体,还是仅作为触发器使用。无论是复合碰撞器还是单独的碰撞器组件,这个属性的行为是相同的。
isTrigger
属性
-
实心碰撞器 :
当
isTrigger
为false
时,碰撞器会作为物理碰撞体处理,物体会在碰撞时产生反弹、阻挡等物理效果。 -
触发器 (Trigger) :
当
isTrigger
为true
时,碰撞器会变成一个触发器。触发器不会产生物理碰撞效果,物体可以穿过它,但会触发OnTriggerEnter2D
、OnTriggerStay2D
和OnTriggerExit2D
等事件。
在复合碰撞器中的行为
-
如果你在一个对象上组合了多个碰撞器,比如
BoxCollider2D
和CircleCollider2D
,你可以单独为每个碰撞器设置isTrigger
。这样,某些碰撞器可以作为触发器,而其他的保持实心。BoxCollider2D box = gameObject.AddComponent<BoxCollider2D>();
-
CircleCollider2D circle = gameObject.AddComponent<CircleCollider2D>(); box.isTrigger = false; // 实心碰撞器
-
circle.isTrigger = true; // 触发器
-
复合碰撞器是否支持实心/触发器的混合 :
如果你在一个对象上复合多个碰撞器,其中有些碰撞器是实心的,有些是触发器,它们的行为会独立存在。触发器的部分仍然只会触发事件,而实心部分会处理物理碰撞。
碰撞器
碰撞检测函数
trigger也是一样的
2D 碰撞器 不仅限于 CircleCollider2D
和 BoxCollider2D
。你可以使用多种不同类型的 2D 碰撞器,而且可以将多个碰撞器组件组合在一起,从而创建更复杂的碰撞区域
常见的 2D 碰撞器类型:
- CircleCollider2D
- 一个圆形的 2D 碰撞器,适用于圆形或球状的物体。
- BoxCollider2D
- 一个矩形的 2D 碰撞器,适用于长方形或正方形的物体。
- PolygonCollider2D
- 可以定义任意形状的多边形碰撞器,通过多个顶点连接来形成复杂的轮廓。适用于非规则形状的物体。
- EdgeCollider2D
- 由一系列线段组成的碰撞器,不会包围任何区域,适用于地形或平台边缘。
- CapsuleCollider2D
- 胶囊形的碰撞器,适用于长条状带有圆头的物体,比如角色碰撞体。
复合碰撞器的概念
复合碰撞器 是指将多个简单的碰撞器(如 Circle、Box 等)组合在同一个对象上,以模拟一个更复杂的形状。例如,你可以将多个 BoxCollider2D
和 CircleCollider2D
组合在一个物体上来准确包围其形状。
-
通过添加多个碰撞器组件:
- 你可以在同一个 GameObject 上添加多个不同的碰撞器组件,比如同时添加
BoxCollider2D
和CircleCollider2D
。这样,物体在碰撞时会按照这些碰撞器的组合形状来检测。
gameObject.AddComponent<BoxCollider2D>(); gameObject.AddComponent<CircleCollider2D>();
- 你可以在同一个 GameObject 上添加多个不同的碰撞器组件,比如同时添加
-
Rigidbody2D 与复合碰撞器:
- 当一个对象上有多个碰撞器时,通常需要配合一个
Rigidbody2D
使用。Rigidbody2D
将这些碰撞器视为一个整体,使它们一起运动和检测。
- 当一个对象上有多个碰撞器时,通常需要配合一个
PolygonCollider2D 的使用
PolygonCollider2D
是非常强大的工具,它允许你通过多个顶点来定义复杂的形状,因此在某些情况下,你可能不需要复合多个简单的碰撞器,而可以直接使用一个 PolygonCollider2D
来表示整个复杂形状。
-
自定义形状 : 你可以在 Unity 编辑器中手动调整
PolygonCollider2D
的顶点,或者通过代码动态生成顶点。PolygonCollider2D polyCollider = gameObject.GetComponent<PolygonCollider2D>(); polyCollider.SetPath
-
(0, new Vector2[] { new Vector2(0,0), new Vector2(1,0), new Vector2(0,1) });
使用多个碰撞器的优点
-
更精确的碰撞检测 :
对于非规则形状的对象,单一的
BoxCollider2D
或CircleCollider2D
可能无法精确模拟其边界。通过组合多个碰撞器,你可以更准确地定义物体的形状,减少不必要的物理计算或碰撞失误。 -
优化性能 :
复合多个简单的碰撞器有时比使用一个复杂的
PolygonCollider2D
更高效。虽然PolygonCollider2D
能创建任意形状,但它的计算复杂度较高。
物体在碰撞之后的位移旋转,是依靠rigidbody
有了刚体只是受力的作用,还没有确定物体的大小和形状
rigidbodyAPI
1. 基础属性
-
velocity (
Vector2
)当前
Rigidbody2D
的速度向量,控制物体在 2D 空间中的移动速度。你可以直接设置它来让物体在某个方向上移动。rb.velocity = new Vector2(2, 0); // 设置刚体水平向右移动,速度为 2
-
angularVelocity (
float
)物体的旋转速度(角速度),以度/秒为单位。正值表示顺时针旋转,负值表示逆时针旋转。
rb.
angularVelocity= 50f; // 设置刚体以
50 度/秒的速度
顺时针旋转
-
mass (
float
)物体的质量,影响碰撞和物体受力的行为。
rb.mass = 5.0f; // 设置刚体的质量为 5
-
drag (
float
)线性阻力,模拟空气或液体的阻力,减慢物体的移动速度。
rb.drag = 0.5f; // 设置阻力为 0.5
-
angularDrag (
float
)角阻力,减慢物体的旋转速度。
rb.angularDrag = 0.3f; // 设置角阻力为 0.3
-
gravityScale (
float
)控制刚体受重力影响的强度,默认为 1(受正常重力影响)。设置为 0 时,刚体不受重力影响。
rb.gravityScale = 0; // 取消重力影响
-
isKinematic (
bool
)如果
isKinematic
为true
,则刚体不再受物理引擎的控制(不受重力、碰撞等影响),而由脚本控制它的运动。rb.isKinematic = true; // 将刚体设置为运动学刚体
-
interpolation (
RigidbodyInterpolation2D
)控制刚体在物理帧之间的插值方式。可以选择
None
、Interpolate
或Extrapolate
。这是为了在帧率不稳定的情况下平滑显示物体的运动。rb.interpolation
=
RigidbodyInterpolation2D.Interpolate; // 开启插值
-
collisionDetectionMode (
CollisionDetectionMode2D
)设置刚体的碰撞检测模式,有
Discrete
(默认)、Continuous
等模式。连续碰撞检测可减少高速运动物体穿过障碍物的问题。rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous;
// 使用连续碰撞检测
2. 力和碰撞
-
AddForce(Vector2 force, ForceMode2D mode = ForceMode2D.Force)
向刚体施加一个力。
mode
参数可以是Force
(连续施加力)或Impulse
(瞬间施加力)。rb.AddForce(new Vector2(10, 5)); // 向刚体施加一个向右上方的力
-
rb.AddForce(new Vector2(10, 5), ForceMode2D.Impulse); // 瞬间施加一个力
-
AddTorque(float torque, ForceMode2D mode = ForceMode2D.Force)
向刚体施加一个扭矩(使物体旋转的力)。
rb.AddTorque(20f); // 施加一个使物体旋转的力
-
MovePosition(Vector2 position)
手动将刚体移动到一个新位置。如果
isKinematic
为true
,可以使用此方法直接控制刚体位置。rb.MovePosition(new Vector2(3, 5)); // 将刚体移动到 (3, 5) 位置
-
MoveRotation(float angle)
手动将刚体旋转到一个新的角度(以度为单位)。适用于
isKinematic
为true
的刚体。rb.MoveRotation(90f); // 将刚体旋转到 90 度
-
IsTouchingLayers(int layerMask)
检查刚体是否接触某个特定层的物体。
bool isTouching = rb.IsTouchingLayers(LayerMask.GetMask("Ground")); // 检查是否接触名为 "Ground" 的层
-
Sleep()
使刚体进入休眠状态,停止它的物理计算。刚体可以通过碰撞或其他事件重新唤醒。
rb.Sleep(); // 让刚体进入休眠
-
WakeUp()
唤醒刚体,开始物理计算。
rb.WakeUp(); // 唤醒刚体
3. 碰撞事件
这些事件是和 Rigidbody2D
物体碰撞时触发的,可以用来处理游戏中的碰撞逻辑。
-
OnCollisionEnter2D(Collision2D collision)
当
Rigidbody2D
与另一个物体发生碰撞时触发。void OnCollisionEnter2D(Collision2D collision)
-
{ Debug.Log("Collided with " +
collision.gameObject.name); }
-
OnCollisionExit2D(Collision2D collision)
当
Rigidbody2D
与另一个物体停止碰撞时触发。 -
OnTriggerEnter2D(Collider2D collider)
当
Rigidbody2D
进入触发器(Trigger
)区域时触发。 -
OnTriggerExit2D(Collider2D collider)
当
Rigidbody2D
离开触发器区域时触发。
4. 常见方法
-
SetRotation(float angle)
设置刚体的旋转角度。
rb.
SetRotation(45f); // 直接设置刚体旋转到 45 度 -
SetRotation(Quaternion rotation)
设置刚体的旋转为四元数形式。
-
OverlapPoint(Vector2 point)
检查刚体的碰撞体是否覆盖某个特定的点。
bool isOverlapping = rb.OverlapPoint(
new Vector2(2, 2)); // 检查某个点是否被刚体覆盖
静态刚体和只加碰撞器有什么区别
运动学刚体
simulated有些不同,
额外多了use full kinematic contacts
切换刚体类型
Interpolate
选项解释
Rigidbody2D
的 Interpolate
属性有以下三个选项:
-
None(默认值):
- 没有插值,也就是说物体的运动只会在每一帧物理计算后更新。这意味着物体的运动会非常"生硬",尤其是在帧率波动较大的情况下,物体的运动可能显得不连贯或卡顿。
- 如果你的游戏物理运算足够快,且帧率稳定,这种方式是性能最高的。
-
Interpolate:
- Unity 会基于前一帧的物理位置和平滑插值来推测物体当前帧的渲染位置,使物体看起来运动更加平滑。它通过插值的方式,计算出一个基于当前帧时间的中间位置。
- 适合当物理更新频率较低,或者帧率不稳定的情况。插值会让视觉效果更流畅。
-
Extrapolate:
- 与
Interpolate
相反,Extrapolate
是通过前一帧的物理位置和速度向外推测出物体的下一帧位置。这意味着 Unity 会根据上一帧的运动状态预估当前帧的位置。 - 适合物体运动变化较为均匀和帧率稳定的情况。Extrapolate 对于突然发生加速或减速的物体,可能会产生不准确的预测。
- 与
使用场景
- None :当你的游戏物理运算频率和帧率非常稳定时,不需要额外插值,可以使用
None
来获得最佳性能。 - Interpolate :如果你的游戏场景中,2D 物体的运动偶尔出现轻微卡顿或不平滑,使用
Interpolate
可以有效解决这个问题,特别是在帧率不稳定的情况下。 - Extrapolate :适用于物体运动较为稳定和线性的情况(比如恒定速度运动的物体),但如果物体运动有频繁的速度变化,
Extrapolate
可能会出现误差。
总结
- None:没有插值,直接使用物理引擎计算的位置更新,性能最高,但可能导致卡顿。
- Interpolate:通过插值平滑物体运动,适合帧率不稳定的情况。
- Extrapolate:通过预测平滑物体运动,适合物体运动较为稳定和线性的情况。
物体的碰撞器上有就用碰撞器上的
子物体没材质,父物体的rigidbody的材质会把子物体一起捎上
图集
1. 打包图集后,SpriteRenderer
是否自动更新
- 不会自动更新 :即使你将图片打包成图集,原先代码中通过文件名引用的
Sprite
还是会指向原来的单独图片,而不是图集里的Sprite
。要让SpriteRenderer
使用图集中的Sprite
,你需要手动更新这些引用。 - 如果希望图片引用更新到图集,通常需要修改代码或使用 Unity 提供的
Sprite Atlas
系统来管理Sprite
资源。
2. 图集的好处
- 性能优化 :将图片打包成图集可以减少
Draw Calls
(绘制调用),因为 Unity 会将同一个图集中的Sprite
一次性加载到显存中,减少了渲染过程中的切换成本。如果你的场景中使用了很多不同图片,将它们打包成图集会大大提升渲染效率。
3. 如何让 SpriteRenderer
使用图集
- 手动调整 :打包成图集后,需要将
SpriteRenderer
引用的Sprite
改为图集中的对应Sprite
。如果手动调整不方便,可以编写脚本动态加载图集并更新引用。
4. 动态打包图集的注意事项
- 打包时,Unity 会自动将相同的
Packing Tag
的图片打包进一个图集。如果你之前没有指定Packing Tag
,需要在图集打包时手动设置,确保相关图片被打包到同一个图集中。
总结:
- 如果你之后将图片打包成图集,引用
SpriteRenderer
的图片不会自动更新到图集中的Sprite
,需要手动或者通过脚本更新引用。 - 打包成图集有助于性能优化,尤其在减少
Draw Calls
方面,但要确保SpriteRenderer
使用图集中的资源才能生效。
在 Unity 中,GetComponent<T>()
不会 自动创建组件。如果你调用 GetComponent<T>()
时,没有找到目标组件,它会返回 null
,而不是自动为你添加一个新组件。
SpriteAtlas需要引用命名空间
-
Read/Write Enabled:
- 如果启用,表示纹理可以在运行时被脚本读取或修改。这会占用更多内存,因此在不需要时关闭。
-
Generate Mip Maps:
- 生成多级纹理(Mip Map),用于在不同距离上显示不同分辨率的纹理,从而提高性能和画质。通常在3D场景中使用。
-
sRGB:
- 如果启用,表示纹理将按照 sRGB 色彩空间加载。对于颜色数据(例如 UI 或环境光贴图),sRGB 是合适的选项,而对于法线贴图或其他不涉及颜色的纹理数据,则应禁用。
-
Filter Mode (Bilinear):
- 定义纹理在缩放时如何被过滤。常见模式包括:
- Point :像素化处理,没有插值,适合像素艺术风格。
- Bilinear:双线性过滤,会对纹理进行平滑处理。
- Trilinear:在 bilinear 基础上加入多级纹理之间的平滑过渡,适合需要更高质量的场景。
- 定义纹理在缩放时如何被过滤。常见模式包括:
-
Platform-Specific Settings (Default, iOS, Android):
- 允许你为不同的平台设置不同的纹理参数。每个平台可以有不同的最大纹理尺寸、格式、压缩设置等。这有助于优化不同平台上的性能和内存占用。
-
Format (Automatic):
- 纹理的存储格式,通常你可以将其设置为 "Automatic",让 Unity 为目标平台自动选择最佳格式。可以手动选择特定格式,如 RGB、RGBA 或压缩格式。
-
Compression:
- 纹理压缩质量的设置。选项通常包括:
- None:不压缩,最高质量但占用内存较大。
- Low Quality:高压缩,较低质量,适合不重要的纹理。
- Normal Quality:标准压缩,平衡质量和内存使用。
- High Quality:较低压缩,较高质量。
- 纹理压缩质量的设置。选项通常包括:
-
Use Crunch Compression:
- Crunch 压缩是一种特殊的压缩格式,能大幅减少磁盘空间占用,但加载时间稍长。适合需要减少存储大小的项目。
-
Objects for Packing:
- 这是用于精灵图集(Sprite Atlas)打包的选项。可以将多个精灵添加到列表中,Unity 会将它们打包为一个图集,以减少绘制调用(Draw Calls)并提高性能。
-
Pack Preview:
- 预览打包的效果,查看将如何处理这些纹理。