Unity 2Dゲームのタイリング、マテリアルスケーリング

Unityで2Dゲームを開発する場合、多くの場合、同じ素材からさまざまなサイズの多くの要素を作成する必要があります。 最も単純な例は、あらゆる種類のプラットフォーマーの土、草、石、その他の要素のタイルです。 原則として、同一のタイルはデフォルトで同じマテリアルを使用します(そうでなければ、以前に作成されたマテリアルの数が多すぎます)。 多くの場合、基本タイルからレベルフレームを作成することは、レベル上のオブジェクトが多すぎるため不便な場合があります。そのため、基本タイルの代わりに、大きなタイルが使用されます。 地上に2つの草のセクションを「植える」必要があるとします。



画像







この図では、地面の上に、サイズが1x1の9つの独立した芝生タイルがあります。 Ctrl + C、Ctrl + Vを使用すると、右側の8つのタイルは正常に配置されましたが、レベルが数百の芝生タイルであり、レベル自体が数十でなければならない場合、単一のタイルの配置には時間がかかりすぎます。 この種のタスクに最適なソリューションは、単一のタイルをスケーリングすることです。 つまり この場合、草の一部をコピーし、結果のオブジェクトをX軸に沿って8回引き伸ばす必要があります(たとえば、エディターのインスペクターで)。これは次のようになります。



画像



結果は受け入れられるとはほとんど言えません。 通常のスケーリングでは、オブジェクト自体に加えて、このオブジェクトのマテリアルのスケール(エディタ、[インスペクタ]タブ)、つまりTilingパラメータを変更する必要があります。



画像



次の結果が得られます。



画像



ご覧のとおり、8タイルのブロックは意図したように見えますが、左側の1タイルのブロックは8倍縮小しました。 問題は、これらの2つのオブジェクトが同じマテリアルを使用しているため、一方のオブジェクトのマテリアルを変更すると、他方のオブジェクトのマテリアルも変更されることです。

この問題は、次の方法で解決できます。各オブジェクトには、transform.sharedMaterialコンポーネント-これは共通のマテリアルであり、transfrom.materialコンポーネント-このコンポーネントが変更されると、オブジェクトで使用されるマテリアルのコピーが作成されます。他のオブジェクトに影響を与えずに変更できます。 簡単なスクリプトを作成しましょう:



TexTilingScript.js



scaleMaterial(); function scaleMaterial() { //       renderer.material.mainTextureScale.x = transform.localScale.x; renderer.material.mainTextureScale.y = transform.localScale.y; }
      
      







このスクリプトは、オブジェクトの初期化中にオブジェクトの新しいマテリアルを作成およびスケーリングします。 このスクリプトを両方のオブジェクトに追加します。 [再生]をクリックすると、次の結果が得られます。



画像



人生は美しいように思えますが、1つの「しかし」があります。そのような結果は「ゲーム」の間にのみ得られ、編集中はすべてがまだ悲しいです:



画像



期待される結果、 スクリプトは、アプリケーションの起動時にのみ実行されます。 編集中にマテリアルを正しくスケーリングするには、このスクリプトのハンドラーをエディターに追加する必要があります。 これを行うには、Assets / Editorフォルダーに別のスクリプトを作成します。



TexTilingEditorScript.js



 @CustomEditor(TexTilingScript) class TexTilingEditorScript extends Editor { function OnSceneGUI () { //    TexTilingScript     ,     var script = target as TexTilingScript; //        script.scaleMaterial(); } }
      
      







このスクリプトは、TexTilingScriptコンポーネントを持つオブジェクトのscaleMaterial関数を、画面上でそのようなオブジェクトが選択されるたびに(たとえば、マウスで選択されるたびに)呼び出し、受信した変更を保存します。



画像



1つを除くすべてが正常です-エラーがログに表示されます:

編集モード中にrenderer.materialを呼び出すためにマテリアルをインスタンス化します。 これにより、マテリアルがシーンにリークされます。 ほとんどの場合、代わりにrenderer.sharedMaterialを使用します。

事実は、編集中にオブジェクトのマテリアルを変更することです。新しい一時的なマテリアルを作成します。これはアプリケーションの起動後に削除されます。 Unity開発者がこのケースを警告ではなくエラーとして設計した理由を心から理解していません。 この調整は非常に受け入れられ、競合を引き起こしません。 しかし、誰かが赤い色に悩まされている場合-自分のアドバイスに従うことができます-スケーリングするには、renderer.materialではなくrenderer.sharedMaterialを使用できます。それでも、このオプションは受け入れ可能で便利であると考えることができます。 新しいscaleSharedMaterial()関数をTexTilingScriptに追加します。



TexTilingScript.js



 scaleMaterial(); function scaleMaterial() { //       renderer.material.mainTextureScale.x = transform.localScale.x; renderer.material.mainTextureScale.y = transform.localScale.y; } function scaleSharedMaterial() { //   ,      renderer.sharedMaterial.mainTextureScale.x = transform.localScale.x; renderer.sharedMaterial.mainTextureScale.y = transform.localScale.y; }
      
      







TexTilingEditorScriptスクリプトで、呼び出されたf番目を変更します。





TexTilingEditorScript.js



 @CustomEditor(TexTilingScript) class TexTilingEditorScript extends Editor { function OnSceneGUI () { //    TexTilingScript     ,     var script = target as TexTilingScript; //     script.scaleSharedMaterial(); } }
      
      







これで「エラー」は表示されなくなりましたが、編集中にオブジェクトのマテリアルを正しくスケーリングするには、最初にそれを選択する必要があります。 また、非常に受け入れられるオプションです。

さて、この問題を解決するための別のオプションは、事前に各オブジェクトに独自のマテリアルを作成することです。 ただし、プロジェクトソースに何百もの事前に作成された資料があるとは限らないため、1つだけを実行できる場合は、スクリプトを使用することが最良のソリューションの1つです。



すべてのスクリプトはJavaScriptで記述されています。 Unity 3.3、Pro。



All Articles