通常は、どんなゲームアセットに修正を加えたい場合でも、ランタイムに一時的に行うことが望ましいといえます。例えば、キャラクターが無敵なほどパワーアップしたとしたら、プレイヤーキャラクターの Material の Shader を変更して、視覚的に無敵のステートを実際に示したいかもしれません。これには、使用されるマテリアルを修正する必要があります。__再生モード__を終了するときに、マテリアルに別のシェーダーを設定したくないため、この修正は永続的ではありません。
しかし、Unity で永続的なソースアセットを修正するスクリプトを書くことが可能です。例えば前述のマテリアルの例をスタート地点として使用します。
マテリアルのシェーダーを一時的に変更するには、material コンポーネントの shader プロパティを変更します。
private var invincibleShader = Shader.Find ("Specular");
function StartInvincibility {
renderer.material.shader = invincibleShader;
}
スクリプトを使用して再生モードを終了する場合、material の状態は最初に再生モードに入る前の値にリセットされます。これは renderer.material がアクセスされるときは常に、マテリアルが自動的にインスタンス化されて、インスタンスが返されるためです。このインスタンスは同時に、かつ、自動的にレンダラーに適用されます。このため永続的に反映されることを心配せずに変更を行うことができます。
次に実行モードを終了したときに、マテリアルをリセットしたくないとします。これには、renderer.sharedMaterial を使用できます。sharedMaterial プロパティはレンダラーによって使用される実際のアセットを (場合によっては他のものも) 返します。
以下のコードによりマテリアルが鏡面シェーダーを使用するように永続的に変更を行います。実行モードに入る前の状況にマテリアルをリセットしません。
private var invincibleShader = Shader.Find ("Specular");
function StartInvincibility {
renderer.sharedMaterial.shader = invincibleShader;
}
このように、sharedMaterial への変更を行うことは便利ですが、リスクも伴うものです。sharedMaterial への変更は永続的であり、元に戻すことができません。
この同じ法則はマテリアル以外でも適用できます。このルールに従うすべてのアセットは以下のとおりです。
上記のクラスのいずれか (Material、Mesh、または Physics Material) でパブリック変数を宣言して、関連するクラスメンバーではなく変数によりアセットに変更を加えた場合、修正が適用される前の自動インスタンス化によるメリットは得られません。
修正したときに必ず自動的にインスタンス化されない 2 つの異なるアセットがあります。
スクリプティングを通してこれらのアセットに加えた変更は常に永続的であり、元に戻すことができません。このため、Terrain の Height Map をスクリプティングを通して変更する場合、インスタンス化および値の割り当てをカスタムで検討する必要があります。テクスチャについても同様です。テクスチャファイルのピクセルを変更した場合、変更は永続的です。