自由学习记录(11)

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 中,单独的 BoxCollider2DCircleCollider2DPolygonCollider2D 等通常是实心的,它们没有类似的设置来直接生成"空心"的效果。只有复合碰撞器 通过组合其他碰撞器(如 BoxCollider2D、PolygonCollider2D)并设置 Geometry Type 才能创建空心的几何结构。

实现空心碰撞器的步骤:

  1. 给对象添加多个基础碰撞器,比如 BoxCollider2DPolygonCollider2D
  2. 添加 Composite Collider 2D 组件,Unity 会自动将这些基础碰撞器组合成一个整体。
  3. Composite Collider 2D 中,将 Geometry Type 设置为 Outlines,这样碰撞器只在边缘生效,内部将是空心的。

这样就可以模拟出一个空心的物体,其他物体可以在它内部自由移动,只有当它们接触到外边的轮廓时才会发生碰撞。

Trigger

物理材质

所有 2D 碰撞器 都可以通过设置 isTrigger 属性来控制它们是作为实心的物理碰撞体,还是仅作为触发器使用。无论是复合碰撞器还是单独的碰撞器组件,这个属性的行为是相同的。

isTrigger 属性

  • 实心碰撞器

    isTriggerfalse 时,碰撞器会作为物理碰撞体处理,物体会在碰撞时产生反弹、阻挡等物理效果。

  • 触发器 (Trigger)

    isTriggertrue 时,碰撞器会变成一个触发器。触发器不会产生物理碰撞效果,物体可以穿过它,但会触发 OnTriggerEnter2DOnTriggerStay2DOnTriggerExit2D 等事件。

在复合碰撞器中的行为

  • 如果你在一个对象上组合了多个碰撞器,比如 BoxCollider2DCircleCollider2D,你可以单独为每个碰撞器设置 isTrigger。这样,某些碰撞器可以作为触发器,而其他的保持实心。

    BoxCollider2D box = gameObject.AddComponent<BoxCollider2D>();

  • CircleCollider2D circle = gameObject.AddComponent<CircleCollider2D>(); box.isTrigger = false; // 实心碰撞器

  • circle.isTrigger = true; // 触发器

  • 复合碰撞器是否支持实心/触发器的混合

    如果你在一个对象上复合多个碰撞器,其中有些碰撞器是实心的,有些是触发器,它们的行为会独立存在。触发器的部分仍然只会触发事件,而实心部分会处理物理碰撞。

碰撞器

碰撞检测函数

trigger也是一样的

2D 碰撞器 不仅限于 CircleCollider2DBoxCollider2D。你可以使用多种不同类型的 2D 碰撞器,而且可以将多个碰撞器组件组合在一起,从而创建更复杂的碰撞区域

常见的 2D 碰撞器类型:

  1. CircleCollider2D
    • 一个圆形的 2D 碰撞器,适用于圆形或球状的物体。
  2. BoxCollider2D
    • 一个矩形的 2D 碰撞器,适用于长方形或正方形的物体。
  3. PolygonCollider2D
    • 可以定义任意形状的多边形碰撞器,通过多个顶点连接来形成复杂的轮廓。适用于非规则形状的物体。
  4. EdgeCollider2D
    • 由一系列线段组成的碰撞器,不会包围任何区域,适用于地形或平台边缘。
  5. CapsuleCollider2D
    • 胶囊形的碰撞器,适用于长条状带有圆头的物体,比如角色碰撞体。

复合碰撞器的概念

复合碰撞器 是指将多个简单的碰撞器(如 Circle、Box 等)组合在同一个对象上,以模拟一个更复杂的形状。例如,你可以将多个 BoxCollider2DCircleCollider2D 组合在一个物体上来准确包围其形状。

  • 通过添加多个碰撞器组件

    • 你可以在同一个 GameObject 上添加多个不同的碰撞器组件,比如同时添加 BoxCollider2DCircleCollider2D。这样,物体在碰撞时会按照这些碰撞器的组合形状来检测。

    gameObject.AddComponent<BoxCollider2D>(); gameObject.AddComponent<CircleCollider2D>();

  • 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) });

使用多个碰撞器的优点

  • 更精确的碰撞检测

    对于非规则形状的对象,单一的 BoxCollider2DCircleCollider2D 可能无法精确模拟其边界。通过组合多个碰撞器,你可以更准确地定义物体的形状,减少不必要的物理计算或碰撞失误。

  • 优化性能

    复合多个简单的碰撞器有时比使用一个复杂的 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)

    如果 isKinematictrue,则刚体不再受物理引擎的控制(不受重力、碰撞等影响),而由脚本控制它的运动。

    rb.isKinematic = true; // 将刚体设置为运动学刚体

  • interpolation (RigidbodyInterpolation2D)

    控制刚体在物理帧之间的插值方式。可以选择 NoneInterpolateExtrapolate。这是为了在帧率不稳定的情况下平滑显示物体的运动。

    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)

    手动将刚体移动到一个新位置。如果 isKinematictrue,可以使用此方法直接控制刚体位置。

    rb.MovePosition(new Vector2(3, 5)); // 将刚体移动到 (3, 5) 位置

  • MoveRotation(float angle)

    手动将刚体旋转到一个新的角度(以度为单位)。适用于 isKinematictrue 的刚体。

    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 选项解释

Rigidbody2DInterpolate 属性有以下三个选项:

  1. None(默认值):

    • 没有插值,也就是说物体的运动只会在每一帧物理计算后更新。这意味着物体的运动会非常"生硬",尤其是在帧率波动较大的情况下,物体的运动可能显得不连贯或卡顿。
    • 如果你的游戏物理运算足够快,且帧率稳定,这种方式是性能最高的。
  2. Interpolate

    • Unity 会基于前一帧的物理位置和平滑插值来推测物体当前帧的渲染位置,使物体看起来运动更加平滑。它通过插值的方式,计算出一个基于当前帧时间的中间位置。
    • 适合当物理更新频率较低,或者帧率不稳定的情况。插值会让视觉效果更流畅。
  3. 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

    • 预览打包的效果,查看将如何处理这些纹理。

Java多线程

相关推荐
西岸行者2 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意2 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码2 天前
嵌入式学习路线
学习
毛小茛2 天前
计算机系统概论——校验码
学习
babe小鑫2 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms2 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下2 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。2 天前
2026.2.25监控学习
学习
im_AMBER2 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J2 天前
从“Hello World“ 开始 C++
c语言·c++·学习