User Tools

Site Tools


zh_cn:tutorial:entity

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
zh_cn:tutorial:entity [2019/12/19 10:36] lightcolourzh_cn:tutorial:entity [2023/01/15 01:23] (current) – [创建一个实体] solidblock
Line 1: Line 1:
-====== 添加一个实体 ======+===== 创建一个实体 =====
  
-==== 介绍 ====+//本文的源码托管于 [[https://github.com/Draylar/entity-testing|这个仓库]] 的 entity 分支.//
  
-实体是步采取增,方后。 +实体(Entity)游戏世界里的种可以根据附的逻辑移动的物体,包括: 
-要添加实体,您将需要3个主要类:+  * 矿车 
 +  * 箭 
 +  * 船 
 +  
 +生物实体(Living Entity)是拥有生命值,并且可以造成伤害的实体。 
 +为了实现不同的功能,生物实体有着不同的分支类型,其中有: 
 +  * ''HostileEntity'' 敌对实体,用于僵尸、苦力怕、骷髅等 
 +  * ''AnimalEntity'' 动物实体,用于羊、牛、猪等 
 +  * ''WaterCreatureEntity'' 水生物实体,用于可以游泳的实体 
 +  * ''FishEntity'' 鱼实体,用于鱼 
 +  
 +具体继承、使用哪取决于你的需求和。 
 +随着开发进度的推进,对于特定的任务,实体的逻辑变得越来越具体、简明。有以下两种继承自 ''LivingEntity'' 的实体: 
 +  * ''MobEntity'' 
 +  * ''PathAwareEntity'' 
 +  
 +''MobEntity'' 具有AI逻辑和移动控制。 ''PathAwareEntity'' 提供额外的寻路系统很多AI任务都需要用到寻路。
  
-   *实体为您的生物提供逻辑/ AI +在这篇教程中,我们将研究创建一个立方体实体,并继承 ''PathAwareEntity'' . 这个实体将拥有模型和纹理。移动和物理机制将会以后教程中介绍。 
-   * Renderer类,它允许您将实体连接到模型 +===== 创建并注册一个实体 =====
-   * Model类,这是您的玩家游戏中看到+
  
-我们将创建一个cookie爬虫当它爆炸时,它将在所有地方启动cookie。 +创建一个继承自 ''PathAwareEntity'' 的类类是我们创建的实体的大脑和主体
-==== 注册一个实体 ====+
  
-与积木和物品不同,您基本上总是想要一个完全专用于您的实体的类。 我们正在创建爬虫克隆,因此将使我们的实体类扩展CreeperEntity: + 
-<code java> +<code java [enable_line_numbers="true"]> 
-public class CookieCreeperEntity extends CreeperEntity +/* 
-    [...]+    * 我们创建的实体继承自 PathAwareEntity, 它继承自 MobEntity, 而 MobEntity 继承自 LivingEntity. 
 +    * 
 +    * LivingEntity 拥有生命值,并且可以造成伤害。 
 +    * MobEntity 具有AI逻辑和移动控制。 
 +    * PathAwareEntity 提供额外的寻路系统,很多AI任务都需要用到寻路。 
 +    */ 
 +public class CubeEntity extends PathAwareEntity 
 +     
 +    public CubeEntity(EntityType<? extends PathAwareEntity> entityType, World world) { 
 +        super(entityType, world); 
 +    }
 } }
 </code> </code>
-您的IDE应该指示您创建与超级匹配的构造函数-立即执行此操作。 
  
-注册您的实体,我们将使用Registry.ENTITY_TYPE。 要获取所需的注册可以使用EntityType.Builder或FabricEntityTypeBuilder-我们建议使用第二个实+你可以在 ''ENTITY_TYPE'' 注册类别下注册这个体。Fabric 提供一个 ''FabricEntityTypeBuilder''继承自原版 ''EntityType.Builder'' 类。Fabric 提供的这类提供了配置你的体的追踪数值的额外方法 
 <code java [enable_line_numbers="true"]> <code java [enable_line_numbers="true"]>
-public static final EntityType<CookieCreeperEntityCOOKIE_CREEPER = +public class EntityTesting implements ModInitializer { 
-    Registry.register( +     
-        Registry.ENTITY_TYPE, +    /* 
-        new Identifier("wiki-entity", "cookie-creeper"), +        * 使用“entitytesting:cube”作为ID注册我们的实体 
-        FabricEntityTypeBuilder.create(EntityCategory.AMBIENTCookieCreeperEntity::new).size(EntityDimensions.fixed(12)).build()+        * 
 +        * 这个实体注册在了 SpawnGroup#CREATURE 类别下,大多数的动物和友好或中立的生物都注册在这个类别下。 
 +        * 它有一个 0.75 × 0.75(或12个像素宽,即一个方块的3/4)大小的碰撞体积。 
 +        */ 
 +    public static final EntityType<CubeEntityCUBE = Registry.register( 
 +            Registries.ENTITY_TYPE, 
 +            new Identifier("entitytesting", "cube"), 
 +            FabricEntityTypeBuilder.create(SpawnGroup.CREATURECubeEntity::new).dimensions(EntityDimensions.fixed(0.75f0.75f)).build()
     );     );
 +    
 +    @Override
 +    public void onInitialize() {
 +    
 +    }
 +}
 </code> </code>
  
-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). +实体需要//属性(Attributes)//和//渲染器(Renderer)//才能起作用。
  
-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类。 我们将皮肤更改为Cookie皮肤,而不是普通的绿色迷彩。+大部分的原版实体都有一个静态方法用于返回它们的属性(比如说 ''ZombieEntity#createZombieAttributes'' )。 
 +我们的自制实体没任何独立的数值,目前,我们可以直接使用 ''MobEntity#createMobAttributes''.
  
-首先,创建一个MobEntityRenderer。 MobEntityRenderer具有2个通类型:实体和模型。 因为我们使用的是Creeper模型,所以我们还必须通过为其指定型来告诉Creeper模型这不是Creeper实体+原版里有一个 ''DefaultAttributeRegistry'' 类用于注册这些属性 
 +想要使用它并不容易,所以Fabric提供一个 ''FabricDefaultAttributeRegistry'' 类。 
 +你应该在你的Mod的初始化部分的某处注册默认的属性:
  
 <code java [enable_line_numbers="true"]> <code java [enable_line_numbers="true"]>
-public class CookieCreeperRenderer extends MobEntityRenderer<CookieCreeperEntityCreeperEntityModel<CookieCreeperEntity>> {+public class EntityTesting implements ModInitializer { 
 +     
 +    public static final EntityType<CubeEntity> CUBE = [...]; 
 +     
 +    @Override 
 +    public void onInitialize() { 
 +        /* 
 +            * 注册我们方块实体的默认属性。 
 +            * 属性是一个生物当前状态的数值,其中有攻击伤害和生命值等。 
 +            * 如果实体没有及时注册适当的属性,则游戏将崩溃。 
 +            * 
 +            * 在1.15中,它是通过重写实体类内部的方法来完成的。 
 +            * 大部分的原版实体都有一个静态方法(例如,ZombieEntity#createZombieAttributes)用于初始化它们的属性。 
 +            */ 
 +        FabricDefaultAttributeRegistry.register(CUBE, CubeEntity.createMobAttributes()); 
 +    } 
 +
 +</code> 
 + 
 +===== 注册实体的渲染器 ===== 
 + 
 +最后一个需要注册的是实体的**渲染器**。渲染器一般通过提供模型来决定实体的 //外观//。 
 +''MobEntityRenderer'' 是生物实体最好的选择。继承这个类需要重写一个用于提供纹理的方法,和三个用于父类构造的参数: 
 +  * ''EntityRenderDispatcher'' 实例 
 +  * ''Model'' 实体的模型 
 +  * 实体阴影的大小,''float''类型 
 +  
 +下面的代码展示了一个简单的实体渲染器,阴影大小是 0.5f,纹理的路径为 ''resources/assets/entitytesting/textures/entity/cube/cube.png''。 
 +注意:用到的纹理和模型将在下一步创建。 
 + 
 +<code java [enable_line_numbers="true"]> 
 +/* 
 +    * 一个用来提供模型、阴影大小和纹理的渲染器 
 +    */ 
 +public class CubeEntityRenderer extends MobEntityRenderer<CubeEntityCubeEntityModel>
 +     
 +    public CubeEntityRenderer(EntityRenderDispatcher entityRenderDispatcher) { 
 +        super(entityRenderDispatcher, new CubeEntityModel(), 0.5f); 
 +    } 
 +     
 +    @Override 
 +    public Identifier getTexture(CubeEntity entity) { 
 +        return new Identifier("entitytesting", "textures/entity/cube/cube.png"); 
 +    } 
 +
 +</code> 
 + 
 +在**客户端初始化类**中使用 ''EntityRendererRegistry'' 来注册这个渲染器: 
 +<code java [enable_line_numbers="true"]> 
 +@Environment(EnvType.CLIENT) 
 +public class EntityTestingClient implements ClientModInitializer { 
 +     
 +    @Override 
 +    public void onInitializeClient() { 
 +        /* 
 +         * 方块实体渲染器的注册,提供模型、阴影大小和纹理的渲染器。 
 +         * 
 +         * 实体渲染器也可以在实体基于上下文进行渲染前(EndermanEntityRenderer#render). 操作模型。 
 +         */ 
 +        EntityRendererRegistry.INSTANCE.register(EntityTesting.CUBE, (dispatcher, context) -> { 
 +            return new CubeEntityRenderer(dispatcher); 
 +        }); 
 +    } 
 +
 +</code> 
 + 
 +===== 创建模型和纹理 ===== 
 + 
 +完成实体创建的最后一步是创建模型和纹理。模型定义了实体的//结构// ,而纹理提供了实体的颜色。 
 + 
 +标准的模型在类的顶部提供并在构造方法中初始化“部位(parts)”,即 ''ModelPart'' 对象,在构造方法中实例化,在 ''getTexturedModelData'' 方法中获得数据,然后在 ''render'' 方法中渲染它们。注意 ''setAngles'' 和 ''render'' 是 ''EntityModel'' 类的抽象方法,必须重写。 
 + 
 +<code java [enable_line_numbers="true"]> 
 +public class CubeEntityModel extends EntityModel<CubeEntity>
 +     
 +    private final ModelPart base; 
 +     
 +    public CubeEntityModel(ModelPart modelPart) { 
 +        base = modelPart.getChild(EntityModelPartNames.CUBE); 
 +    } 
 +    
     [...]     [...]
 } }
 </code> </code>
-需要重写getTexture方法并添加构造函数。 默认情况下,构造函数具有3参数EntityRenderDispatcher,EntityModel,float),但是我们可以删除最并自己创建+在创建一个部位之后,我们需要添加形状shape。为此,我们必须为根部添加一个子形状。新部分的纹理位置在 ''.uv'' 中,其偏移位于 ''.cuboid'' 的前三个数字中,尺寸则为 ''.cuboid''个数字。注意,模型的原点从拐角处开始,所以你需要一些偏移让居中
  
-<code java> +<code java [enable_line_numbers="true"]
-public CookieCreeperRenderer(EntityRenderDispatcher entityRenderDispatcher_1) +public class CubeEntityModel extends EntityModel<CubeEntity>
-+     
-    super(entityRenderDispatcher_1, new CreeperEntityModel<>(), 1);+    private final ModelPart base; 
 +     
 +    public CubeEntityModel() { 
 +        [...] 
 +    
 +  
 +    // 你可以使用 BlockBench,制作你的模型并为你的实体模型导出以得到这个方法。 
 +    public static TexturedModelData getTexturedModelData() { 
 +        ModelData modelData = new ModelData()
 +    ModelPartData modelPartData = modelData.getRoot(); 
 +        modelPartData.addChild(EntityModelPartNames.CUBEModelPartBuilder.create().uv(0, 0).cuboid(-6F, 12F, -6F, 12F, 12F, 12F), ModelTransform.pivot(0F, 0F, 0F)); 
 +    }
 } }
 </code> </code>
-    
-对于getTexture方法,您需要返回模型的纹理。 如果为null,则//您的实体将不可见。 这是100%保证的方法,可以花费3个小时来弄清楚模型为何不起作用。 为方便起见,我创建了一个Cookie爬行器纹理,所有人均可使用,您可以从[[https://imgur.com/a/o3TOlxN |此处]]下载。 
  
-默认的实体纹理文件夹:textures/entity/entity_name/entity.png。 一个示例实现+我们的实体模型现在有了一个 12x12x12 的方块(大一个方块的75%),并以0, 0, 0中心''setAngles'' 用于模型的动画,但目前我们留空。''render'' 用来告诉游戏我们的体出在哪。注意标准的原版模型通常看起来比它们的碰撞体积更大,因此,我们在这里把模型变小。
  
 <code java [enable_line_numbers="true"]> <code java [enable_line_numbers="true"]>
-@Override +public class CubeEntityModel extends EntityModel<CubeEntity>
-protected Identifier getTexture(CookieCreeperEntity cookieCreeperEntity) +     
-+    private final ModelPart base; 
-    return new Identifier("wiki-entity:textures/entity/cookie_creeper/creeper.png");+     
 +    public CubeEntityModel() [...] 
 +     
 +    @Override 
 +    public void setAngles(CubeEntity entity, float limbAngle, float limbDistance, float animationProgress, float headYaw, float headPitch) { 
 +     
 +    } 
 +     
 +    @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, vertices, light, overlay, red, green, blue, alpha); 
 +        }); 
 +    }
 } }
 </code> </code>
-文件存储resources/assets/wiki-entity/textures/entity/cookie_creeper/creeper.png.+要完成我们的模型,我们还需要一个纹理文件。默认的纹理大小是64宽、32高的;你可以通过在 ''texturedModelData'' 添加返回值来改变。我们使用 64x64 的纹理:
  
-最后,您需要将实体连接到渲染器。 由于渲染仅发生在客户端,因此您应始终在ClientModInitializer中执行以下工作: +{{https://i.imgur.com/JdF9zjf.png}} 
-<code java> +  
-EntityRendererRegistry.INSTANCE.register(CookieCreeperEntity.class, (entityRenderDispatchercontext) -> new CookieCreeperRenderer(entityRenderDispatcher));+<code java [enable_line_numbers="true"]
 +public class CubeEntityModel extends EntityModel<CubeEntity>
 +     
 +    private final ModelPart base; 
 +     
 +    public static TexturedModelData getTexturedModelData() { 
 +        [...
 +        return TexturedModelData.of(modelData64, 64); 
 +    } 
 +     
 +    [...] 
 +
 </code> </code>
  
-这会将我们的实体链接我们的新渲染器类。 如果您载入游戏应该会看到我们的新朋友+===== 生成你的实体 ===== 
 +记得将客户端入口点添加到 fabric.mod.json 中像这样 
 +<code json>
  
-https://i.imgur.com/8Gfc2sV.jpg+  "entrypoints"
 +    "main":
 +      "mod.fabricmc.entitytesting.EntityTesting" 
 +    ], 
 +    "client":
 +      "mod.fabricmc.entitytesting.EntityTestingClient" 
 +    ] 
 +  }, 
 +</code>
  
-如果要使用自己模型可以创建一个扩展EntityModel的新类,并在我们的渲染器中为其交换Creeper模型。 这相当复杂,将在单独教程中介绍。+你可以在游戏内使用 ''/summon entitytesting:cube'' 来生成你实体按下 F3+b 可以查看它碰撞体积: 
 +{{https://i.imgur.com/MmQvluB.png}}
  
 +**注意:**如果你的实体没有继承 ''LivingEntity'',你需要创建你自己的封包处理器。你可以通过网络 API 来完成,也可以对 ''ClientPlayNetworkHandler#onEntitySpawn'' 使用 mixin。
zh_cn/tutorial/entity.1576751768.txt.gz · Last modified: 2019/12/19 10:36 by lightcolour