Skip to content

精确旋转

本页面镜像自
BedrockWiki

根据原始项目协议授权。本文经过AI翻译处理,如有内容遗漏,可以提交PR进行补充。

格式与最低引擎版本 1.20.30

本教程假定您已具备方块的进阶知识与Molang基础。 开始前建议先阅读方块指南

实验性功能

需要启用 Holiday Creator Features 来触发事件。

本教程将引导您实现可支持次级方位旋转的方块(如爬行者头颅与告示牌),通过一个包含此类旋转类型的"贝壳"方块作为实例进行讲解。

查看常规旋转方式?请前往此页面

随机朝向的自定义贝壳方块

特性概览:

  • 可附着于方块顶部,具备16种旋转角度
  • 可附着于方块的侧表面(北、东、南、西)
  • 旋转行为与原版生物头颅一致,且无需依赖方块实体性能消耗!

方块模型

要实现更精确的旋转机制,您的方块模型需额外添加若干骨骼节点。

实现地面精确旋转需要4个基础骨骼节点,每个对应不同的Y轴旋转角度:

  • up_0 (Y旋转角度 = 0)
  • up_22_5 (Y旋转角度 = 22.5)
  • up_45 (Y旋转角度 = 45)
  • up_67_5 (Y旋转角度 = 67.5)

上述角度值采用顺时针方向递增

这些骨骼除旋转参数外,在结构上通常是互为复制的。

TIP

建议将所有骨骼的枢轴点设置于 [0, 0, 0] ,以确保其围绕方块中心旋转。

此外,还需一个 side 骨骼用于侧表面附着时的定位调整。

下方展示的"贝壳"模型结构可供参考:

基础方块JSON

下方是待添加高级旋转功能的"贝壳"方块基础定义。

json
{
  "format_version": "1.20.30",
  "minecraft:block": {
    "description": {
      "identifier": "wiki:shell",
      "menu_category": {
        "category": "nature"
      }
    },
    "components": {
      // `up` 表面的碰撞/选择框
      "minecraft:collision_box": {
        "origin": [-3, 0, -3],
        "size": [6, 3, 6]
      },
      "minecraft:selection_box": {
        "origin": [-3, 0, -3],
        "size": [6, 3, 6]
      },
      "minecraft:material_instances": {
        "*": {
          "texture": "shell" // 在 `RP/textures/terrain_texture.json` 中定义的短名称
        }
      },
      // 阻止方块附着于 `down` 表面
      "minecraft:placement_filter": {
        "conditions": [
          {
             "allowed_faces": ["up", "side"]
          }
        ]
      }
    }
  }
}

方块状态

为实现头颅式旋转机制,需为方块添加2种状态参数:

json
"description": {
  ...
  "traits": {
    // 方块附着面 - 默认为 `north`
    "minecraft:placement_position": {
      "enabled_states": ["minecraft:block_face"]
    }
  },
  "states": {
    // 当附着于 `up` 表面时的精确旋转参数
    "wiki:rotation": {
      "values": { "min": 0, "max": 15 } // 使用更方便的定义整数范围的语法
    }
  }
}

旋转Molang表达式

相较于逐个定义每个 wiki:rotation 值的范围,运用复合Molang表达式配合除法运算可高效实现需求!

c
// 转换玩家头部Y旋转角度至正值
t.positive_head_rot = q.head_y_rotation(0) + 360 * (q.head_y_rotation(0) != math.abs(q.head_y_rotation(0)));
// 计算头部旋转对应的十六分之一圆角(取整)
t.rotation = math.round(t.positive_head_rot / 22.5);

// 0与16代表重复旋转(0度与360度),故当值为16时返回0
return t.rotation != 16 ? t.rotation;

合并为单行表达式以便嵌入JSON:

json
"condition": "t.positive_head_rot = q.head_y_rotation(0) + 360 * (q.head_y_rotation(0) != math.abs(q.head_y_rotation(0))); t.rotation = math.round(t.positive_head_rot / 22.5); return t.rotation != 16 ? t.rotation;"

应用旋转

现在通过Molang表达式动态设定方块属性!

通过事件在玩家放置方块时更新方块属性。此事件上下文可访问 q.block_faceq.head_y_rotation

在方块JSON中添加以下组件与事件:

json
"components": {
  ...
  "minecraft:on_player_placing": {
    "condition": "q.block_face == 1", // 精确旋转仅作用于 `up` 表面
    "event": "wiki:set_rotation"
  }
},
"events": {
  "wiki:set_rotation": {
    "set_block_property": {
      // 应用之前的Molang表达式设置rotation属性
      "wiki:rotation": "q.block_face == 1 ? { t.positive_head_rot = q.head_y_rotation(0) + 360 * (q.head_y_rotation(0) != math.abs(q.head_y_rotation(0))); t.block_rotation = math.round(t.positive_head_rot / 22.5); return t.block_rotation != 16 ? t.block_rotation; };"
    }
  }
}

接着,使用置换定义基础朝向旋转,由模型中的精细骨骼进一步细化。

按顺序在方块JSON中添加以下置换条件:

json
"permutations": [
  {
    "condition": "q.block_property('wiki:rotation') >= 4 || q.block_property('minecraft:block_face') == 'east'",
    "components": {
      "minecraft:transformation": { "rotation": [0, -90, 0] }
    }
  },
  {
    "condition": "q.block_property('wiki:rotation') >= 8 || q.block_property('minecraft:block_face') == 'south'",
    "components": {
      "minecraft:transformation": { "rotation": [0, 180, 0] }
    }
  },
  {
    "condition": "q.block_property('wiki:rotation') >= 12 || q.block_property('minecraft:block_face') == 'west'",
    "components": {
      "minecraft:transformation": { "rotation": [0, 90, 0] }
    }
  }
]

骨骼可见性

并非所有骨骼节点始终可见,因此需利用 minecraft:geometry 的骨骼可见性属性精确控制渲染。多个骨骼存在的目的是因为 minecraft:transformation 仅支持90度的整数倍旋转,而精确旋转需要22.5度的增量。

在方块组件中加入以下内容:

json
"minecraft:geometry": {
  "identifier": "geometry.shell", // 第一步创建的模型
  "bone_visibility": {
    "up_0": "q.block_property('minecraft:block_face') == 'up' && !math