首页 > 解决方案 > 如何用随机图像制作对象?

问题描述

我很难处理材质,为了让我的游戏更具动态性,我想在我的对象上应用一些皮肤。我尝试将网格渲染器上的材质大小设置为 3 并应用 3 个材质,但看起来不太好因为我必须关闭第三种材料,或者第二种和第三种需要保持活动状态。我的第一种材料是颜色,它必须保持不变。

我的意思很容易用照片说出来..

这是我的立方体对象,默认使用一种材质,看起来很完美: 在此处输入图像描述

这是我添加第二种材料时想要查看的内容: 在此处输入图像描述

这是当我添加第三个材料时,第二个仍然处于活动状态,我只需要处于活动状态的第二个或第三个不活动的第二个和第三个

在此处输入图像描述

所以问题是在我的情况下,我只希望在我的示例中我的对象上只有两种材料处于活动状态,第一个总是需要在我的照片中命名为“新材料 2”

然后我只需要第二个或第三个在我的案例上再激活一个,我有问题,因为所有材料都是活动的,然后我的对象看起来不像我想要的样子。我想让随机脚本将它附加到每一个对象在网格中制作 10 种材料并始终激活第一个并从 1 到 10 中选择随机数并在开始时仅激活那个。

同样在统一中->当我添加第二种材料并且我需要将它用于皮肤时,Unity会抱怨也许有更好或正确的方法来做同样的事情..但我只找到了这个解决方案..

所以我的问题是如何给我的立方体皮肤添加多个皮肤并随机选择它们,默认材料或颜色将始终处于活动状态。

非常感谢社区,我不知道没有你我该怎么办!

标签: c#unity3dmeshgame-development

解决方案


您可以为此制作一个简单的组件:

[RequireComponent(typeof(Renderer))]
public class RandomMaterial : MonoBehaviour
{
    // Now in this list add all materials that shall be
    // options for the random selection
    [SerializeField] private Material[] materials;

    // Either already reference this in the Inspector
    // or get it later on runtime
    [SerializeField] private Renderer renderer;

    private void Awake()
    {
        if (!renderer) renderer = GetComponent<Renderer>();

        // A little check
        if(materials.Length == 0)
        {
            Debug.LogWarning("No Materials referenced! -> Ignored", this);
            return;
        }

        // get random index for material
        // first parameter is inclusive - second is exlusive
        // => index will be between 0 and materials.Length -1
        var index = Random.Range(0, materials.Length);
        var selectedMaterial = materials[index];

        // create a new array for 2 Materials
        // you can't simply assign renderer.materials[1]
        // because you don't know if there already are two spots
        // available in that array
        // also makes sure there no other materials left but only those
        // two you will add in the next lines
        var rendererMaterials = new Material[2];
        // keep the first (main) material
        rendererMaterials[0] = renderer.material;
        // set selected material as second material
        rendererMaterials[1] = selectedMaterial;
        // assign the new materials to the object
        renderer.materials = rendererMaterials;
    }
}

根据您的需要,您可能还需要考虑使用renderer.sharedMaterials并相应rendererMaterials[0] = renderer.sharedMaterial;地使用全局材质而不是实例材质。这意味着如果您稍后更改renderer.sharedMaterial|s属性,它将影响场景中使用该共享材质的每个 renderer。否则,如果您更改Renderer.material|s属性,它会创建一个新的 Material 实例,该实例只会影响这个单一Renderer的 .


推荐阅读