Table of Contents

教程:编写触发器脚本

初级 设计师

Warning

Bullet Physics is being phased out. We no longer plan to support or expand its features as our focus shifts to Bepu Physics. We recommend transitioning to Bepu Physics for access to the latest updates and ongoing improvements.

在本教程中,我们将创建一个触发器,当球穿过它时将球的大小加倍。

Note

本教程中的截图和视频是使用早期版本的 Stride 制作的,因此某些 UI 部分以及默认的天空盒和球体可能与你的版本看起来不同。

1. 创建弹跳球

按照创建弹跳球教程中的说明操作。这将创建一个简单的场景,球从半空中落下、撞击地面并弹跳。

2. 设置恢复系数

在本教程中,我们将地面和球体的 restitution(恢复系数)都设置为 0.9,这会使球非常有弹性。这使后面更容易看到触发器的效果,因为球会在触发器区域内外反复弹跳。

  1. 选择 Sphere 实体。

  2. 在 Property Grid 中,在 Rigidbody 下将 Restitution 设置为 0.9。

    设置球体的恢复系数

  3. 选择 Ground 实体。

  4. 在 Property Grid 中,在 Static Collider 下将 Restitution 设置为 0.9。

    设置地面的恢复系数

3. 添加触发器

现在我们将在球和地面之间添加一个触发器,让球穿过它。

  1. 在 Scene Editor 中,点击白色加号按钮(创建新实体)并选择 Empty entity。

    创建新实体

    Game Studio 会向场景中添加一个默认名称为 Entity 的实体。

  2. 这个实体将作为我们的触发器,因此将它重命名为 Trigger,以便于识别。

  3. 由于我们不需要触发器移动,我们将把它设为静态碰撞体。在 Property Grid 中,点击 Add component 并选择 Static Collider。

    添加静态碰撞体组件

  4. 在 Property Grid 中,展开 Static Collider component 以查看其属性。

  5. 勾选 Is Trigger 复选框。

    勾选 'Is trigger'

    这会把碰撞体变成触发器。这意味着对象可以穿过它,但仍然能在代码中检测到。

  6. 我们需要给触发器一个形状。在 Collider Shapes 旁边,点击 绿色加号按钮(添加)并选择 Box。

    添加碰撞体形状

    这会为触发器赋予一个盒体形状。

    已添加的触发器

  7. 我们把触发器做成一个更大的区域。在 Property Grid 中,在 Transform 组件属性下,将 scale 设置为:X:2, Y:2, Z:2

    缩放触发器

    这会把触发器的大小加倍。

    已添加的触发器

4. 为触发器添加模型

目前,触发器在运行时是不可见的。为了更好地展示触发器的工作原理,我们将把它做成一个透明的盒体。这对触发器的功能没有任何影响;这只是意味着我们可以轻松地看到它在运行时的位置。

  1. 创建一个新的程序化模型资源。为此,在 Asset View 中点击 Add asset,并选择 Models > Cube。

    添加模型资源

  2. 创建一个新的空材质资源。为此,在 Asset View 中点击 Add asset,并选择 Materials > Material。

    添加材质资源

  3. 我们重命名材质以便于识别。为此,右键单击,选择 Rename,并输入一个新名称(例如 Transparent)。

  4. 选择 Trigger 实体。在 Property Grid 中,点击 Add component 并选择 Model。

    添加模型组件

    Game Studio 会为实体添加一个模型组件。

  5. 在 Model 下,点击 手形图标(选择资源)。

    拾取资源

  6. 选择我们在步骤 1 中创建的 Cube 模型并点击 OK。

    选择 Cube 模型

  7. 在 Property Grid 中,在 Model > Materials 下,点击 手形图标(选择资源)。

    选择材质

  8. 选择我们在步骤 2 中创建的 Transparent 材质并点击 OK。

    选择材质

  9. 在 Asset View 中,选择 Transparent 材质资源。

    在 Asset View 中选择材质

  10. 在 Property Grid 中,在 Misc > Transparency 下选择 Blend。

    选择 Blend

  11. 默认情况下,Alpha 设置为 1。这使材质完全不透明。要将其设置为 50% 不透明度,请将 Alpha 设为 0.5。

    选择 Blend

    现在触发器区域在运行时将可见。

5. 放置触发器的位置

我们需要把触发器放在地面和球体之间,这样球才能从它中间落下。

在 Property Grid 中,在 Transform 下将 Position 设置为:X:0, Y:3, Z:0

现在触发器实体位于地面和球体之间:

位于地面和球体之间的触发器

6. 用脚本改变球的大小

如果我们现在运行项目(F5),球会从触发器中落下,但什么也不会发生。

让我们编写一个脚本,在球进入触发器时改变它的大小。

Note

有关脚本的更多信息,请参见脚本。

  1. 在 Asset View 中,点击 Add asset 并选择 Scripts > Async Script。

    使用脚本

  2. 在 Create a script 对话框中,将脚本命名为 Trigger 并点击 Create script。

    2a. 如果 Game Studio 询问是否要保存脚本,请点击 Save。

    2b. 如果 Game Studio 询问是否要重新加载程序集,请点击 Reload。

  3. 打开脚本,将其内容替换为以下代码,并保存文件:

    using Stride.Engine;
    using Stride.Physics;
    using System.Threading.Tasks;
    using Stride.Core.Mathematics;
    
    namespace TransformTrigger
    // 你可以为这个脚本使用任何你喜欢的命名空间。
    {
        public class Trigger : AsyncScript
        {
            public override async Task Execute()
            {
                var trigger = Entity.Get<PhysicsComponent>();
                trigger.ProcessCollisions = true;
    
                // 启动状态机
                while (Game.IsRunning)
                {
                    // 1. 等待某个实体与触发器碰撞
                    var firstCollision = await trigger.NewCollision();
    
                    var otherCollider = trigger == firstCollision.ColliderA
                        ? firstCollision.ColliderB
                        : firstCollision.ColliderA;
                    otherCollider.Entity.Transform.Scale = new Vector3(2.0f, 2.0f, 2.0f);
    
                    // 2. 等待该实体离开触发器
                    await firstCollision.Ended();
    
                    otherCollider.Entity.Transform.Scale= new Vector3(1.0f, 1.0f, 1.0f);
                }
            }
        }
    }
    

    这段代码会将任何进入触发器的实体的大小(缩放)加倍。当实体离开触发器时,它会恢复原来的大小。

  4. 重新加载程序集。

7. 添加脚本

最后,让我们把这个脚本作为组件添加到触发器实体上。

  1. 在 Game Studio 中,选择 Trigger 实体。

  2. 在 Property Grid 中,点击 Add component 并选择 Trigger 脚本。

    为实体添加脚本组件

8. 运行项目

运行项目(F5)查看触发器的实际效果。

球穿过触发器,大小加倍,离开触发器后恢复原来的大小。

更多创意

你可以修改脚本,让球体进入触发器时做出其他改变。

例如,你可以切换球体实体上的材质。这个脚本会将 Sphere 实体上的材质从 Sphere Material 切换到 Ground Material,然后再切换回来:

using Stride.Engine;
using Stride.Physics;
using System.Threading.Tasks;
using Stride.Core.Mathematics;
using Stride.Rendering;

namespace TransformTrigger
// 你可以为这个脚本使用任何你喜欢的命名空间。
{
    public class Trigger : AsyncScript
    {
        private Material material1;
        private Material material2;
    
        public override async Task Execute()
        {
            var trigger = Entity.Get<PhysicsComponent>();
            trigger.ProcessCollisions = true;
            
            // 确保材质已加载 
            material1 = Content.Load<Material>("Sphere Material");
            material2 = Content.Load<Material>("Ground Material");

            // 启动状态机
            while (Game.IsRunning)
            {
                // 1. 等待某个实体与触发器碰撞
                var firstCollision = await trigger.NewCollision();

                var otherCollider = trigger == firstCollision.ColliderA
                    ? firstCollision.ColliderB
                    : firstCollision.ColliderA;
                    
                // 2. 更改实体上的材质
                otherCollider.Entity.Get<ModelComponent>().Materials[0] = material2;
                
                // 3. 等待该实体离开触发器
                await firstCollision.Ended();

                // 4. 将材质改回原来的
                otherCollider.Entity.Get<ModelComponent>().Materials[0] = material1;
            }
        }
        
        public override void Cancel()
        {
            Content.Unload(material1);
            Content.Unload(material2);
        }
    }
}

另请参阅