执行方块功能

注:示例代码以可读性为主。实际在游戏中运行前,请在可编程方块中测试并根据方块名称与本地化动作名做调整。

概述

执行方块功能大致可以分为以下两类:

  • 通过对象直接调用具体功能
  • 通过动作名执行功能

基本概念

  • 强类型接口:许多方块在脚本 API 中有专门接口,例如 IMyDoorIMyLightingBlock 等,可以访问特定属性(如门的 Status)并使用通用终端动作执行操作。
  • 终端动作(Terminal Action):大多数方块支持通过动作名执行命令,使用 ApplyAction(string actionName) 或先通过 GetActionWithName 获取 IMyTerminalActionApply
  • API查询:上述所说的所有接口和动作都可以通过 F12 快捷键反编译查询

常用模式

  • 安全检查:在使用前始终检查 nullIsFunctional/IsWorkingEnabled
  • 动作名可能受本地化影响(不同语言下可能不同),建议在游戏内调试时记录/确认动作名。

通过对象直接调用具体功能

示例 1 — 读取门状态并切换开关门

IMyDoor myDoor; // 定义一个IMyDoor接口类型的门成员变量

public Program()
{
    // 这里是 构造函数
    Runtime.UpdateFrequency = UpdateFrequency.None; // 设置 Main函数 的触发频率为 None —— 不会自动触发
    myDoor = GridTerminalSystem.GetBlockWithName("门") as IMyDoor; // 获取一个叫 门 的方块,并将它的类型转为 IMyDoor
}

public void Main(string argument, UpdateType updateSource)
{
    // 这里是 主函数

    // 首先检查我们是否成功获取了门的方块
    if (myDoor == null)
    {
        Echo("未找到门方块!");
        return;
    }

    // 使用门的状态判断并触发动作
    if (myDoor.Status == DoorStatus.Open || myDoor.Status == DoorStatus.Opening)
    {
        // 关闭门
        myDoor.CloseDoor();
    }
    else
    {
        // 打开门
        myDoor.OpenDoor();
    }

    Echo($"当前门的状态是:{myDoor.Status}"); // 输出我们获取方块的当前状态
}

public void Save()
{
    // 这里是 保存函数
}

通过动作名执行功能

示例 1 — 读取门状态并切换开关门(使用通用动作名)

IMyDoor myDoor;

public Program()
{
    myDoor = GridTerminalSystem.GetBlockWithName("门") as IMyDoor;
}

public void Main(string argument, UpdateType updateSource)
{
    if (myDoor == null) return;

    // 使用门的状态判断并触发动作
    if (myDoor.Status == DoorStatus.Open || myDoor.Status == DoorStatus.Opening)
    {
        // 尝试关闭门(动作名示例,视游戏版本/语言可能不同)
        myDoor.ApplyAction("Open_Off");
    }
    else
    {
        // 尝试打开门
        myDoor.ApplyAction("Open_On");
    }
}

示例 2 — 开/关灯(使用通用动作名)

IMyLightingBlock light;

public Program()
{
    light = GridTerminalSystem.GetBlockWithName("主灯") as IMyLightingBlock;
}

void TurnOnLight()
{
    if (light == null) return;
    // 常见动作名:OnOff_On / OnOff_Off / OnOff_Toggle
    light.ApplyAction("OnOff_On");
}

void ToggleLight()
{
    if (light == null) return;
    light.ApplyAction("OnOff_Toggle");
}

示例 3 — 通过 GetActionWithName 应用动作

public void ApplyActionByName(IMyTerminalBlock block, string actionName)
{
    if (block == null) return;
    var action = block.GetActionWithName(actionName); // 获取动作
    if (action != null)
    {
        action.Apply(block);
    }
}

// 调用举例
// ApplyActionByName(myDoor as IMyTerminalBlock, "Open_On");

查找可用的动作名

  • 在 PC 端游戏的控制面板/终端中查看方块操作名称。
  • 在脚本里使用 Echo 输出以确认方块引用是否正确:
Echo($"门对象: {myDoor}");
Echo($"门状态: {myDoor?.Status}");

注意事项与最佳实践

  • 先检测 null,再调用 ApplyAction
  • 有些方块提供了更直观的 API(例如 IMyDoor 的状态属性),优先使用强类型接口读取状态。
  • 动作名在不同游戏版本或语言下可能不同,推荐在目标世界中测试并记录正确的动作名。
  • 避免在高频率的 Main 中频繁触发可能造成性能或重复触发问题,使用状态检查以降低重复调用。

小结

  • 使用 ApplyAction/GetActionWithName 可以通用地触发方块行为;强类型接口用于读取/判断状态。
  • 始终做好 null / IsFunctional 检查,并在游戏中测试动作名的正确性。