一键导入
omg-cocos-playable-asset-management
AssetsManager singleton with caching, duplicate-load prevention, and typed resource loading for playable ad size budgets
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
AssetsManager singleton with caching, duplicate-load prevention, and typed resource loading for playable ad size budgets
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Unity engine adapter: .asmdef graph, Roslyn class diagrams with Unity stereotypes (MonoBehaviour, ScriptableObject, DOTS), UPM package deps, and C4 architecture views
Cocos Creator 3.8.7 playable-ad parameter discovery + implementation. Scans project config files (constant.ts, *Config.ts) AND all Canvas UI nodes via MCP, reads scene values for defaults, wires bindings, auto-assigns. Modes: --quick, --standard, --deep, --exhaustive, --auto.
Compare CK updates against GameKit baseline, suggest which changes to incorporate.
Answer technical questions with context-aware skill activation. Use for 'how does X work', 'what is the best way to', 'explain this pattern' queries.
Check context usage limits, monitor time remaining, optimize token consumption, debug context failures. Use when asking about context window, token budget, or agent context sizing.
Implement features end-to-end: plan, code, test, review via registry agents. Use for 'implement X', 'build Y feature', 'add Z functionality'. Handles full workflow.
| name | omg-cocos-playable-asset-management |
| description | AssetsManager singleton with caching, duplicate-load prevention, and typed resource loading for playable ad size budgets |
This skill was ported from upstream reference material. Interpret command names, paths, and agent-routing guidance as Codex/Oh My Game Kit equivalents. Prefer active Codex tools and local project instructions over Codex-specific mechanics when they conflict.
Singleton wrapping Cocos resources.load() with a memory cache and in-flight deduplication. Critical for playable ads where the <5MB size budget demands careful asset reuse. See omg-cocos-playable-object-pool for how ObjectPoolManager delegates to this class.
AssetsManager (singleton)
├── _cache: Map<string, Asset> ← "path_TypeName" → Asset
└── _loadingPromises: Map<string, Promise> ← deduplication guard
Cache key format: "${path}_${type.name}" e.g. "audio/BGM_AudioClip".
All assets loaded from resources/ folder (Cocos runtime bundle). Paths are relative to assets/resources/.
const am = AssetsManager.instance;
// Generic typed load (with cache + dedup)
const prefab = await am.loadResource("prefab/UI/GameHUD", Prefab);
const sprite = await am.loadResource("sprites/logo", SpriteFrame);
const texture = await am.loadResource("textures/bg", Texture2D);
const json = await am.loadResource("data/config", JsonAsset);
// Convenience shorthands
const prefab = await am.loadPrefab("prefab/UI/GameHUD");
const sprite = await am.loadSprite("sprites/logo");
const audio = await am.loadAudio("BGM"); // prepends "audio/" automatically
const tex = await am.loadTexture("textures/bg");
const json = await am.loadJson("data/config");
// Load entire directory
const frames = await am.loadDir("sprites/icons", SpriteFrame);
const all = await am.loadDir("prefab/enemies"); // untyped
// Parallel preload
await am.preloadResources([
{ path: "prefab/UI/GameHUD", type: Prefab },
{ path: "audio/BGM", type: AudioClip },
]);
// Bundle loading (for split bundles)
const bundle = await am.loadBundle("game-assets");
// Cache queries
am.isCached("prefab/UI/GameHUD", Prefab); // boolean
am.getCachedAsset("prefab/UI/GameHUD", Prefab); // Prefab | null
am.getCacheSize(); // number of cached entries
// Release (decrements Cocos ref count)
am.releaseAsset("prefab/UI/GameHUD", Prefab);
am.releaseAll(); // full cache flush — use on scene exit
Concurrent calls with the same path+type share one Promise. The second caller awaits the same network request — no double load. Promise entry is removed from _loadingPromises on resolve or reject.
// Both calls share one load operation:
const [a, b] = await Promise.all([
am.loadPrefab("prefab/Coin"),
am.loadPrefab("prefab/Coin"), // hits dedup guard, returns same promise
]);
loadAudio(name) automatically prepends "audio/":
await am.loadAudio("BGM"); // loads resources/audio/BGM.mp3
await am.loadAudio("SFX_Tap");
Do not include "audio/" in the name — it will double-prefix.
loadAsync(type, id) loads from prefab/UI/{id} — kept for backward compatibility. Prefer loadResource() for new code.
Preload all assets during loading state:
await AssetsManager.instance.preloadResources([
{ path: "prefab/UI/WinView", type: Prefab },
{ path: "prefab/UI/LoseView", type: Prefab },
{ path: "audio/BGM", type: AudioClip },
{ path: "audio/SFX_Win", type: AudioClip },
]);
Load and instantiate a prefab:
const prefab = await AssetsManager.instance.loadPrefab("prefab/UI/Tutorial");
const node = instantiate(prefab);
node.parent = this.node;
Load sprite for dynamic UI:
const frame = await AssetsManager.instance.loadSprite("sprites/avatars/hero");
this.avatarSprite.spriteFrame = frame;
Release on scene exit to free memory:
onDestroy(): void {
AssetsManager.instance.releaseAll();
}
AssetsManager | resources.load() direct | |
|---|---|---|
| Cache | Yes — reuses asset | No — loads again |
| Dedup | Yes — shared promise | No — parallel loads |
| Type safety | Typed generics | Typed generics |
| Use case | All runtime loads | Avoid — use AssetsManager |
releaseAll() on scene/level transitionsgetCacheSize() to monitor cached count during developmentloadDir() for icon sheets — one call, all frames cachedreleaseAsset() per clip after playback if one-shot"audio/BGM" to loadAudio() — results in path "audio/audio/BGM" (not found)loadResource() before accessing the asset — returns unresolved PromisereleaseAll() while assets are still referenced by active nodes — Cocos ref-counts drop to 0 and GC destroys them mid-useloadAsync() (legacy) for new prefabs — path is hardcoded to prefab/UI/ prefixAsset.decRef explicitly when releasing dynamic loads.