## 太空工程师编程笔记2 - 获取和控制其他块
### 游戏中的块对象
游戏中,我们会用到各种块,从大小上直观分为大船块和小船块。
在游戏内部的表示,其实是一些不同的具有继承关系的类,然后各类具体的块是子类。
常见的继承关系为:
IMyEntity->IMyCubeBlock->IMyTerminalBlock->IMyFunctionalBlock->具体的块类
但也可能并不继承某些接口,比如装甲块就只继承到IMyCubeBlock,具体继承关系要看具体定义。
游戏内编程对块操作基本上是获取继承了这些接口的块,然后通过接口对块进行操作。
#### 具体块继承的基本接口
IMyEntity是游戏世界中的实体,比如块、陨石、导弹等等都可以算是实体,这个接口比较底层,贴近游戏引擎。利用这个接口可以得到块的基础信息。
~~~csharp
public interface IMyEntity
{
// Methods
IMyInventory GetInventory();
IMyInventory GetInventory(int index);
Vector3D GetPosition();
// Properties
MyEntityComponentContainer Components { get; }
long EntityId { get; }
string Name { get; }
string DisplayName { get; }
bool HasInventory { get; }
int InventoryCount { get; }
BoundingBoxD WorldAABB { get; }
BoundingBoxD WorldAABBHr { get; }
MatrixD WorldMatrix { get; }
BoundingSphereD WorldVolume { get; }
BoundingSphereD WorldVolumeHr { get; }
}
~~~
IMyCubeBlock是方块,各类方块,包括装甲块在内,都属于IMyCubeBlock。利用这个接口可以得到块的各类状态信息。
~~~csharp
public interface IMyCubeBlock : IMyEntity
{
// Methods
string GetOwnerFactionTag();
[Obsolete("GetPlayerRelationToOwner() is useless ingame. Mods should use the one in ModAPI.IMyCubeBlock")]
MyRelationsBetweenPlayerAndBlock GetPlayerRelationToOwner();
MyRelationsBetweenPlayerAndBlock GetUserRelationToOwner(long playerId);
[Obsolete]
void UpdateIsWorking();
[Obsolete]
void UpdateVisual();
// Properties
SerializableDefinitionId BlockDefinition { get; }
bool CheckConnectionAllowed { get; }
IMyCubeGrid CubeGrid { get; }
string DefinitionDisplayNameText { get; }
float DisassembleRatio { get; }
string DisplayNameText { get; }
bool IsBeingHacked { get; }
bool IsFunctional { get; }
bool IsWorking { get; }
Vector3I Max { get; }
float Mass { get; }
Vector3I Min { get; }
int NumberInGrid { get; }
MyBlockOrientation Orientation { get; }
long OwnerId { get; }
Vector3I Position { get; }
}
~~~
IMyTerminalBlock是终端方块,即在终端界面有界面的,能进行互动。可以操纵名字一类的信息,并且可以利用编程块互动。
~~~csharp
public interface IMyTerminalBlock : IMyCubeBlock, IMyEntity
{
// Methods
void GetActions(List<ITerminalAction> resultList, Func<ITerminalAction, bool> collect = null);
ITerminalAction GetActionWithName(string name);
void GetProperties(List<ITerminalProperty> resultList, Func<ITerminalProperty, bool> collect = null);
ITerminalProperty GetProperty(string id);
bool HasLocalPlayerAccess();
bool HasPlayerAccess(long playerId);
void SearchActionsOfName(string name, List<ITerminalAction> resultList, Func<ITerminalAction, bool> collect = null);
[Obsolete("Use the setter of Customname")]
void SetCustomName(string text);
[Obsolete("Use the setter of Customname")]
void SetCustomName(StringBuilder text);
// Properties
string CustomName { get; set; }
string CustomNameWithFaction { get; }
string DetailedInfo { get; }
string CustomInfo { get; }
string CustomData { get; set; }
bool ShowOnHUD { get; set; }
bool ShowInTerminal { get; set; }
bool ShowInToolbarConfig { get; set; }
bool ShowInInventory { get; set; }
}
~~~
IMyFunctionalBlock是功能方块,简单来说就是能开关的方块。可以用代码开关。
~~~csharp
public interface IMyFunctionalBlock : IMyTerminalBlock, IMyCubeBlock, IMyEntity
{
// Methods
[Obsolete("Use the setter of Enabled")]
void RequestEnable(bool enable);
// Properties
bool Enabled { get; set; }
}
~~~
#### 具体块
游戏中有数十种块,对应不同的类。
编程块可操作的列表如下:
~~~csharp
public interface IMyAdvancedDoor : IMyDoor, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyAirtightDoorBase : IMyDoor, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyAirtightHangarDoor : IMyAirtightDoorBase, IMyDoor, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyAirtightSlideDoor : IMyAirtightDoorBase, IMyDoor, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyAssembler : IMyProductionBlock, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyAttachableTopBlock : IMyCubeBlock, IMyEntity
public interface IMyBatteryBlock : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyBeacon : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyBlockGroup
public interface IMyCameraBlock : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyCargoContainer : IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyCockpit : IMyShipController, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyCollector : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyConveyor : IMyCubeBlock, IMyEntity
public interface IMyConveyorSorter : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyConveyorTube : IMyCubeBlock, IMyEntity
public interface IMyCryoChamber : IMyCockpit, IMyShipController, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyDecoy : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyDoor : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyExtendedPistonBase : IMyPistonBase, IMyMechanicalConnectionBlock, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyFunctionalBlock : IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyGasGenerator : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyGasTank : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyGridProgramRuntimeInfo
public interface IMyGridTerminalSystem
public interface IMyGyro : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyJumpDrive : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyLargeTurretBase : IMyUserControllableGun, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyLaserAntenna : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyLightingBlock : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyMechanicalConnectionBlock : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyMotorAdvancedRotor : IMyMotorRotor, IMyAttachableTopBlock, IMyCubeBlock, IMyEntity
public interface IMyMotorAdvancedStator : IMyMotorStator, IMyMotorBase, IMyMechanicalConnectionBlock, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyMotorBase : IMyMechanicalConnectionBlock, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyMotorRotor : IMyAttachableTopBlock, IMyCubeBlock, IMyEntity
public interface IMyMotorStator : IMyMotorBase, IMyMechanicalConnectionBlock, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyMotorSuspension : IMyMotorBase, IMyMechanicalConnectionBlock, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyOreDetector : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
[Obsolete("Use IMyGasGenerator")]
public interface IMyOxygenGenerator : IMyGasGenerator, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
[Obsolete("Use IMyGasTank")]
public interface IMyOxygenTank : IMyGasTank, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyPassage : IMyCubeBlock, IMyEntity
public interface IMyPistonBase : IMyMechanicalConnectionBlock, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyPistonTop : IMyAttachableTopBlock, IMyCubeBlock, IMyEntity
public interface IMyProductionBlock : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyProgrammableBlock : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyProjector : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyRadioAntenna : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyReactor : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyRefinery : IMyProductionBlock, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyReflectorLight : IMyLightingBlock, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyRemoteControl : IMyShipController, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMySensorBlock : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyShipConnector : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyShipController : IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyShipDrill : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyShipGrinder : IMyShipToolBase, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyShipToolBase : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyShipWelder : IMyShipToolBase, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMySmallGatlingGun : IMyUserControllableGun, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMySmallMissileLauncher : IMyUserControllableGun, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMySmallMissileLauncherReload : IMySmallMissileLauncher, IMyUserControllableGun, IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyTerminalBlock : IMyCubeBlock, IMyEntity
public interface IMyTextPanel : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyThrust : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyUpgradableBlock : IMyCubeBlock, IMyEntity
public interface IMyUpgradeModule : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyUserControllableGun : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyWarhead : IMyTerminalBlock, IMyCubeBlock, IMyEntity
public interface IMyWheel : IMyMotorRotor, IMyAttachableTopBlock, IMyCubeBlock, IMyEntity
~~~
这些具体块也会有一定继承关系,比如说组装机和精炼厂都继承自IMyProductionBlock,利用这个接口可以控制生产。
~~~csharp
public interface IMyProductionBlock : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
{
// Methods
void AddQueueItem(MyDefinitionId blueprint, decimal amount);
void AddQueueItem(MyDefinitionId blueprint, double amount);
void AddQueueItem(MyDefinitionId blueprint, MyFixedPoint amount);
bool CanUseBlueprint(MyDefinitionId blueprint);
void ClearQueue();
void GetQueue(List<MyProductionItem> items);
void InsertQueueItem(int idx, MyDefinitionId blueprint, decimal amount);
void InsertQueueItem(int idx, MyDefinitionId blueprint, double amount);
void InsertQueueItem(int idx, MyDefinitionId blueprint, MyFixedPoint amount);
void MoveQueueItemRequest(uint queueItemId, int targetIdx);
void RemoveQueueItem(int idx, decimal amount);
void RemoveQueueItem(int idx, double amount);
void RemoveQueueItem(int idx, MyFixedPoint amount);
// Properties
IMyInventory InputInventory { get; }
IMyInventory OutputInventory { get; }
bool IsProducing { get; }
bool IsQueueEmpty { get; }
uint NextItemId { get; }
bool UseConveyorSystem { get; set; }
}
~~~
### 获取和操作块
获取块主要是通过编程块中GridTerminalSystem对象来进行。
**获取块**
~~~csharp
int tick=0;
public Program()
{
// The constructor, called only once every session and
// always before any other method is called. Use it to
// initialize your script.
//
// The constructor is optional and can be removed if not
// needed.
//
// It's recommended to set RuntimeInfo.UpdateFrequency
// here, which will allow your script to run itself without a
// timer block.
Runtime.UpdateFrequency = UpdateFrequency.Update1;
}
public void Main(string argument, UpdateType updateSource)
{
// The main entry point of the script, invoked every time
// one of the programmable block's Run actions are invoked,
// or the script updates itself. The updateSource argument
// describes where the update came from.
//
// The method itself is required, but the arguments above
// can be removed if not needed.
Echo("Running "+tick++);
//第一种获取方式
IMyTerminalBlock block=(IMyTerminalBlock)GridTerminalSystem.GetBlockWithName("testBlock");
if(block!=null)Echo("GetBlockWithName: "+block.ToString());
//第二种获取方式
List<IMyBatteryBlock> blocks=new List<IMyBatteryBlock>();
GridTerminalSystem.GetBlocksOfType<IMyBatteryBlock>(blocks);
if(blocks.Count>0){
Echo("GetBlocksOfType: "+blocks[0].ToString());
//获取电池块的状态
Echo("电池是否处于单工模式:"+blocks[0].SemiautoEnabled);
}
}
~~~
**执行结果**
将电池命名为“testBlock”后,终端显示当前运行次数和两个电池ToString信息
MyBatteryBlock{块id}testBlock
说明两种方式均成功获取到电池块。
同时,能够显示电池的属性。
**本次使用功能**
GridTerminalSystem
~~~csharp
public interface IMyGridTerminalSystem
{
// Methods
void GetBlockGroups(List<IMyBlockGroup> blockGroups, Func<IMyBlockGroup, bool> collect = null);
IMyBlockGroup GetBlockGroupWithName(string name);
void GetBlocks(List<IMyTerminalBlock> blocks);
void GetBlocksOfType<T>(List<IMyTerminalBlock> blocks, Func<IMyTerminalBlock, bool> collect = null) where T: class;
void GetBlocksOfType<T>(List<T> blocks, Func<T, bool> collect = null) where T: class;
IMyTerminalBlock GetBlockWithId(long id);
IMyTerminalBlock GetBlockWithName(string name);
void SearchBlocksOfName(string name, List<IMyTerminalBlock> blocks, Func<IMyTerminalBlock, bool> collect = null);
}
~~~
电池块
~~~csharp
public interface IMyBatteryBlock : IMyFunctionalBlock, IMyTerminalBlock, IMyCubeBlock, IMyEntity
{
// Properties
bool HasCapacityRemaining { get; }
float CurrentStoredPower { get; }
float MaxStoredPower { get; }
float CurrentInput { get; }
float MaxInput { get; }
float CurrentOutput { get; }
float MaxOutput { get; }
bool IsCharging { get; }
bool OnlyRecharge { get; set; }
bool OnlyDischarge { get; set; }
bool SemiautoEnabled { get; set; }
}
~~~
#### 对块进行操作
对块进行操作有两种方式,一种是直接调用或赋值,另一种是“动作”。
**先来看动作**
~~~csharp
public void Main(string argument, UpdateType updateSource)
{
//先获取块
IMyTerminalBlock block=(IMyTerminalBlock)GridTerminalSystem.GetBlockWithName("testBlock");
if(block!=null)Echo("GetBlockWithName: "+block.ToString());
//获取该块可以进行的动作
List<ITerminalAction> resultList=new List<ITerminalAction>();
block.GetActions(resultList);
//在终端输出
Echo("testBlock可进行的动作如下:");
foreach (var item in resultList)
{
Echo(item.Id+" -> "+item.Name.ToString());
}
}
~~~
**执行结果**
按下run之后,打印了电池可进行的动作,如下:
~~~
OnOff -> Toggle block On/Off
OnOff_On -> Toggle block On
OnOff_Off -> Toggle block Off
Recharge -> Recharge On/Off
Discharge -> Discharge On/Off
SemiAuto -> Semi-auto On/Off
~~~
各块具体动作有哪些可参考https://spaceengineerswiki.com/Programming_Guide/Action_List
**执行动作**
~~~csharp
public void Main(string argument, UpdateType updateSource)
{
//先获取块
IMyTerminalBlock block=(IMyTerminalBlock)GridTerminalSystem.GetBlockWithName("testBlock");
if(block!=null)Echo("GetBlockWithName: "+block.ToString());
//获取该块可以进行的动作(这里采用第二种方法)
//List<ITerminalAction> resultList=new List<ITerminalAction>();
//block.GetActions(resultList);
ITerminalAction action=block.GetActionWithName("SemiAuto");
action.Apply(block);
}
~~~
**执行结果**
每点击一次run,电池的单双工状态就被切换一次。
- 序言
- 写在前面的话
- 太空工程师
- MEA小组
- 一、入门
- 1.1 基础概念
- 1.2 编程工具
- 1.3 变量
- 1.4 函数 Function
- 1.5 基本语法
- 1.5.1 运算符
- 1.5.2 if
- 1.5.3 for
- 1.5.4 其他语法
- 1.3 类 Class
- 二、编程块
- 2.1 方块的概念
- 2.2 List<T>结构
- 2.3 获取方块
- 2.4 方块的使用
- 三、Ship 类
- 3.1 简介
- Ship v0.5
- 代码
- 手册(待更新)
- 例子(待更新)
- Ship v1.0
- 代码
- 例子
- 文档
- 实例化
- 内置变量
- 内置方法
- Target类
- 四、运动控制算法在SE中的应用
- 4.1 运动控制介绍
- 4.2 过程控制
- 4.3 震荡和动态误差
- 4.4 误差累加方案
- 4.5 PID算法
- 4.6 对PID算法的一点点简化
- 4.7 一阶惯性系统的PID算法优化的研究
- 五、MEA方块类
- 5.0 核心代码目录
- v1.0核心代码
- v1.1 核心代码
- v2.0 核心代码
- 5.1 类的概念
- 5.2 MEA的方块类(Block)
- 5.3 方块类文档
- 5.4 方块类2.0 全教程
- 5.4.1 安装和使用
- 5.4.2 方块类(Block)
- 5.4.3 显示屏类(DisplayScreen)
- 5.4.4 LCD类(LCD)
- 5.4.5 主控座椅类(Cockpit)
- 六、疯猴的编程笔记
- 第一个程序
- 获取和控制其他块
- 物流与生产
- 界面与通信
- 运动与姿态
- 侦测与导航
- 七、SteamZhou的笔记
- 有趣而花里胡哨的IDEA
- 八、质子对撞炮的笔记
- 属性 Property
- 接口 interface