zh_cn:tutorial:entity
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
zh_cn:tutorial:entity [2019/12/19 10:36] – lightcolour | zh_cn:tutorial:entity [2023/01/15 01:23] (current) – [创建一个实体] solidblock | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== 添加一个实体 | + | ===== 创建一个实体 ===== |
- | ==== 介绍 ==== | + | // |
- | 实体是下一步采取增加一个项目,方后。 | + | 实体(Entity)是游戏世界里的一种可以根据附加的逻辑移动的物体,包括: |
- | 要添加实体,您将需要3个主要类: | + | * 矿车 |
+ | * 箭 | ||
+ | * 船 | ||
+ | |||
+ | 生物实体(Living Entity)是拥有生命值,并且可以造成伤害的实体。 | ||
+ | 为了实现不同的功能,生物实体有着不同的分支类型,其中有: | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | 具体继承、使用哪个取决于你的需求和目的。 | ||
+ | 随着开发进度的推进,对于特定的任务,实体的逻辑变得越来越具体、简明。有以下两种继承自 '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | '' | ||
- | *实体类,为您的生物提供逻辑/ | + | 在这篇教程中,我们将研究创建一个立方体实体,并继承 '' |
- | * Renderer类,它允许您将实体连接到模型 | + | ===== 创建并注册一个实体 ===== |
- | * Model类,这是您的玩家在游戏中看到的 | + | |
- | 我们将创建一个cookie爬虫,当它爆炸时,它将在所有地方启动cookie。 | + | 创建一个继承自 '' |
- | ==== 注册一个实体 | + | |
- | 与积木和物品不同,您基本上总是想要一个完全专用于您的实体的类。 | + | |
- | <code java> | + | <code java [enable_line_numbers=" |
- | public class CookieCreeperEntity | + | /* |
- | | + | * 我们创建的实体继承自 PathAwareEntity, |
+ | * | ||
+ | * LivingEntity 拥有生命值,并且可以造成伤害。 | ||
+ | * MobEntity 具有AI逻辑和移动控制。 | ||
+ | * PathAwareEntity 提供额外的寻路系统,很多AI任务都需要用到寻路。 | ||
+ | */ | ||
+ | public class CubeEntity | ||
+ | | ||
+ | public CubeEntity(EntityType<? | ||
+ | super(entityType, | ||
+ | } | ||
} | } | ||
</ | </ | ||
- | 您的IDE应该指示您创建与超级匹配的构造函数-立即执行此操作。 | ||
- | 要注册您的实体,我们将使用Registry.ENTITY_TYPE。 要获取所需的注册表实例,可以使用EntityType.Builder或FabricEntityTypeBuilder-我们建议使用第二个实例。 | + | 你可以在 '' |
<code java [enable_line_numbers=" | <code java [enable_line_numbers=" | ||
- | public static final EntityType< | + | public class EntityTesting implements ModInitializer { |
- | | + | |
- | | + | /* |
- | new Identifier(" | + | * 使用“entitytesting: |
- | FabricEntityTypeBuilder.create(EntityCategory.AMBIENT, CookieCreeperEntity::new).size(EntityDimensions.fixed(1, 2)).build() | + | * |
+ | * 这个实体注册在了 SpawnGroup# | ||
+ | * 它有一个 0.75 × 0.75(或12个像素宽,即一个方块的3/ | ||
+ | */ | ||
+ | | ||
+ | | ||
+ | new Identifier(" | ||
+ | FabricEntityTypeBuilder.create(SpawnGroup.CREATURE, CubeEntity::new).dimensions(EntityDimensions.fixed(0.75f, 0.75f)).build() | ||
); | ); | ||
+ | | ||
+ | @Override | ||
+ | public void onInitialize() { | ||
+ | | ||
+ | } | ||
+ | } | ||
</ | </ | ||
- | The size() method allows you to set the hitbox of your entity. A creeper is 1 block wide and 2 blocks tall, so we'll use (1, 2). | + | 实体需要// |
- | If you load up your game at this point, you will be able to use /summon to see your creation. If all went right, it should appear as a normal creeper. I would not recommend going into survival. | + | ===== 注册实体的属性 ===== |
- | ==== 创建一个渲染器 ==== | + | **属性**定义了一个生物拥有的基本数值:它有多少生命值?它能造成多少伤害?它有默认的装备栏吗? |
- | 我们的Cookie爬虫自动具有模型,因为它扩展了Creeper类。 | + | 大部分的原版实体都有一个静态方法用于返回它们的属性(比如说 '' |
+ | 我们的自制实体没有任何独立的数值,目前,我们可以直接使用 '' | ||
- | 首先,创建一个MobEntityRenderer类。 MobEntityRenderer具有2个通用类型:实体和模型。 因为我们使用的是Creeper模型,所以我们还必须通过为其指定类型来告诉Creeper模型这不是Creeper实体。 | + | 原版里有一个 |
+ | 想要使用它并不容易,所以Fabric提供一个 '' | ||
+ | 你应该在你的Mod的初始化部分的某处注册默认的属性: | ||
<code java [enable_line_numbers=" | <code java [enable_line_numbers=" | ||
- | public class CookieCreeperRenderer | + | public class EntityTesting implements ModInitializer { |
+ | |||
+ | public static final EntityType< | ||
+ | |||
+ | @Override | ||
+ | public void onInitialize() { | ||
+ | /* | ||
+ | * 注册我们方块实体的默认属性。 | ||
+ | * 属性是一个生物当前状态的数值,其中有攻击伤害和生命值等。 | ||
+ | * 如果实体没有及时注册适当的属性,则游戏将崩溃。 | ||
+ | * | ||
+ | * 在1.15中,它是通过重写实体类内部的方法来完成的。 | ||
+ | * 大部分的原版实体都有一个静态方法(例如, | ||
+ | */ | ||
+ | FabricDefaultAttributeRegistry.register(CUBE, | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== 注册实体的渲染器 ===== | ||
+ | |||
+ | 最后一个需要注册的是实体的**渲染器**。渲染器一般通过提供模型来决定实体的 // | ||
+ | '' | ||
+ | * '' | ||
+ | * '' | ||
+ | * 实体阴影的大小,'' | ||
+ | |||
+ | 下面的代码展示了一个简单的实体渲染器,阴影大小是 0.5f,纹理的路径为 '' | ||
+ | 注意:用到的纹理和模型将在下一步创建。 | ||
+ | |||
+ | <code java [enable_line_numbers=" | ||
+ | /* | ||
+ | * 一个用来提供模型、阴影大小和纹理的渲染器 | ||
+ | */ | ||
+ | public class CubeEntityRenderer | ||
+ | |||
+ | public CubeEntityRenderer(EntityRenderDispatcher entityRenderDispatcher) { | ||
+ | super(entityRenderDispatcher, | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public Identifier getTexture(CubeEntity entity) { | ||
+ | return new Identifier(" | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | 在**客户端初始化类**中使用 '' | ||
+ | <code java [enable_line_numbers=" | ||
+ | @Environment(EnvType.CLIENT) | ||
+ | public class EntityTestingClient implements ClientModInitializer { | ||
+ | |||
+ | @Override | ||
+ | public void onInitializeClient() { | ||
+ | /* | ||
+ | * 方块实体渲染器的注册,提供模型、阴影大小和纹理的渲染器。 | ||
+ | * | ||
+ | * 实体渲染器也可以在实体基于上下文进行渲染前(EndermanEntityRenderer# | ||
+ | */ | ||
+ | EntityRendererRegistry.INSTANCE.register(EntityTesting.CUBE, | ||
+ | return new CubeEntityRenderer(dispatcher); | ||
+ | }); | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== 创建模型和纹理 ===== | ||
+ | |||
+ | 完成实体创建的最后一步是创建模型和纹理。模型定义了实体的// | ||
+ | |||
+ | 标准的模型在类的顶部提供并在构造方法中初始化“部位(parts)”,即 '' | ||
+ | |||
+ | <code java [enable_line_numbers=" | ||
+ | public class CubeEntityModel extends EntityModel< | ||
+ | |||
+ | private final ModelPart base; | ||
+ | |||
+ | public CubeEntityModel(ModelPart modelPart) | ||
+ | base = modelPart.getChild(EntityModelPartNames.CUBE); | ||
+ | } | ||
+ | | ||
[...] | [...] | ||
} | } | ||
</ | </ | ||
- | 您需要重写getTexture方法并添加构造函数。 默认情况下,构造函数具有3个参数(EntityRenderDispatcher,EntityModel,float),但是我们可以删除最后两个参数并自己创建它们: | + | 在创建一个部位之后,我们需要添加一个形状(shape)。为此,我们必须为根部添加一个子形状。新部分的纹理位置在 '' |
- | <code java> | + | <code java [enable_line_numbers=" |
- | public | + | public |
- | { | + | |
- | | + | private final ModelPart base; |
+ | |||
+ | public CubeEntityModel() { | ||
+ | [...] | ||
+ | | ||
+ | |||
+ | // 你可以使用 BlockBench,制作你的模型并为你的实体模型导出以得到这个方法。 | ||
+ | public static TexturedModelData getTexturedModelData() { | ||
+ | ModelData modelData = new ModelData(); | ||
+ | ModelPartData modelPartData = modelData.getRoot(); | ||
+ | modelPartData.addChild(EntityModelPartNames.CUBE, ModelPartBuilder.create().uv(0, | ||
+ | } | ||
} | } | ||
</ | </ | ||
- | |||
- | 对于getTexture方法,您需要返回模型的纹理。 如果为null,则// | ||
- | 默认的实体纹理文件夹约定为:textures/ | + | 我们的实体模型现在有了一个 12x12x12 的方块(大约一个方块的75%),并以0, |
<code java [enable_line_numbers=" | <code java [enable_line_numbers=" | ||
- | @Override | + | public class CubeEntityModel extends EntityModel< |
- | protected Identifier getTexture(CookieCreeperEntity cookieCreeperEntity) | + | |
- | { | + | private final ModelPart base; |
- | | + | |
+ | public CubeEntityModel() [...] | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public void render(MatrixStack matrices, VertexConsumer vertices, int light, int overlay, float red, float green, float blue, float alpha) { | ||
+ | ImmutableList.of(this.base).forEach((modelRenderer) | ||
+ | modelRenderer.render(matrices, | ||
+ | }); | ||
+ | } | ||
} | } | ||
</ | </ | ||
- | 文件存储在resources/ | + | 要完成我们的模型,我们还需要一个纹理文件。默认的纹理大小是64宽、32高的;你可以通过在 '' |
- | 最后,您需要将实体连接到渲染器。 由于渲染仅发生在客户端,因此您应始终在ClientModInitializer中执行以下工作: | + | {{https:// |
- | <code java> | + | |
- | EntityRendererRegistry.INSTANCE.register(CookieCreeperEntity.class, | + | <code java [enable_line_numbers=" |
+ | public class CubeEntityModel extends EntityModel< | ||
+ | |||
+ | private final ModelPart base; | ||
+ | |||
+ | public static TexturedModelData getTexturedModelData() { | ||
+ | [...] | ||
+ | return TexturedModelData.of(modelData, 64, 64); | ||
+ | } | ||
+ | |||
+ | [...] | ||
+ | } | ||
</ | </ | ||
- | 这会将我们的实体链接到我们的新渲染器类。 如果您载入游戏,应该会看到我们的新朋友: | + | ===== 生成你的实体 |
+ | 记得将客户端入口点添加到 fabric.mod.json 中,像这样: | ||
+ | <code json> | ||
- | https://i.imgur.com/8Gfc2sV.jpg | + | " |
+ | " | ||
+ | "mod.fabricmc.entitytesting.EntityTesting" | ||
+ | ], | ||
+ | " | ||
+ | " | ||
+ | ] | ||
+ | }, | ||
+ | </ | ||
- | 如果要使用自己的模型,则可以创建一个扩展EntityModel的新类,并在我们的渲染器中为其交换Creeper模型。 这相当复杂,将在单独的教程中介绍。 | + | 你可以在游戏内使用 |
+ | {{https:// | ||
+ | **注意:**如果你的实体没有继承 '' |
zh_cn/tutorial/entity.1576751768.txt.gz · Last modified: 2019/12/19 10:36 by lightcolour