jpskill.com
🛠️ 開発・MCP コミュニティ

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本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
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
🪟 Windows (PowerShell)
$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. 1. 下の青いボタンを押して hytopia-assets.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → hytopia-assets フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

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`
  ]);
}

ベストプラクティス

  1. モデルの最適化 - GLB 形式を使用し、ポリゴン数を制限します
  2. テクスチャの圧縮 - 適切な形式を使用します(UI には PNG、3D には圧縮形式)
  3. オーディオ形式 - 音楽には MP3、短い SFX には WAV
  4. 遅延ロード - 必要なときにのみアセットをロードします
  5. マテリアルの再利用 - 重複するマテリアルを作成しないでください
  6. アトラス テクスチャ - 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

  1. Optimize models - Use GLB format, limit polygon count
  2. Compress textures - Use appropriate formats (PNG for UI, compressed for 3D)
  3. Audio formats - MP3 for music, WAV for short SFX
  4. Lazy loading - Load assets only when needed
  5. Reuse materials - Don't create duplicate materials
  6. 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');
  }
}