20220318のUnityに関する記事は7件です。

Blender作られたアニメーションをUnityに取り込むときのTips

Blender 作られたアニメーションを Unity に取り込む時に色々詰まったので、 そのときに知ってたらよかったなと思ったメモです。 前提 Unity 2020.3.2f1 Blender 2.9.2 メモ fbx から Animation Clip を取り出す 知っていれば簡単。 Unityにfbxをドラッグ&ドロップでインポート fbx を開いて見える Animation Clip を選択 Macなら command + d 、Windowsなら ctrl + d で取り出せる Animation Clip を取り出すときの注意 ボーンの設定 Animation Clip を取り出す前に、ボーンの設定変更しておかないと Animation Clip が正常に動作しない可能性があります。例えば Humanoid 用の Animation Clip なのに、違うボーン設定のまま取り出すと、Humanoid に適用しても正常にアニメーションしません。 アニメーションがループするときに、オブジェクトが時計回りに回転する Animation Clip の Root Transform Rotation を設定すると治る可能性があります。【Unity】Blenderで作成したアニメーションのループをなめらかにする方法の アニメーションをループ再生させる を参照ください。 0フレーム目にT字ポーズが入っている Blender から Unity に取り込むために、0フレーム目をT字ポーズさせています。その場合は、取り出す前に1フレーム目から始まるようにしておくことで、T字ポーズを無視することができます。【Unity】Blenderで作成したアニメーションのループをなめらかにする方法 の フレーム数調整 を参照ください。 1フレーム目から始めたが、アニメーション開示にカクツク場合 clipsの一番上のアニメーションに0フレームにTポーズが入っていない可能性があるので、入っていなければ入れてください clipsの一番上のアニメーション初期位置が他のアニメーションに反映するようです clipsの一番上以外のニメーションは0フーレムにTポーズを入れなくても大丈夫のようです
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

冗長性を回避できるために、Unityの内蔵アセットはどのようにパッケージ化すればいいのか

今回の話題: 冗長性を回避できるために、Unityの内蔵アセットはどのようにパッケージ化すればいいのか SpriteAtlasの「冗長性」問題 Meshの使用メモリについて UGUI.Rendering.UpdateBatches時間コストが高い PluginsのDLLはどのようにPackageに影響するか AssetBundle Q:今はAssetBundleをパッケージ化しようと思いますが、Unityの内蔵アセットはAssetBundle名を指定できますか? AssetBundleにある内蔵アセットの冗長性は一般的にどのように解決しますか? 既存のデータを確認した後、内蔵アセットのパッケージ化により、AssetBundleの冗長処理では、内蔵アセットをローカルに抽出またはダウンロードし、アセットの参照関係を変更してから、パッケージがAssetBundle名を指定できるようになりました。Unityは、スクリプトがAssetBundleをパッケージ化する際に内蔵アセットのBundle名を指定することをサポートしますか。これにより、複数のアセットが同じ内蔵アセットに依存することを防ぎ、冗長性をもたらしますか? A:Scriptable Build Pipelineを使用して実現できます。具体的な方法については、Addressableで内蔵のShaderをパッケージ化する方法を参照してください。 public static IList<IBuildTask> AssetBundleBuiltInResourcesExtraction() { var buildTasks = new List<IBuildTask>(); // Setup buildTasks.Add(new SwitchToBuildPlatform()); buildTasks.Add(new RebuildSpriteAtlasCache()); // Player Scripts buildTasks.Add(new BuildPlayerScripts()); buildTasks.Add(new PostScriptsCallback()); // Dependency buildTasks.Add(new CalculateSceneDependencyData()); #if UNITY_2019_3_OR_NEWER buildTasks.Add(new CalculateCustomDependencyData()); #endif buildTasks.Add(new CalculateAssetDependencyData()); buildTasks.Add(new StripUnusedSpriteSources()); buildTasks.Add(new CreateBuiltInResourcesBundle("UnityBuiltInResources")); //将CreateBuiltInShadersBundle改成自己创建的类 buildTasks.Add(new PostDependencyCallback()); // Packing buildTasks.Add(new GenerateBundlePacking()); buildTasks.Add(new UpdateBundleObjectLayout()); buildTasks.Add(new GenerateBundleCommands()); buildTasks.Add(new GenerateSubAssetPathMaps()); buildTasks.Add(new GenerateBundleMaps()); buildTasks.Add(new PostPackingCallback()); // Writing buildTasks.Add(new WriteSerializedFiles()); buildTasks.Add(new ArchiveAndCompressBundles()); buildTasks.Add(new AppendBundleHash()); buildTasks.Add(new PostWritingCallback()); // Generate manifest files // TODO: IMPL manifest generation return buildTasks; } [MenuItem("AssetBundles/GenerateAB")] public static void GenerateAB() { var outputPath = "Assets/AssetBundles"; if (!Directory.Exists(outputPath)) Directory.CreateDirectory(outputPath); BuildTarget targetPlatform = BuildTarget.StandaloneWindows; var group = BuildPipeline.GetBuildTargetGroup(targetPlatform); var parameters = new BundleBuildParameters(targetPlatform, group, outputPath); var buildInput = ContentBuildInterface.GenerateAssetBundleBuilds(); IBundleBuildContent content = new BundleBuildContent(buildInput); var taskList = AssetBundleBuiltInResourcesExtraction(); //创建自己的task ReturnCode exitCode = ContentPipeline.BuildAssetBundles(parameters, content, out result, taskList); if (exitCode < ReturnCode.Success) return; var manifest = ScriptableObject.CreateInstance<CompatibilityAssetBundleManifest>(); manifest.SetResults(result.BundleInfos); File.WriteAllText(parameters.GetOutputFilePathForIdentifier(Path.GetFileName(outputPath) + ".manifest"), manifest.ToString()); } 下記のコードはCreateBuiltInResourcesBundle.csからのもので,从CreateBuiltInShadersBundle.csから一つのクラスをコピーして、少しのコードを変更します: public ReturnCode Run() { HashSet<ObjectIdentifier> buildInObjects = new HashSet<ObjectIdentifier>(); foreach (AssetLoadInfo dependencyInfo in m_DependencyData.AssetInfo.Values) buildInObjects.UnionWith(dependencyInfo.referencedObjects.Where(x => x.guid == k_BuiltInGuid)); foreach (SceneDependencyInfo dependencyInfo in m_DependencyData.SceneInfo.Values) buildInObjects.UnionWith(dependencyInfo.referencedObjects.Where(x => x.guid == k_BuiltInGuid)); ObjectIdentifier[] usedSet = buildInObjects.ToArray(); Type[] usedTypes = ContentBuildInterface.GetTypeForObjects(usedSet); if (m_Layout == null) m_Layout = new BundleExplictObjectLayout(); //Type shader = typeof(Shader); //for (int i = 0; i < usedTypes.Length; i++) //{ // if (usedTypes[i] != shader) // continue; // m_Layout.ExplicitObjectLocation.Add(usedSet[i], ShaderBundleName); //} //上面是打包内置Shader的操作,改成全部资源就可以了 foreach (ObjectIdentifier identifier in usedSet) { m_Layout.ExplicitObjectLocation.Add(identifier, ShaderBundleName); } if (m_Layout.ExplicitObjectLocation.Count == 0) m_Layout = null; return ReturnCode.Success; } テスト結果は次のとおりです。 UnityのデフォルトのEffectをprefabにしてAssetBundleにパッケージ化します(Package名はpsです)。特殊効果に使用される内蔵アセットがすべてこのAssetBundleに含まれていることがわかります。 SBPでパッケージ化した後は、次のようになります。 psのAssetBundleにアセットがないことがわかります。生成された内蔵AssetBundleにはpsによって使用される3つの内蔵アセットがあり、psはUnityBuiltInResourcesのAssetBundleに依存します。 AssetBundle Q:SpriteAtlasについて、UIがレンダリング時に関連するSprite情報に従って対応するSpriteAtlaを見つけるということだと思いました。各UIレンダリングが同じAtlasを使用するようになり、Draw Callを減らすことができます。したがって、理論的には、Atlasの一枚で十分です。しかし、なぜAtlasのパッケージ化したAssetBundleには、Atlasに加えて、参照されている元の画像もあるのか。UIのAssetBundleパッケージにも、参照されている元の画像があります。 なぜそのような「冗長性」があるのか​​、そしてImageがアトラスを参照するのか画像を参照するのか?またはその原理は何ですか? 元のイメージがAtlasパッケージに配置されている場合、元のイメージはAtlasPackageに含まれていますが、UIPackageには含まれていません。元のイメージがAssetBundlePackageの外部に配置されている場合、AtlasPackageとUIPackageの両方に元のイメージがあります。それは何の原理でしょうか? A1:最初にこの記事を読むことをお勧めします: 【Unity游戏开发】SpriteAtlas与AssetBundle最佳食用方案(中国語注意) SpriteAtlasを適切に使用する場合、AssetBundleを解凍すると、Textureと複数のSpriteの2つのアセットが含まれていることがわかります。Texture はテクスチャであり、表示されるファイルサイズは大きいです。Spriteはテクスチャ全体でのスプライトのオフセット位置情報を記述したデータファイルとして理解でき、表示されるファイルサイズは小さいです。 したがって、これは冗長ではなく、正常です。 A2:ただし、確かに冗長性の問題があります。Prefab1とPrefab2が同じAtlasの Spriteを参照している場合、Atlasは少なくとも1つのAssetBundleにアクティブに含まれている必要があります。そうでない場合、2つのPackageに受動的に入力され、冗長性が発生します。 AtlasはAssetBundlePackageを設定しません。 Atlasは、AssetBundlePackageの1つにパッケージ化します。 Mesh Q:Meshのメモリ使用量に関して、Unity 2020のMeshにはどのような情報が表示されますか? ボーンをインポートする ここでボーンをインポートしないと、頂点情報が占めるスペースが2倍に減りますが、ボーンをインポートした後の頂点情報には何を増加しますか? ボーンをインポートしない 2番目の問題は次のとおりです。ボーンをインポートする場合、メモリ内のMeshは0.6MBを占有します。これは、上記のInspectorに表示されるもののほぼ2倍であり、他のモデルのテストも2倍です。 Read/Write Enabledを有効にすることが問題だと考えていましたが、このオプションがどうであれ、メモリ使用量は変わらないことがわかりました。このメモリ使用量はどのように発生しますか。また、Read/Write Enabledを有効にすると、2倍のメモリコストが発生しますか? テストの結果、ボーンをインポートせずに、Read/Write Enabledを有効にする場合は、有効にしない場合の2倍のメモリが必要となります。Read/Write Enabledを有効にしないと、Inspectorと同じメモリを占有することがわかりました。 ボーンをインポート時にRead/Write Enabledが有効になっているかどうかは、Inspectorインターフェイスの表示メモリの2倍です。ボーンがインポートされた後、モデルの頂点がデフォルトで変更されると推測されます。これは、デフォルトでRead/Write Enabledを有効にするのと同じです。 A:最初の質問: InspectorパネルのVertices列は、Meshの頂点属性(またはチャネル)を指します。Meshにチャネルのデータが含まれている場合、各頂点に頂点属性があることを意味します。 Unityによって定義された頂点チャネルは14があります。 ボーンがインポートされる場合、追加の頂点属性は頂点のボーンウェイトとボーンインデックスです。 Mesh.boneWeights()およびMesh.GetBonesPerVertex()を介してアクセスできます。 ただし、BoneWeightプロパティは、4つのfloat32と4つのint32、合計8×4=32Bytesを格納します。一つのBones indexは一つのByteに相当します。 (8×4+1)Byte/Vert x 5512Vert = 177.63KB 2番目の質問:ボーンアニメーションをインポートして、CPU側でスキニング計算を実行します。つまり、CPUで頂点属性を取得します。 UGUI Q:テストレポートでは、UGUI.Rendering.UpdateBatchesの使用量が多いと書かれています。それは何の原因でしょうか。 A1:シーンにあるTransformが変更されたUI要素が多すぎます。シーン内で変更されたCanvasが3つあり、これらの3つのCanvasの下Transformが変更された要素が312あるようです。 A2:CanvasのUI要素がCanvasRenderer.SyncTransformを何度も(数百回程度)トリガーすると、親ノードUGUI.Rendering.UpdateBatchesの時間も比較的高くなります。 テスト後、Unity 2018、2019、および2020のバージョンで、SetActive(true)を呼び出してUI要素をDeactive状態からActive状態に変更すると、UI要素が配置されているCanvas内のすべてのUI要素がCanvasRenderer.SyncTransformをトリガーします。 Unity 2017のバージョンでは、このような操作はこのSetActive(true)自体の要素にのみ影響します。UnityのBugなのか、このように設計されているのかはわかりません。ただし、Unity 2018、2019、および2020バージョンでは、Scaleを0または1に設定する方法を使用して、UIを非表示にできるため、Scanleが変更したUI要素のみがCanvasRenderer.SyncTransformをトリガーします。 Script Q:下図に示すように、プロジェクトを開けるとすぐにTimeline異常が報告されます。後で、Pluginsの下のDLLに関連していることがわかります。DLLTimelineを削除すると、正常になります。では、DLLがTimeline に影響を与えるのはなぜですか。Timelineのこれらのオーバーロードされた関数はUnityEditor.CoreModuleにあるはずだが、どうやって見つけられないでしょうか? A:Unityスクリプトには厳密なコンパイル順序があります: precompiled DLL -> asmdefs -> StandardAsset -> Plugins -> Plugins/Editor -> Assets -> Editor。 プリコンパイルされたDLLには、同じ名前が記述されたPlayableBehaviourクラスが含まれている可能性が高く、同じメソッドが実装されています。 このDLLは、Unityによって[Package]の[Timeline]の前にロードおよびコンパイルされます。Timelineをコンパイルすると、2つのPlayableBehaviourが検出されるため、書き換えに適した方法が見つかりません。 上記の考えに従って、エラーをローカルで再現しました。 このDLL(ConsoleApp1.dll)をPluginsディレクトリにスローすると、同じエラーが表示されます(DLLは元の質問と回答から取得できます)。 UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、パフォーマンス分析と最適化ソリューション及びコンサルティングサービスを提供している会社でございます。 今なら、UWA GOTローカルツールが15日間に無償試用できます!! よければ、ぜひ! UWA公式サイト:https://jp.uwa4d.com UWA GOT OnlineレポートDemo:https://jp.uwa4d.com/u/got/demo.html UWA公式ブログ:https://blog.jp.uwa4d.com
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

URPでのBRDF計算式の問題

1)URPでのBRDF計算式の問題 2)Job Systemがメインスレッドの時間を占めるという問題 3)ProfilerでTempBufferの問題を特定する 4)Unity2019でHDRPのカメラのGL線画の問題 5)UnityWebCamTextureによって取得されたカメラ画像が回転される Shader Q:最近URP Shaderを見ているときに問題が見つかりました。それが間違っているかどうかわかりませんが、最初にコードを貼り付けます。 1つ目は、URPのLighting.hlslでBRDFを初期化する部分です。 inline void InitializeBRDFData(half3 albedo, half metallic, half3 specular, half smoothness, half alpha, out BRDFData outBRDFData) { #ifdef _SPECULAR_SETUP half reflectivity = ReflectivitySpecular(specular); half oneMinusReflectivity = 1.0 - reflectivity; outBRDFData.diffuse = albedo * (half3(1.0h, 1.0h, 1.0h) - specular); outBRDFData.specular = specular; #else half oneMinusReflectivity = OneMinusReflectivityMetallic(metallic); half reflectivity = 1.0 - oneMinusReflectivity; outBRDFData.diffuse = albedo * oneMinusReflectivity; outBRDFData.specular = lerp(kDieletricSpec.rgb, albedo, metallic); #endif outBRDFData.grazingTerm = saturate(smoothness + reflectivity); outBRDFData.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(smoothness); outBRDFData.roughness = max(PerceptualRoughnessToRoughness(outBRDFData.perceptualRoughness), HALF_MIN); outBRDFData.roughness2 = outBRDFData.roughness * outBRDFData.roughness; outBRDFData.normalizationTerm = outBRDFData.roughness * 4.0h + 2.0h; outBRDFData.roughness2MinusOne = outBRDFData.roughness2 - 1.0h; #ifdef _ALPHAPREMULTIPLY_ON outBRDFData.diffuse *= alpha; alpha = alpha * oneMinusReflectivity + reflectivity; #endif } 私の理解では: outBRDFData.perceptualRoughnessは、粗さで、ラフネスと呼ばれるものです。 outBRDFData.roughnessは、粗さの2乗です。 outBRDFData.roughness2は、粗さの4乗です。 URPのLighting.hlslでBRDFを計算する部分を見てください。 // Based on Minimalist CookTorrance BRDF // Implementation is slightly different from original derivation: http://www.thetenthplanet.de/archives/255 // // * NDF [Modified] GGX // * Modified Kelemen and Szirmay-Kalos for Visibility term // * Fresnel approximated with 1/LdotH half3 DirectBDRF(BRDFData brdfData, half3 normalWS, half3 lightDirectionWS, half3 viewDirectionWS) { #ifndef _SPECULARHIGHLIGHTS_OFF float3 halfDir = SafeNormalize(float3(lightDirectionWS) + float3(viewDirectionWS)); float NoH = saturate(dot(normalWS, halfDir)); half LoH = saturate(dot(lightDirectionWS, halfDir)); // GGX Distribution multiplied by combined approximation of Visibility and Fresnel // BRDFspec = (D * V * F) / 4.0 // D = roughness^2 / ( NoH^2 * (roughness^2 - 1) + 1 )^2 // V * F = 1.0 / ( LoH^2 * (roughness + 0.5) ) // See "Optimizing PBR for Mobile" from Siggraph 2015 moving mobile graphics course // https://community.arm.com/events/1155 // Final BRDFspec = roughness^2 / ( NoH^2 * (roughness^2 - 1) + 1 )^2 * (LoH^2 * (roughness + 0.5) * 4.0) // We further optimize a few light invariant terms // brdfData.normalizationTerm = (roughness + 0.5) * 4.0 rewritten as roughness * 4.0 + 2.0 to a fit a MAD. float d = NoH * NoH * brdfData.roughness2MinusOne + 1.00001f; half LoH2 = LoH * LoH; half specularTerm = brdfData.roughness2 / ((d * d) * max(0.1h, LoH2) * brdfData.normalizationTerm); // On platforms where half actually means something, the denominator has a risk of overflow // clamp below was added specifically to "fix" that, but dx compiler (we convert bytecode to metal/gles) // sees that specularTerm have only non-negative terms, so it skips max(0,..) in clamp (leaving only min(100,...)) #if defined (SHADER_API_MOBILE) || defined (SHADER_API_SWITCH) specularTerm = specularTerm - HALF_MIN; specularTerm = clamp(specularTerm, 0.0, 100.0); // Prevent FP16 overflow on mobiles #endif half3 color = specularTerm * brdfData.specular + brdfData.diffuse; return color; #else return brdfData.diffuse; #endif } ここでの最終的な式は次のとおりです。 BRDFspec=roughness^2/( NoH^2*(roughness^2-1)+1)^2*(LoH^2*(roughness+0.5)*4.0) 次に、コードに記述されているアドレスであるUnityの2015年の記事を見てください。 コードにあるroughnessは、実際には画像のroughnessの2乗です。混乱を防ぐために、以下はroughness©和roughness(n)で表します。 roughness©=roughness(n)^2 これを見て、私は疑問を持っています。論文のroughness(n)+0.5 ステップはコードに対応したら、roughness©^0.5+0.5 はずだが、URPコードでroughness©+0.5を直接使用します。これは私の理解が間違っているか、それともURPのShaderが間違っているか。 A:未熟な見方ですが、私の結論は次のとおりです。 2乗roughness(n)^2プラス5は妥当です 1乗と2乗のどちらを使用してもほとんど違いはありません SIGGRAPHレポートの元のVF関数は次のとおりです。 使用される実際のVF関数は、上記の関数の近似値であり、画像に近い関数を使用して最適化します。 次のように作者は1乗と2乗をとる関数を画像化します。 2つの画像はそれほど違いがなく、傾向から見れば、2乗を取るのは元のVFに近いように見えます(Modified KSK and Schlick Fresnel depend on LH)。 作者は、Lighting.hlslのコードを変更して、最初の1乗を使用します。 outBRDFData.normalizationTerm=outBRDFData.perceptualRoughness*4 同じ画面でroughness(n)+0.5とroughness(n)^2+0.5 を使用してマテリアルを描画すると、ほとんど違いはありません。 グラフィックスの最初の法則によると、見た目が正しければ正しいので、両方が正しいことを理解するのは問題ありません。そうすれば、差が大きくなければ、掘り下げる必要がないということでしょうか。 Script Q:下図に示すように、Job Systemで実行したのにメインスレッドの時間を占めるのはなぜですか? A:子スレッドの実行が終了するのを待ちます。 Rendering Q:写真に示されているように、シーンにある2つのTempBufferはC#スクリプトから作成したわけではありません。シーンはAfterEffectsを使用せず、Grab PassのShaderも使用せずに、シーンカメラはMSAAとHDRをオフにしており、これら2つのTempBufferがまだあります。それを完全に取り除く方法は? これは、次の2つのことと関わりそうです。 A1:次のように設定してみてください:Camera.forceIntoRenderTexture = false; このオプションは、カメラを強制的にTempBufferにレンダリングします。 AfterEffectsを使用しない場合は手動でfalseに設定し、AfterEffectsを有効にすると自動的にtrueに設定します。したがって、After Effectsを使用する場合、TempBufferは避けられません。 A2:すべてのMonoBehaviorのOnRenderImage(RenderTexture source、RenderTexture destination)関数をブロックします。一般的に、各OnRenderImage(RenderTexture source, RenderTexture destination) 関数は一つのTempBufferを生成します。 A3:Grab RenderTextureは通常、Depthが最小のカメラのClear FlagsがDepth Onlyに設定されている場合に表示されます。 Rendering Q:Unity 2019.3.0f6で、GL線画を使うと、Gameビューにカメラが見つかりません。プロジェクトはHDRPプロジェクトに属しています。 A1:GL描画をGLDraws()に配置してください。Unity2020.2.2f1c1で、HDRP10.2.2環境で効果を正常に描画しました。 protected void OnEnable() { if (GraphicsSettings.renderPipelineAsset != null) RenderPipelineManager.endFrameRendering += OnCameraRender; } protected void OnDisable() { if (GraphicsSettings.renderPipelineAsset != null) RenderPipelineManager.endFrameRendering -= OnCameraRender; } protected void OnCameraRender(ScriptableRenderContext context, Camera[] cameraList) { foreach(var camera in cameraList) { if (CheckFilter(camera)) GLDraws(); } } Script Q:Unity WebCamTextureから取得したカメラ画像が回転されました。WeChatをスワイプしたところ、画像は正しいです。スマホを回転させると、画像は常に正しくて、回転の痕跡はありません。スマホが縦向きの場合は正常ですが、横向きに回転させると画像が正しくなくなります。 A:画面を回転させたときに、表示に使用するRawImageの回転を次のように調整できます。 UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、パフォーマンス分析と最適化ソリューション及びコンサルティングサービスを提供している会社でございます。 今なら、UWA GOTローカルツールが15日間に無償試用できます!! よければ、ぜひ! UWA公式サイト:https://jp.uwa4d.com UWA GOT OnlineレポートDemo:https://jp.uwa4d.com/u/got/demo.html UWA公式ブログ:https://blog.jp.uwa4d.com
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Unity] WindowsからMacに移行したらVisual Studio Codeが開かなくなった時の対処法(備忘録)

現象 WindowsからMacBookAirに新しく買い替えて、unityでゲーム開発をしようとしたら、unityからvisual studioが開けず、visual studioから開こうとするとエラー?が出る 出てたエラーは以下の画像 結論:とりあえずunity関連のものを全て再インストールしたら直った 試したこと ①unityの Package Managerからvisual studio Editorの設定を見直してみる 参考記事→Unity2020 でスクリプトをVisualSutudioで開けない問題の解消 結果⇨参考記事通りに進めるとunityからは問題なく開けるようになったが、エラー文は消えない ②visual studio code editorのパッケージを最新にアップデートする [Window]/[Package Manager]を開いて、「Visual Studio Code Editor」と「Visual Studio Editor」の両方をアップデートする 参考記事→UnityからスクリプトをVisual studioで開いてもコードが表示されない 結果⇨最新バージョンだったから意味なし ③visual studioをアンインストールして、もう一回設定し直してみる 結果⇨更なる問題が、、、 ④上記の問題を解決。(インストールとエラー、再度インストールを繰り返す、、、) 参考記事→Visual Studio for Mac のインストーラーで、インストール中にエラーが発生した時の対処方法(System.Net.WebException) 結果⇨インストーラーしか入らず、アプリケーションファイルからクリックして開くと謎の表示に飛び、適当にボタンぽちぽちしてたら意味わからんサイトに飛んだ 怪しそうだったのでダウンロードはしなかった? ⑤もう一度visual studioに関するものを消して再度インストールしなおす 結果⇨振り出しに戻る ⑥unity関連全て再インストール 結果⇨でけた 以上!!!!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Unity]UniTaskとTaskの違い

はじめに UniTaskとUnityに既存であるTaskとの違いメモ。 詳細テーブル Task UniTask 機能 Unityでは不要な機能が多い Unityで活用できる機能のみ実装 オブジェクトサイズ 大きい 小さい 実行コンテキストの管理 TaskScheduler、SynchronizationContext UnityのPlayerLoop 必要なC# Version C# 5.0以上 C# 7.0以上 TaskTracker なし UnityEditorで確認可能 メモリアロケーション 常にヒープ ゼロアロケーションで駆動する await時の制約 なし 同じUniTaskに対して2回awaitできない Task メインスレッドを動かしたまま、裏で通信を走らせたい時に使用できる。 複数の処理を同時に実行して、完了までの時間を短縮したい時に使用する。 描画には関係ない処理をメインスレッドから追い出して、動作の軽量化を図りたい時に使用する。 UniTask UniTaskとはUnity向けに最適化されたTask実装を提供するライブラリ郡。 Unity向けTask実装「UniTask/UniTask」。 UniTaskの稼働状況をモニタできる「UniTaskTracker」。 Unity向けIAsyncEnumerable実装「UniTaskAsyncEnumerable」。 名前空間「Cysharp.Threading.Tasks」 TaskScheduler / SynchronizationContext TaskSchedulerは、タスクと実際にタスクを実行するスレッドと間の調整をします。調整とはタスクをどのスレッドに割り当てるか、あるいはタスクを実行する順番を管理すること。 SynchronizationContextは、「指定した処理を指定したスレッドで実行するために用いるオブジェクト」。 TaskTracker Taskをチェックするツール。トラッキングを有効にしてスタックトレースを取得することは有用ですが、パフォーマンスに大きな影響を与えます。推奨される使い方は、タスクリークを見つけるためにトラッキングとスタックトレースの両方を有効にし、完了したら両方を無効にすることです。 メモリアロケーション プログラムが、自分の仕事で使うメモリを確保すること。 ヒープ 動的に確保と解放を繰り返せるメモリ領域のこと。 ゼロアロケーション プログラムが、自分の仕事で使うメモリを確保することがないこと。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【HDRと色彩管理1】光、色、色度図

前回のプロジェクトでHDR表示を作成した時、カラーマネジメントの内容をたくさん理解する必要があると気づきました。見れば見るほど複雑になるので、勉強しながらこの記事をまとめました。 この記事は5つのセクションに分かれています。このセクションでは、光と色、CIE 1931 RGB/XYZ色空間と色度図に焦点を当てて説明しようと思います。私はできるだけ自分なりに分かりやすく説明しようと思います。これらの概念が何なのか、この章を読んでいただければ、はっきりと答えられると思います。 たくさんの定義と名詞の警告!恐れないで。始めましょう! 1.1 我々はどうやって光や色を見るのか 色につき、考慮すべき3つの側面があります。 (1)オブジェクト (2)目 (3)脳 人間の目は非常に複雑な構造を持っており、機械を使って100%復元することは基本的に不可能です。人間の目にはいくつかの重要な構造があります。 (1)瞳孔(Pupil):虹彩(Iris)の真ん中にある円形の穴を指します。目の絞りに相当します。虹彩の働きにより自律的に大きさが変化して光量を調整しています。 (2)水晶体(Lens):光線が虹彩を貫いた後、水晶体を通過します。目のレンズに相当します。その幅を拡大または縮小することで、光の焦点範囲を制御できます。 (3)硝子体(Vitreous):水晶体によって屈折および集束された光は、硝子体を通過します。硝子体は、人間の目の大部分を満たし、網膜を支える厚い半透明のゲル状物質です。 (4)網膜(Retina):人間の目のフィルムに相当します。人間の目に渡された画像を受け取り、それらを電気インパルスに変換し、視神経によって脳に送信する役割を果たします。 (5)光受容体(Photoreceptors):網膜は光受容細胞で構成されており、桿体細胞(Rods)と錐体細胞(Cones)の2種類に分けることができます。 桿体:光に敏感であるため、夜間および周辺視野にとって重要ですが、光受容色素の不足で色覚を発達させにくいです(色を区別できない) 錐体:主に色の認識に関与し、明るい光でより良く役割を果たします。錐体光受容細胞には主に3つのタイプがあり、赤(約600 nmの波長)、緑(約550 nmの波長)、および青(約450 nmの波長)の光に最も敏感です。この視覚系は三色視覚と呼ばれます。これらの3種類の錐体はそれぞれ、長波(L)、中波(M)、および短波(S)に敏感であるため、L(ong)、M(edium)、およびS(hort)錐体と呼ばれます。 https://chrisbrejon.com/cg-cinematography/chapter-1-color-management/から 結局、脳はすべてのデータ信号を処理する責任を担います。たとえば、網膜にうつる像は上下左右が逆で、脳はそれを逆転します。したがって、実際、私たちが「見る」のは、実際に人間の目に当たる光ではなく、人間の目によって提供される信号に基づいて脳が再構築する効果です。 What we really see is our mind’s reconstruction of objects based on input provided by the eyes — not the actual light received by our eyes. —— From this article 人間の目の構造(3種類の錐体細胞)は、私たちが知覚できる色域の範囲を決定します。他の生き物と比較して、人間の目の色覚能力は非常に無味です。たとえば、シャコには16の異なる色覚細胞があります。しかし、以下で説明するように、幸いなことに3つしかありません。そうでなければ、カラーマネジメントシステムはますます複雑になっていたでしょう。 1.2光と色とは 世界では、最初に光があり、次に色がありました。 「光」とは? 光は通常、人間の目で見ることができる電磁波(可視光)を指し、視覚は可視光への知覚です。可視光は、電磁スペクトルの特定の部分にすぎず、一般に400〜700ナノメートル(nm)の波長の電磁波、つまり、紫外線より長く、赤外線より短い波長の電磁波として定義されます。資料により、可視光の波長範囲を定義する方法は異なっています。狭いものでは420〜680 nm、広いものでは380〜800nmの範囲です。 …光は高周波電磁波であると同時に、光子と呼ばれる素粒子で構成される粒子の流れでもあります。したがって、光は粒子と波動の両方の特性を同時に持つか、光は「波動粒子の二重性」を持ちます。 -ウィキから 一般に、光は電磁波の形で伝わるエネルギーの一種です。多色光を分散系(プリズムなど)で分割した後、光の波長(または周波数)に応じて順番に並べてパターンを形成することができます。このパターンをスペクトル(Spectrum)と呼びます。人間の目に見えるのは可視スペクトルの一部のみです。これらの可視スペクトルは波長が約400nmから750nmで、可視光と呼ばれます。 「色」とは? 色は、目、脳、および私たちの生活体験により、視覚的に感知された光の色の特徴であり、赤、オレンジ、黄色、緑、青、紫などの名前で光の色のカテゴリを表します。色への知覚は、可視スペクトルの電磁放射による人間の目の錐体細胞の刺激に由来します。色の種類と色の物理的仕様は、反射光の波長によってオブジェクトに関連付けられます。この反射は、光の吸収、発光スペクトルなど、オブジェクトの物理的特性によって決まります。しかし、色への知覚は、光の物理的性質だけでなく、心理学などの多くの要因も含みます。たとえば、色への知覚は、周囲の色の影響を受けることがよくあります。 普段いわゆる「色」とは、実際には、可視スペクトルの電磁放射による人間の目の錐体細胞の刺激です。しかし、脳の色の知覚は、光の物理的性質だけで決まるわけではありません。たとえば、色への知覚は、周囲の色の影響を受けることがよくあります。有名な青いドレスや白いドレスの事件を参照してください。 スペクトルの定義: スペクトルとは、複雑な波長の光が分散システム(グレーティング、プリズムなど)で分割された後、光の波長(または周波数)に応じて順番に形成されるパターンです。スペクトルの一部可視スペクトルは、人間の目に見える電磁スペクトルの唯一の部分であり、この波長範囲の電磁放射は可視光と呼ばれます。スペクトルには、人間の脳が視覚的に区別できるすべての色が含まれているわけではありません。それは茶色やピンクなどの色は単一の色ではなくさまざまな色で構成されているからです。 -ウィキから 生活では、スペクトルにある単色光があまりに見られません。さまざまな強度と波長の光が混合して豊富な色世界を形成しています。光を表現する方法の一つとして、横軸に波長、縦軸にスペクトル放射発散度(明るさ、強度、フラックス)をとるスペクトルパワー分布(PSD)を使用することができます。 Source: https://agraphicsguy.wordpress.com/2018/11/29/basic-color-science-for-graphics-engineers/ 簡単にまとめると、「光」は、スペクトルを使用して説明できる物理的な概念です。そして、「色」は、可視スペクトルの電磁放射による錐体細胞の刺激に基づいて人間の脳によって得られる視覚的な感知であり、感性的な色濃いが帯びられています。光と色は、理性と感性の絡み合いのように、離れることができません。 1.3色の量子化:カラーマッチング関数 スペクトルエネルギー分布マップは、実際に光を定量化する方法を提供します。可視光があれば、スペクトル上のすべての単一波長の光を横軸に、各単一波長のエネルギーを縦軸にし、2Dグラフを取得できます。レンダリングなどの多くの分野で、私たちが本当に気にかけているのは、各光の物理的特性ではなく、人間の目にどのような色が見えるかです。スペクトルエネルギー分布マップは、これらのフィールドについて記録する必要があるデータが多すぎます。結局のところ、可視単色光の波長範囲は400nmから750nmまでです。スペクトルエネルギー分布マップが光を定量化する一般的な方法であるというと、色を定量化するためのより簡潔な方法が必要です。 光の受信から色の表示まで人間の目はどのように働くかからヒントを得ました。脳の働きを考えると、脳に見えた色は、目の3種類の錐体細胞によって伝達された電気信号です。つまり、光のスペクトルエネルギー分布がどれほど複雑であっても、最終的に人間の脳に到達する信号源は常に3つだけです。さらに、スペクトル分布が完全に異なる2つの多色光があっても、錐体細胞を同じように刺激する限り、私たちの目からみれば、同じ「色」であるかもしれません。つまり、色と光の関係は1対多であり、メタメリズム(metamerism)としても知られている現象です。 このようにして、カラーマッチング実験が始まりました。3つの単一波長光を選択し、それらを三元光primariesと呼んでいます。可視スペクトルの単一波長光ごとに、各primaryの強度に対応する3つのパラメーターを見つけて、人間の目が同じように色を認識できるようにします。この方法で可視スペクトルのすべての単一波長光を測定すると、次のテーブルのように、関数r(λ)、g(λ)、b(λ)のセットを取得できます。 https://medium.com/hipster-color-science/a-beginners-guide-to-colorimetry-401f1830b65aから この一連の関数は、カラーマッチング関数です。歴史的にも、このような等色マッチング実験が多く行われました。最も有名で広く使用されている(1つ)のは、1931年のCIE1931RGBカラーマッチング関数です。 CIE(International Commission on Illumination国際照明委員会、略語がCOIではなくCIEである理由は、フランス語に由来するからである)は、1913年に設立された組織であり、光と色に関連する国際規格の開発に取り組んでいます。 CIE 1931 RGBで使用される三元光の波長は、700 nm(R)、546.1 nm(G)、および435.8 nm(B)です。 上記のカラーマッチング関数は負の値であることに注意してください。たとえば、上の図の610nmの波長の場合、その3つの関数値は次のようになります。 λ=610nm r(λ)= 0.34756 g(λ)= 0.04776 b(λ)= -0.00038 つまり、3つの正の値の三元光を使用することで、可視スペクトルのすべての単一波長光を表すことはできません。負の値を導入する必要があります。では、実験で「負の数の光」を取得するにはどうすればよいでしょうか。 520nmの波長での実験の概略図を以下に示します。 520nmのような明るい緑色を再現するには、「負の赤色光」を使用する必要があることがわかります。これは、Reference Lightの側面とPrimary Red Lightの反対側に特定の強度値を持つ赤色光を使用することで相殺できます。これは赤色光の値が負です。 次のアニメーションは、可視スペクトルの等色マッチング実験の完全なプロセスを示しています。 カラーマッチング関数は、単一波長の可視光源の測定を表しますが、光の重ね合わせにより、任意のスペクトルの光源に対してこのようなマッチング関数を実行できます。RGBを3次元空間の3つの座標軸とし、CIE 1931カラーマッチング関数の3つの関数を3次元空間に順番に描画すると、3次元空間にカラーラインを取得できます。この曲線はスペクトル軌跡(spectral locus)と呼ばれます。 この曲線を原点に向かって、または原点から離れてスケーリングすることにより、この空間内のさまざまな強度の単色光の表現を表すことができます。また、この曲線上の各点に原点を接続し、放射線が得られました。各光線を無限大の方向に延長して一つの曲面に形成しました。この曲面はさまざまな波長のさまざまな明るさの単色光を表します。この曲面で囲まれたボリューム空間は、さまざまな波長とさまざまな明るさの光源を混合することで観察できるすべての色を表します。下記のビデオは、このプロセスを非常に鮮明に示しています(出典:Call of DutyのHDR、このPPTはすごい): 上記の3次元空間は、CIE 1931RGB色空間(次のCIE 1931 XYZ色空間と混同しないように注意してください)であり、CIE1931RGB色マッチング関数の各データセットによって定義されます。任意の可視光について、その色空間の三刺激値(tristimulus values)を使用してそれを表すことができます(前述の条件付き等色現象を思い出してください。これは、同じ三刺激値を使用してスペクトル的に異なるさまざまな光源を表すこともできることを意味します) : Tristimulus values measure light intensity based on the three primary color values (RGB), typically represented by X, Y, and Z coordinates. The tristimulus values system is the foundation of color language, also referred to as the CIE color system, and is used to communicate precise color values around the world. —— From this article 人間の目に対応すると、スペクトルに対する3つの錐体の感度は、LMS色空間(Lは長い、Mは中間、Sは短い)を形成していると簡単に考えることができます。これは、色空間を簡単に定量化するために使用できます。 1.4最適化の維持:負の値を排除する 前述のように、CIE RGB色空間には負の値があり、これらの負の値はすべてRコンポーネントに表示されます。これらの負の値を排除するために、CIEは、RGB色空間から別の色空間XYZ色空間を拡張するという良いアイデアを思いつきました。3×3空間変換マトリックスを使用して、2つの色空間間で変換できます。 XYZ色空間の3つの基本ベクトルは、RGB色空間のような実際の物理的意味を持って実際の物理的な光ではなく、XYZの3つの軸は完全に想像されているため、XYZは想像色とも呼ばれます。これは、現実の世界でXYZ 3つの物理光を実際に構築し、上記のようにそれらに基づいてカラーマッチング実験を行うことができないことを意味します。しかし、XYZ色空間には多くの利点があります。最も明白なのは、XYZ色マッチング関数がすべて正であるということです。もう1つの重要な機能は、Y軸が意図的に選択されており、その方向が明るさ関数と一致していることです。つまり、Y値が大きいほど、明るさが大きくなります。さて、ここに新しい名詞の光度関数(luminosity function)があります。とりあえずスキップしましょう。 これはCIE1931XYZ色空間であり、カラーマッチング関数x(λ)、y(λ)、z(λ)によって定義されます。 このビデオは、RGB色空間からXYZ色空間への変換プロセスを非常に鮮明に表現していることに注意してください(出典:Call of DutyのHDR。)。 前述の新しい用語である光度関数について説明します。その定義は以下のように示します。 A luminosity function or luminous efficiency function describes the average spectral sensitivity of human visual perception of brightness. —— From wiki 簡単に言えば、人間の目は、同じエネルギーの条件下では、赤色光と青色光は緑色光よりも暗いと考えており、光度関数は、同じエネルギーで異なる波長の単色光に対する人間の目の光度知覚の変化を表します。 この関数は、色覚異常などの要因の影響を受ける可能性があります。下の図の緑(タンパク眼)、赤(緑の失明)、および黄色(CIE 1931標準)は、さまざまな条件下での光度関数曲線を表しています。 CIE 1931 XYZ色空間のY軸方向は、基本的に上記の光度関数曲線と一致しています(上の図から、CIE 1931 XYZ色空間の光度関数曲線とy(λ)関数曲線が基本的に一致していることがわかります)。つまり、XYZ空間で色のY値を観察することにより、色の明るさ情報を取得できます。 また、CIE1931XYZとCIE1931RGBは、同じ色データの異なる表現であることに注意してください。XYZ色空間にはさまざまな利点があるため、通常、このXYZ空間で色を定義して説明しますが、カラーデータをRGB空間に変換するには、3×3空間変換行列が必要です。 1.5次元削減を継続する:明るさを排除する XYZ色空間は素晴らしいですが、そのような3次元空間で色を議論するのは少し難しいです。多くの場合、実際には色の彩度と飽和度のみを考慮し、明るさは考慮しません。つまり、色の表現を3次元から2次元の表現に減らすことができます。一般に、XYZ色空間から平面X + Y + Z=1に色を投影できます。この2次元色度色空間(chromaticity color space)は、CIE 1931 xyz色空間と呼ばれます(本当に小文字の名前に変更しただけです)。x+y + z = 1という制約がある場合、色度を指定するために実際に必要な値は2つだけです。通常、xyを残してzをドロップすることを選択します。つまり、上記のx + y + z = 1平面をXY平面に再投影して、色度を指定するためにxy値のみを使用できるようにします。 これは有名なCIE1931xy chromaticity diagram(つまり色度図)であり、明るさを考慮せずに見ることができるすべての可視色を表しています。 この馬蹄形の境界は、単色光の各波長に対応する色、つまりスペクトル軌跡(spectral locus)に対応します。 スペクトル軌跡線で囲まれた領域は、さまざまな波長の単色光を混合することで知覚できる色を表しています。 色度図は、色について話し合うための基準を提供します。あらゆる分野の人々が、ハードウェアの表示などの要因による曖昧さなしに、色度図の特定の色について話し合うことができます。 UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、パフォーマンス分析と最適化ソリューション及びコンサルティングサービスを提供している会社でございます。 今なら、UWA GOTローカルツールが15日間に無償試用できます!! よければ、ぜひ! UWA公式サイト:https://jp.uwa4d.com UWA GOT OnlineレポートDemo:https://jp.uwa4d.com/u/got/demo.html UWA公式ブログ:https://blog.jp.uwa4d.com
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Unity] modelのmaterialをmask用のmaterialに切り替える

初めに Unityを使ったアニメーション制作が最近でもチラホラ記事になる事があります。 そこで出力した絵にレタッチする際にマスク画像が必要になる事があります。 イメージはこんな感じ Unityちゃんの元に設定されているmaterialからスクリプトで切り替えることで、マスクみたいな モデルにします。 機能説明 機能として、モードを2つ用意しました。 ※Colorモード ChangerMaterialsに設定される、Colorはランダムで指定されています。 そのカラーを使って、設定されます。 MaterialShaderとMaterialShaderColorNameはランダムでスクリプトで 指定するShader名とColorのプロパティ名です。 Materialをプログラムで生成するので、マテリアルに適用するshderと色を指定する プロパティ名を指定してあげます。 ※Nameモード ChangeSearchNameにマテリアル名の後ろに指定されているマテリアルを 探し、設定します。 スクリプト using UnityEditor; using UnityEngine; using System.Linq; using System.Collections.Generic; [System.Serializable] public class ChangerData { public SkinnedMeshRenderer ren; public Material mat; public Color col; } public class MaterialChanger : EditorWindow { [MenuItem("Tool/MaterialChanger")] public static void Open() { var window = GetWindow<MaterialChanger>(); window.Show(); } public enum eSelect { Color, Name, }; private GameObject _gameObject = null; //スクロール位置 private Vector2 _scrollPosition = Vector2.zero; private bool _changeToggle = true; private readonly int _directoryIndex = 1; private eSelect _select = eSelect.Color; private string _changeMaterialShader = "Unlit/Color"; private string _changeMaterialShaderColorName = "_Color"; private string _changeSearchName = "_change"; private MaterialPropertyBlock m_mpb; public MaterialPropertyBlock mpb { get { return m_mpb ?? (m_mpb = new MaterialPropertyBlock()); } } [SerializeField] private List<ChangerData> _changerMaterials = new List<ChangerData>(); /// <summary> /// /// </summary> void OnGUI() { // 自身のSerializedObjectを取得 var so = new SerializedObject(this); //描画範囲が足りなければスクロール出来るように _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition); EditorGUI.BeginChangeCheck(); _gameObject = EditorGUILayout.ObjectField("root object", _gameObject, typeof(GameObject), true) as GameObject; if (EditorGUI.EndChangeCheck() && _gameObject) { Init(); } if (_gameObject) { _select= (eSelect)EditorGUILayout.EnumPopup( "select", _select); switch (_select) { case eSelect.Name: _changeSearchName = EditorGUILayout.TextField("ChangeSearchName", _changeSearchName); break; case eSelect.Color: _changeMaterialShader = EditorGUILayout.TextField("MaterialShader", _changeMaterialShader); _changeMaterialShaderColorName = EditorGUILayout.TextField("MaterialShaderColorName", _changeMaterialShaderColorName); break; } _changeToggle = EditorGUILayout.Toggle("ChangeToggle", _changeToggle); //切り替え if (GUILayout.Button("MaterialChang")) { MaterialChang(); } EditorGUILayout.PropertyField(so.FindProperty("_changerMaterials"), true); } so.Update(); so.ApplyModifiedProperties(); //スクロール箇所終了 EditorGUILayout.EndScrollView(); } /// <summary> /// /// </summary> private void Init() { // Listクリア _changerMaterials.Clear(); // 指定オブジェクト以下のレンダラーを取得 var rens = _gameObject.GetComponentsInChildren<SkinnedMeshRenderer>(); foreach( var ren in rens) { var mats = ren.sharedMaterials; foreach (var mat in mats) { ChangerData data = new ChangerData(); data.mat = mat; data.ren = ren; data.col = new Color(Random.value, Random.value, Random.value, 1.0f); _changerMaterials.Add(data); } } } /// <summary> /// 切り替え用のデータからマテリアル取得 /// </summary> /// <param name="data"></param> /// <returns></returns> private Material GetNameToMaterial( ChangerData data ) { var name = data.mat.name; if (_changeToggle) { name += _changeSearchName; } //名前から切り替え用のマテリアルを探してロードする var guids = AssetDatabase.FindAssets(name); if (guids.Length == 0) return null; var paths = guids.Where(_ => AssetDatabase.GUIDToAssetPath(_).Contains(".mat")).Select(guid => AssetDatabase.GUIDToAssetPath(guid)).ToArray(); if (paths.Length == 0) return null; var objects = AssetDatabase.LoadAllAssetsAtPath(paths[0]); if (objects.Length == 0) return null; // LoadAllAssetsAtPathでロードしたオブジェクトのどこにマテリアル設定されているか調べる var objIndex = 0; for (var i = 0; i < objects.Length; i++) { if (objects[i] is Material) { objIndex = i; break; } } return objects[objIndex] as Material; } /// <summary> /// /// </summary> private void MaterialChang() { //Debug.Log("MaterialChang"); foreach (var changerMaterial in _changerMaterials) { // マテリアルがレンダラーにいくつか設定されているから // indexを調べる var index = changerMaterial.ren.sharedMaterials .Select((p, i) => new { Content = p, Index = i }) .Where(_=> _.Content != null) .Where(_ => _.Content.name.Contains(changerMaterial.mat.name)) .Select(ano => ano.Index).First(); // マテリアル作成 var mat = new Material(Shader.Find(_changeMaterialShader)); //元に戻すために、マテリアル名を指定する var mats = changerMaterial.ren.sharedMaterials; //ランダムカラーを指定するか、名前でスワップするか switch (_select) { case eSelect.Color: mat.name = changerMaterial.mat.name; break; case eSelect.Name: mat = GetNameToMaterial(changerMaterial); break; } // 設定するマテリアルがnullだった場合は、切り替えをしないでcontinue if (mat == null) continue; // マテリアルをスワップするか、切り替え前のマテリアルを指定するか mats[index] = (_changeToggle ? mat: changerMaterial.mat); if (_changeToggle && eSelect.Color == _select) { // この時点ですでにほかのスクリプトなどからMaterialPropertyBlockが // セットされているかもしれないので、まずは取得する changerMaterial.ren.GetPropertyBlock(mpb); // MaterialPropertyBlockに対して色をセットする mpb.SetColor(_changeMaterialShaderColorName, changerMaterial.col); // MaterialPropertyBlockをセットする changerMaterial.ren.SetPropertyBlock(m_mpb); } else { if (m_mpb != null) { changerMaterial.ren.GetPropertyBlock(mpb); mpb.Clear(); m_mpb = null; } } //render Materialにセット changerMaterial.ren.sharedMaterials = mats; } AssetDatabase.Refresh(); } } スクリプトの説明 ランダムカラーで指定する際に使用しているのがMaterialPropertyBlockを使っています。 これを使えば、自分で数分マテリアル用意しなくても便利です。 LoadAllAssetsAtPathどうやらロードしたデータに適応されている、コンポーネント全部引っ張ってきてくれる 結構優秀なやつでした。ただ、欲しいコンポーネントなのかは、中身全部調べて見るしか無いでした。 プロジェクトの中のオブジェクトを探して参照する手段として AssetDatabase.FindAssetsでオブジェクトのGUIDを調べて AssetDatabase.GUIDToAssetPathでGUIDからオブジェクトのパスしらべて AssetDatabase.LoadAllAssetsAtPathパスからアセットをロードします。 最後に プロジェクトの中からロードするのをもっといい方法がないのかなって思いました。 アニメのレタッチするように必要と言われて作ったのですが、これがどんな風に利用されるかは。。 まだわかってませんので、もしこんな機能が欲しいって言ってくれたらアップデートします。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む