{"id":"hakochanjp/hueless","name":"hueless","scope":"hakochanjp","platform":"roblox","description":"Desaturate mesh textures at runtime and fade the colour back in","version":"0.1.0","latest":"0.1.0","versions":["0.1.0"],"license":"MIT","licenseRating":"safe","licenseCaveats":["The package archive does not include its license text; the license is declared in its manifest metadata."],"licenseVerified":false,"dependencies":{},"integrity":"021cc7e518efa3228237b8257e1493094a1c2cfdb38aecfc91c8a27b097592c1","likes":0,"downloads":0,"install":"forest install hakochanjp/hueless","url":"https://forest.dev/p/roblox/hakochanjp/hueless","files":"https://api.forest.dev/ai/package/roblox/hakochanjp/hueless/files","readme":"# Hueless\n\nメッシュのテクスチャを実行時にグレースケール化し、あとから色をフェードで戻すための Roblox モジュール。\n\n「最初は色のない世界で、プレイヤーが通ったところから色が戻る」といった演出のために作りました。\n\n## インストール\n\n```toml\n[dependencies]\nHueless = \"hakochanjp/hueless@0.1.0\"\n```\n\n```\nwally install\n```\n\n## 使い方\n\n入口は `new` だけです。\n\n### 簡易\n\n```lua\nlocal Hueless = require(ReplicatedStorage.Packages.Hueless)\n\nlocal hueless = Hueless.new()\n\nhueless:Preload(workspace.PlantField)     -- Part / Model / Folder / 配列\nhueless:Desaturate(workspace.PlantField)  -- 全部グレーになる\nhueless:Trail(workspace.PlantField, humanoidRootPart)  -- 近づいた株から色が戻る\n```\n\n### 微調整\n\n```lua\nlocal hueless = Hueless.new({\n    Resolution      = 256,\n    FadeTime        = 1.2,\n    EasingStyle     = Enum.EasingStyle.Sine,\n    EasingDirection = Enum.EasingDirection.Out,\n    Strength        = 0.85,\n    Luma            = Hueless.Luma.BT709,\n    MaxConcurrent   = 3,\n    OverlayScale    = 1.02,\n    IdAttribute     = \"PlantId\",\n})\n\nhueless:Restore(part, { FadeTime = 2 })\nhueless:RestoreInstant(part)\nprint(hueless:IsDesaturated(part))\n\nlocal trail = hueless:Trail(parts, root, { Radius = 8, Interval = 0.08 })\ntrail:Stop()\n\nhueless:Destroy()\n```\n\n## API\n\n| メソッド | 説明 |\n| --- | --- |\n| `Hueless.new(options?)` | 唯一の入口 |\n| `:Preload(target)` | グレー画像を先に作る。戻り値は用意できた種類数 |\n| `:Desaturate(target)` | グレーにする |\n| `:Restore(target, fadeOptions?)` | 色をフェードで戻す |\n| `:RestoreInstant(target)` | フェードなしで即座に戻す |\n| `:IsDesaturated(part)` | グレー状態か |\n| `:SetTexture(part, textureId)` | SurfaceAppearance 付きメッシュのテクスチャ ID を教える |\n| `:Trail(target, follow, options?)` | `follow` に近づいた Part から順に戻す |\n| `:Destroy()` | すべて片付ける |\n\n`target` は Part 単体でも Model / Folder でも、それらの配列でも受け付けます。\n\n### オプション\n\n| 名前 | 既定値 | 説明 |\n| --- | --- | --- |\n| `Resolution` | `256` | グレー画像の一辺。メモリ直結 |\n| `FadeTime` | `0.6` | 色が戻るのにかける秒数 |\n| `EasingStyle` | `Quad` | |\n| `EasingDirection` | `Out` | |\n| `Strength` | `1` | `0` = 元のまま、`1` = 完全にグレー |\n| `Luma` | `BT601` | `BT601` / `BT709` / `Average` / 自作関数 |\n| `MaxConcurrent` | `3` | 元画像を同時に何枚まで抱えるか |\n| `Retries` | `3` | 読み込み失敗時の再試行回数 |\n| `OverlayScale` | `1.02` | 重ねるコピーの拡大率 |\n| `IdAttribute` | `nil` | 状態を属性の値で覚える |\n| `TextureAttribute` | `nil` | テクスチャ ID をこの名前の属性から読む（SurfaceAppearance 用） |\n\n## 仕組み\n\n色はライティングではなく **テクスチャ画像そのもの** を差し替えて変えています。\n\n`BasePart.Color` は乗算のティントなので、灰色を掛けても暗くなるだけで彩度は落ちません。彩度を実際に抜くには `EditableImage` でピクセルを書き換える必要があります。\n\n色を戻すときはテクスチャを Tween できないので、グレーのコピーを本体に被せ、そのコピーを薄くしていきます。下から本体のカラーが透けてくる形です。\n\n## 注意点\n\n**Game Settings → Security → Allow Editable Image & Mesh API を ON にしてください。** OFF だと `Preload` が `0` を返します。\n\n**テクスチャの所有者を揃えてください。** 体験の所有者（グループ所有ならそのグループ）と同じアカウントがアップロードしたアセットしか読み込めません。\n\n**クライアント側で実行してください。** `EditableImage` はレプリケートされません。\n\n**SurfaceAppearance 付きメッシュはテクスチャ ID を教えてください。** `SurfaceAppearance.ColorMap` は実クライアントでは **読み取りにも Plugin 権限が必要** で、ゲームスクリプトからは読めません（Edit モードやプラグインからは読めるので気づきにくい）。属性か `SetTexture` で ID を渡します。\n\n```lua\n-- 方法1: 属性で教える（ストリーミングに強い。推奨）\nmesh:SetAttribute(\"HuelessTexture\", \"rbxassetid://...\")  -- サーバー側などで\nlocal hueless = Hueless.new({ TextureAttribute = \"HuelessTexture\" })\n\n-- 方法2: コードで直接教える\nhueless:SetTexture(mesh, \"rbxassetid://...\")\n```\n\nなお SurfaceAppearance の `AlphaMode` が `Overlay` の場合、ColorMap のアルファは「透明度」ではないため、被せるグレーコピーにはアルファを 255 に潰した版を自動で使います。\n\n**`Resolution` はメモリに直結します。**\n\n```\n 256² = 0.25 MB\n 512² = 1.00 MB\n1024² = 4.00 MB   （テクスチャ 1 種類あたり）\n```\n\n`EditableImage` には通常のテクスチャとは別枠のメモリ上限があります。21 種類を 1024² で作ろうとして実際に上限に当たりました。**上限に当たると error ではなく `nil` が返る** ので気づきにくいです。\n\n同じテクスチャを使うインスタンスは 1 枚を共有するので、1000 株置いてもグレー画像は種類数しか作られません。\n\n## 開発（実機検証）\n\nプロジェクトファイルは 2 つあります。\n\n| ファイル | 用途 |\n| --- | --- |\n| `default.project.json` | ライブラリ本体の定義（wally / sourcemap 用） |\n| `serve.project.json` | 検証プレースへの同期用。`ReplicatedStorage.Packages.Hueless` にマップする |\n\n検証プレースで最新のソースを使うには:\n\n```\nrojo serve serve.project.json\n```\n\nを起動して、Studio の Rojo プラグインから Connect してください。既存の\n`ReplicatedStorage.Packages.Hueless` は接続時にリポジトリの内容へ同期されます。\n`Test.server.lua` は `globIgnorePaths` で同期から除外しています。\nReplicatedStorage / Packages 配下のほかのインスタンスには触りません。\n\n## ライセンス\n\nMIT\n","readmeTruncated":false}