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
Last revisionBoth sides next revision
zh_cn:tutorial:entity [2019/12/19 10:37] lightcolourzh_cn:tutorial:entity [2023/01/15 01:22] – [生成你的实体] 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.txt · Last modified: 2023/01/15 01:23 by solidblock