hytopia-assets
HYTOPIA SDKを使ったゲーム開発で、モデルやテクスチャ、音声、UIなどの素材を読み込み、最適化する際に役立ち、ゲームのアセット管理を効率的に行うことを支援するSkill。
📜 元の英語説明(参考)
Helps manage assets in HYTOPIA SDK games. Use when users need to load models, textures, audio, or UI elements. Covers asset loading, HytopiaUI, models, textures, sounds, and asset optimization.
🇯🇵 日本人クリエイター向け解説
HYTOPIA SDKを使ったゲーム開発で、モデルやテクスチャ、音声、UIなどの素材を読み込み、最適化する際に役立ち、ゲームのアセット管理を効率的に行うことを支援するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o hytopia-assets.zip https://jpskill.com/download/9060.zip && unzip -o hytopia-assets.zip && rm hytopia-assets.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/9060.zip -OutFile "$d\hytopia-assets.zip"; Expand-Archive "$d\hytopia-assets.zip" -DestinationPath $d -Force; ri "$d\hytopia-assets.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
hytopia-assets.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
hytopia-assetsフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
HYTOPIA Assets & UI
このスキルは、HYTOPIA SDK ゲームにおけるアセットと UI の管理を支援します。
このスキルを使用する場面
このスキルは、ユーザーが以下のようなことをしたい場合に役立ちます。
- 3D モデル(GLTF/GLB)をロードしたい
- テクスチャまたはマテリアルを追加する必要がある
- サウンドや音楽の再生について質問がある
- UI 要素(HUD、メニュー)を作成したい
- アセットのロードを最適化する必要がある
- デフォルトの SDK アセットについて質問がある
コアとなるアセットの概念
モデルのロード
import { Model, Entity } from 'hytopia';
class Character extends Entity {
constructor() {
super();
this.model = new Model({
modelUri: 'models/character.gltf',
scale: 1.0,
rotation: { x: 0, y: 0, z: 0 }
});
}
}
// アニメーション付きでロード
const animatedModel = new Model({
modelUri: 'models/player.gltf',
animationUri: 'animations/player-idle.gltf',
loopAnimation: true
});
デフォルトアセットの使用
import { Model, BlockType } from 'hytopia';
// SDK に含まれるデフォルトモデル
const defaultModels = {
player: 'hytopia:models/player.gltf',
cube: 'hytopia:models/cube.gltf',
sphere: 'hytopia:models/sphere.gltf'
};
// デフォルトのブロックテクスチャ
const defaultBlocks = {
grass: BlockType.GRASS,
dirt: BlockType.DIRT,
stone: BlockType.STONE,
wood: BlockType.WOOD,
leaves: BlockType.LEAVES
};
カスタムテクスチャ
import { BlockType, Material } from 'hytopia';
// カスタムテクスチャを持つブロックを作成
const customBlock = new BlockType({
id: 'my-mod:custom-block',
name: 'Custom Block',
textureUri: 'textures/custom-block.png',
material: new Material({
roughness: 0.8,
metalness: 0.0
})
});
オーディオ
サウンドの再生
import { Audio, Entity } from 'hytopia';
class SoundEntity extends Entity {
playSound() {
// ワンショットサウンド
this.playAudio({
uri: 'sounds/explosion.mp3',
volume: 1.0,
pitch: 1.0,
spatial: true, // 3D ポジショナルオーディオ
range: 20 // 20 ユニット以内で聞こえる
});
}
playMusic() {
// ループする BGM
this.playAudio({
uri: 'music/background.mp3',
volume: 0.5,
loop: true,
spatial: false // グローバルオーディオ
});
}
}
// 特定の場所で再生
world.playAudioAtPosition(
{ x: 0, y: 10, z: 0 },
{ uri: 'sounds/ambient.mp3', volume: 0.3, range: 30 }
);
オーディオ管理
// 特定のサウンドを停止
entity.stopAudio('sounds/explosion.mp3');
// エンティティ上のすべてのサウンドを停止
entity.stopAllAudio();
// フェードアウト
entity.fadeAudio('music/background.mp3', 0, 2000); // 2 秒かけて 0 にフェード
HytopiaUI
UI 要素の作成
import { Player, UI } from 'hytopia';
// UI をプレイヤーに送信
player.sendUI({
type: 'panel',
id: 'hud',
position: { x: 0.5, y: 0.9 }, // 正規化された画面位置
anchor: 'center-bottom',
children: [
{
type: 'text',
id: 'score',
text: 'Score: 0',
style: { fontSize: 24, color: '#ffffff' }
},
{
type: 'bar',
id: 'health',
value: 100,
max: 100,
style: {
width: 200,
height: 20,
backgroundColor: '#333333',
fillColor: '#ff0000'
}
}
]
});
UI の更新
// 特定の要素を更新
player.updateUI('score', {
text: `Score: ${player.getData('score')}`
});
player.updateUI('health', {
value: player.getData('health'),
max: 100
});
// UI を削除
player.removeUI('hud');
インタラクティブ UI
player.sendUI({
type: 'panel',
id: 'menu',
children: [
{
type: 'button',
id: 'start-btn',
text: 'Start Game',
onClick: 'start-game'
},
{
type: 'button',
id: 'settings-btn',
text: 'Settings',
onClick: 'open-settings'
}
]
});
// クリックを処理
player.onUIEvent = (event) => {
if (event.elementId === 'start-btn') {
startGame(player);
} else if (event.elementId === 'settings-btn') {
openSettings(player);
}
};
アセットの構成
推奨される構造
assets/
├── models/
│ ├── characters/
│ ├── items/
│ └── environment/
├── textures/
│ ├── blocks/
│ ├── ui/
│ └── effects/
├── audio/
│ ├── sfx/
│ ├── music/
│ └── ambient/
└── ui/
├── hud.json
├── menu.json
└── inventory.json
アセットのロード戦略
import { AssetManager } from 'hytopia';
// 重要なアセットをプリロード
await AssetManager.preload([
'models/player.gltf',
'textures/crosshair.png',
'sounds/jump.mp3'
]);
// 必要に応じてロード
function loadLevel(levelId: string) {
return AssetManager.loadBatch([
`levels/${levelId}/terrain.gltf`,
`levels/${levelId}/skybox.png`
]);
}
ベストプラクティス
- モデルの最適化 - GLB 形式を使用し、ポリゴン数を制限します
- テクスチャの圧縮 - 適切な形式を使用します(UI には PNG、3D には圧縮形式)
- オーディオ形式 - 音楽には MP3、短い SFX には WAV
- 遅延ロード - 必要なときにのみアセットをロードします
- マテリアルの再利用 - 重複するマテリアルを作成しないでください
- アトラス テクスチャ - UI スプライトをアトラスに結合します
一般的なパターン
クロスヘア UI
player.sendUI({
type: 'image',
id: 'crosshair',
position: { x: 0.5, y: 0.5 },
anchor: 'center-center',
source: 'textures/crosshair.png',
style: { width: 32, height: 32 }
});
ダメージインジケーター
function showDamageIndicator(player: Player, damage: number) {
player.sendUI({
type: 'text',
id: 'damage-text',
position: { x: 0.5, y: 0.4 },
anchor: 'center-center',
text: `-${damage}`,
style: {
fontSize: 36,
color: '#ff0000',
fontWeight: 'bold'
}
});
// 遅延後に削除
setTimeout(() => player.removeUI('damage-text'), 1000);
}
ローディング画面
function showLoadingScreen(player: Player) {
player.sendUI({
type: 'panel',
id: 'loading',
fullScreen: true,
style: { backgroundColor: '#000000' },
children: [
{
type: 'text',
text 📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
HYTOPIA Assets & UI
This skill helps you manage assets and UI in HYTOPIA SDK games.
When to Use This Skill
Use this skill when the user:
- Wants to load 3D models (GLTF/GLB)
- Needs to add textures or materials
- Asks about playing sounds or music
- Wants to create UI elements (HUD, menus)
- Needs to optimize asset loading
- Asks about default SDK assets
Core Asset Concepts
Loading Models
import { Model, Entity } from 'hytopia';
class Character extends Entity {
constructor() {
super();
this.model = new Model({
modelUri: 'models/character.gltf',
scale: 1.0,
rotation: { x: 0, y: 0, z: 0 }
});
}
}
// Load with animation
const animatedModel = new Model({
modelUri: 'models/player.gltf',
animationUri: 'animations/player-idle.gltf',
loopAnimation: true
});
Using Default Assets
import { Model, BlockType } from 'hytopia';
// Default models included with SDK
const defaultModels = {
player: 'hytopia:models/player.gltf',
cube: 'hytopia:models/cube.gltf',
sphere: 'hytopia:models/sphere.gltf'
};
// Default block textures
const defaultBlocks = {
grass: BlockType.GRASS,
dirt: BlockType.DIRT,
stone: BlockType.STONE,
wood: BlockType.WOOD,
leaves: BlockType.LEAVES
};
Custom Textures
import { BlockType, Material } from 'hytopia';
// Create block with custom texture
const customBlock = new BlockType({
id: 'my-mod:custom-block',
name: 'Custom Block',
textureUri: 'textures/custom-block.png',
material: new Material({
roughness: 0.8,
metalness: 0.0
})
});
Audio
Playing Sounds
import { Audio, Entity } from 'hytopia';
class SoundEntity extends Entity {
playSound() {
// One-shot sound
this.playAudio({
uri: 'sounds/explosion.mp3',
volume: 1.0,
pitch: 1.0,
spatial: true, // 3D positional audio
range: 20 // Audible within 20 units
});
}
playMusic() {
// Looping background music
this.playAudio({
uri: 'music/background.mp3',
volume: 0.5,
loop: true,
spatial: false // Global audio
});
}
}
// Play at location
world.playAudioAtPosition(
{ x: 0, y: 10, z: 0 },
{ uri: 'sounds/ambient.mp3', volume: 0.3, range: 30 }
);
Audio Management
// Stop specific sound
entity.stopAudio('sounds/explosion.mp3');
// Stop all sounds on entity
entity.stopAllAudio();
// Fade out
entity.fadeAudio('music/background.mp3', 0, 2000); // Fade to 0 over 2 seconds
HytopiaUI
Creating UI Elements
import { Player, UI } from 'hytopia';
// Send UI to player
player.sendUI({
type: 'panel',
id: 'hud',
position: { x: 0.5, y: 0.9 }, // Normalized screen position
anchor: 'center-bottom',
children: [
{
type: 'text',
id: 'score',
text: 'Score: 0',
style: { fontSize: 24, color: '#ffffff' }
},
{
type: 'bar',
id: 'health',
value: 100,
max: 100,
style: {
width: 200,
height: 20,
backgroundColor: '#333333',
fillColor: '#ff0000'
}
}
]
});
Updating UI
// Update specific element
player.updateUI('score', {
text: `Score: ${player.getData('score')}`
});
player.updateUI('health', {
value: player.getData('health'),
max: 100
});
// Remove UI
player.removeUI('hud');
Interactive UI
player.sendUI({
type: 'panel',
id: 'menu',
children: [
{
type: 'button',
id: 'start-btn',
text: 'Start Game',
onClick: 'start-game'
},
{
type: 'button',
id: 'settings-btn',
text: 'Settings',
onClick: 'open-settings'
}
]
});
// Handle clicks
player.onUIEvent = (event) => {
if (event.elementId === 'start-btn') {
startGame(player);
} else if (event.elementId === 'settings-btn') {
openSettings(player);
}
};
Asset Organization
Recommended Structure
assets/
├── models/
│ ├── characters/
│ ├── items/
│ └── environment/
├── textures/
│ ├── blocks/
│ ├── ui/
│ └── effects/
├── audio/
│ ├── sfx/
│ ├── music/
│ └── ambient/
└── ui/
├── hud.json
├── menu.json
└── inventory.json
Asset Loading Strategy
import { AssetManager } from 'hytopia';
// Preload critical assets
await AssetManager.preload([
'models/player.gltf',
'textures/crosshair.png',
'sounds/jump.mp3'
]);
// Load on demand
function loadLevel(levelId: string) {
return AssetManager.loadBatch([
`levels/${levelId}/terrain.gltf`,
`levels/${levelId}/skybox.png`
]);
}
Best Practices
- Optimize models - Use GLB format, limit polygon count
- Compress textures - Use appropriate formats (PNG for UI, compressed for 3D)
- Audio formats - MP3 for music, WAV for short SFX
- Lazy loading - Load assets only when needed
- Reuse materials - Don't create duplicate materials
- Atlas textures - Combine UI sprites into atlases
Common Patterns
Crosshair UI
player.sendUI({
type: 'image',
id: 'crosshair',
position: { x: 0.5, y: 0.5 },
anchor: 'center-center',
source: 'textures/crosshair.png',
style: { width: 32, height: 32 }
});
Damage Indicator
function showDamageIndicator(player: Player, damage: number) {
player.sendUI({
type: 'text',
id: 'damage-text',
position: { x: 0.5, y: 0.4 },
anchor: 'center-center',
text: `-${damage}`,
style: {
fontSize: 36,
color: '#ff0000',
fontWeight: 'bold'
}
});
// Remove after delay
setTimeout(() => player.removeUI('damage-text'), 1000);
}
Loading Screen
function showLoadingScreen(player: Player) {
player.sendUI({
type: 'panel',
id: 'loading',
fullScreen: true,
style: { backgroundColor: '#000000' },
children: [
{
type: 'text',
text: 'Loading...',
style: { fontSize: 48, color: '#ffffff' }
},
{
type: 'progress',
id: 'loading-bar',
value: 0,
max: 100,
style: { width: 400, height: 20 }
}
]
});
}
function updateLoadingProgress(player: Player, percent: number) {
player.updateUI('loading-bar', { value: percent });
if (percent >= 100) {
player.removeUI('loading');
}
}