User Tools

Site Tools


zh_cn:tutorial:blockentityrenderers

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
zh_cn:tutorial:blockentityrenderers [2023/08/29 10:31] – [例子] wjz_pzh_cn:tutorial:blockentityrenderers [2024/08/27 04:42] (current) solidblock
Line 1: Line 1:
 ====== 使用方块实体渲染器动态渲染方块和物品 ====== ====== 使用方块实体渲染器动态渲染方块和物品 ======
-// +//这是本教程的 1.15 以上版本。对于 1.14 版本,请参见[[tutorial:1.14:blockentityrenderers|使用方块实体渲染器动态渲染方块和物品(1.14)(英文)]]。//
-这是本教程的 1.15 以上版本。对于 1.14 版本,请参见[[zh_cn:tutorial:1.14:blockentityrenderers|使用方块实体渲染器动态渲染方块和物品(1.14)]]。//+
  
 阅读本教程之前,请确保您已[[blockentity|添加方块实体]]! 阅读本教程之前,请确保您已[[blockentity|添加方块实体]]!
 ===== 介绍 ===== ===== 介绍 =====
-方块本身并不是那么有趣,只是在某个位置和某个大小保持静止直到损坏。我们可以使用方块实体渲染器(block entity renderer)更加动态地渲染与方块实体有关的物品和方块——在不同的位置、以不同的大小渲染多个物品。+方块本身并不是那么有趣,只是在某个位置和某个大小保持静止直到损坏。我们可以使用**方块实体渲染器**(block entity renderer)更加动态地渲染与方块实体有关的物品和方块——在不同的位置、以不同的大小渲染多个物品。
 ===== 例子 ===== ===== 例子 =====
 在本教程中,我们将通过向其添加 ''BlockEntityRenderer'' 来构建所创建的方块实体。渲染器将显示一个唱片机,漂浮在方块上方,上下移动并旋转。 在本教程中,我们将通过向其添加 ''BlockEntityRenderer'' 来构建所创建的方块实体。渲染器将显示一个唱片机,漂浮在方块上方,上下移动并旋转。
Line 24: Line 23:
 </code> </code>
  
-我们将需要注册我们的 ''BlockEntityRenderer'',但仅针对客户端。在单人游戏设置中这无关紧要,因为服务器与客户端在同一进程中运行。但是,在多人游戏设置中,服务器在与客户端不同的进程中运行,服务器代码没有 ''BlockEntityRenderer'' 的概念,因此不接受注册。要仅为客户端运行初始化代码,我们需要设置一个 ''client'' 入口点(entrypoint) +我们将需要注册我们的 ''BlockEntityRenderer'',但仅针对客户端。在单人游戏设置中这无关紧要,因为服务器与客户端在同一进程中运行。但是,在多人游戏设置中,服务器在与客户端不同的进程中运行,服务器代码没有 ''BlockEntityRenderer'' 的概念,因此不接受注册。要仅为客户端运行初始化代码,我们需要设置一个 ''client'' 入口点。
- +
-在实现 ''ClientModInitializer'' 的主类旁边创建一个新类:+
  
 +在实现了 ''ClientModInitializer'' 的入口点中:
 <code java> <code java>
 @Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
Line 37: Line 35:
 } }
 </code> </code>
-将此类设置为 ''fabric.mod.json'' 中的client入口点(根据需要修改路径):+将此类设置为 [[documentation:fabric_mod_json|fabric.mod.json]] 中的 ''client'' 入口点,如果还没有完成的话(根据需要修改路径):
 <code javascript "fabric.mod.json"> <code javascript "fabric.mod.json">
-"entrypoints": {+
 +  [...] 
 +  "entrypoints": {
     [...]     [...]
     "client": [     "client": [
Line 46: Line 46:
       }       }
     ]     ]
 +  },
 +  [...]
 }     }    
 </code> </code>
  
-在我们的 ClientModInitializer 中注册 ''BlockEntityRenderer''+在我们的 ''ClientModInitializer'' 中注册 ''BlockEntityRenderer''
  
 <code java> <code java>
Line 55: Line 57:
     public void onInitializeClient() {     public void onInitializeClient() {
         BlockEntityRendererRegistry.register(DEMO_BLOCK_ENTITY, DemoBlockEntityRenderer::new);         BlockEntityRendererRegistry.register(DEMO_BLOCK_ENTITY, DemoBlockEntityRenderer::new);
-        //不行就试试BlockEntityRendererRegistry.INSTANCE.register(DEMO_BLOCK_ENTITY, DemoBlockEntityRenderer::new);+        // 旧版本如果不行就试试这个: 
 +        // BlockEntityRendererRegistry.INSTANCE.register(DEMO_BLOCK_ENTITY, DemoBlockEntityRenderer::new);
     }     }
 </code> </code>
-我们重写在每一帧都会被调用的 ''render'' 方法,我们将在其中进行渲染——对于初学者,请调用 ''matrices.push();'',这在进行GL调用时是必需的(我们将在紧接之后进行):+我们重写在每一帧都会被调用的 ''render'' 方法,将在其中进行渲染——对于初学者,请调用 ''matrices.push();'',这在进行 GL 调用时是必需的(我们将在紧接之后进行):
  
 <code java> <code java>
Line 65: Line 68:
     }     }
 </code> </code>
-然后,我们对唱片机进行平移(matrices.translate)和旋转(matrices.multiply)。平移分为两部分:将其平移到高于方块中心的 0.5、1.25 和 0.5。第二部分是变化的部分:y 值的偏移量。偏移量是任何给定帧的物品高度。每次我们都要重新计算,因为我们希望它可以动画上下跳跃。我们通过以下方式计算:+然后,我们对唱片机进行平移(''matrices.translate'')和旋转(''matrices.multiply'')。平移分为两部分:将其平移到高于方块中心的 0.5、1.25 和 0.5。第二部分是变化的部分:y 值的偏移量。偏移量是任何给定帧的物品高度。每次我们都要重新计算,因为我们希望它可以动画上下跳跃。我们通过以下方式计算:
    *获取当前世界时间,该时间会随着时间而变化。    *获取当前世界时间,该时间会随着时间而变化。
    *添加部分刻。(部分刻是一个小数值,代表最后一次完整刻和现在之间的时间间隔。我们使用此方法,要不然动画会抖动,因为每秒的刻数少于每秒的帧数。)    *添加部分刻。(部分刻是一个小数值,代表最后一次完整刻和现在之间的时间间隔。我们使用此方法,要不然动画会抖动,因为每秒的刻数少于每秒的帧数。)
Line 83: Line 86:
     }     }
 </code> </code>
-最后,我们将获得 Minecraft 的 ''ItemRenderer'',并使用 ''renderItem'' 渲染唱片机物品。我们还将 ''ModelTransformation.Type.GROUND'' 传递给 ''renderItem'',因为我们希望有类似与物品置于地上的效果。尝试对此值进行试验,看看会发生什么(这是一个枚举)。在这些 GL 调用之后,我们还需要调用''matrices.pop();''+最后,我们将获得 Minecraft 的 ''ItemRenderer'',并使用 ''renderItem'' 渲染唱片机物品。我们还将 ''ModelTransformationMode.GROUND''((对于旧有和 Minecraft 版本,可能是 ''ModelTransformation.Mode.GROUND'' 或 ''ModelTransformation.Type.GROUND''))传递给 ''renderItem'',因为我们希望有类似与物品置于地上的效果。尝试对此值进行试验,看看会发生什么(这是一个枚举)。在这些 GL 调用之后,我们还需要调用''matrices.pop();''
 <code java> <code java>
     public void render(DemoBlockEntity blockEntity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) {     public void render(DemoBlockEntity blockEntity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) {
         [...]         [...]
-        MinecraftClient.getInstance().getItemRenderer().renderItem(stack, ModelTransformation.Mode.GROUND, light, overlay, matrices, vertexConsumers, 0);+        MinecraftClient.getInstance().getItemRenderer().renderItem(stack, ModelTransformationMode.GROUND, light, overlay, matrices, vertexConsumers, blockEntity.getWorld(), 0);
  
         // GL 调用之后的必要调用         // GL 调用之后的必要调用
Line 94: Line 97:
 </code> </code>
  
-现在就可以尝试新创建的方块实体渲染器。但是,如果您没有使方块透明,您会发现有些不对劲——这个浮动的方块,即唱片机,是黑色的!这是因为默认情况下,//无论您在方块实体中渲染什么,都将接收该方块实体所在位置的光照度//。所以浮动的方块接收这个不透明方块内部的光照,这意味着接收不到光。为了解决此问题,我们会让Minecraft接收方块实体上方位置的光照强度。+现在就可以尝试新创建的方块实体渲染器。但是,如果您没有使方块透明,您会发现有些不对劲——这个浮动的方块,即唱片机,是黑色的!这是因为默认情况下,//无论您在方块实体中渲染什么,都将接收该方块实体所在位置的光照度//。所以浮动的方块接收这个不透明方块内部的光照,这意味着接收不到光。为了解决此问题,我们会让 Minecraft 接收方块实体上方位置的光照强度。
  
 要获取光照,我们在方块实体上方的位置调用 ''WorldRenderer#getLightmapCoordinates();'',并在 ''renderItem()'' 使用这个光照。 要获取光照,我们在方块实体上方的位置调用 ''WorldRenderer#getLightmapCoordinates();'',并在 ''renderItem()'' 使用这个光照。
Line 103: Line 106:
                  
         int lightAbove = WorldRenderer.getLightmapCoordinates(blockEntity.getWorld(), blockEntity.getPos().up());         int lightAbove = WorldRenderer.getLightmapCoordinates(blockEntity.getWorld(), blockEntity.getPos().up());
-        MinecraftClient.getInstance().getItemRenderer().renderItem(stack, ModelTransformation.Mode.GROUND, lightAbove, OverlayTexture.DEFAULT_UV, matrices, vertexConsumers, 0);+        MinecraftClient.getInstance().getItemRenderer().renderItem(stack, ModelTransformationMode.GROUND, lightAbove, OverlayTexture.DEFAULT_UV, matrices, vertexConsumers, blockEntity.getWorld(), 0);
                  
         [...]         [...]
Line 112: Line 115:
  
 ===== 根据方块实体数据进行渲染 ===== ===== 根据方块实体数据进行渲染 =====
-有时候你需要根据方块实体的数据(nbt)进行渲染,结果发现这些数据全是空的,尽管通过 ''/data get block'' 命令可以正常访问数据。这是因为你没有将服务器的数据同步至客户端。参见[[zh_cn:tutorial:blockentity#将服务器数据同步至客户端]]。+有时候你需要根据方块实体的数据(nbt)进行渲染,结果发现这些数据全是空的,尽管通过 ''/data get block'' 命令可以正常访问数据。这是因为你没有将服务器的数据同步至客户端。参见[[blockentity modify data#将服务器数据同步至客户端]]。
zh_cn/tutorial/blockentityrenderers.1693305084.txt.gz · Last modified: 2023/08/29 10:31 by wjz_p