【问题标题】:Selecting a material from a list, storing it and then returning the material as a new mater从列表中选择一种材料,将其存储,然后将该材料作为新材料返回
【发布时间】:2021-07-30 22:45:41
【问题描述】:

我对 C# 相当陌生,并尝试在 Unity 中生成一个脚本,该脚本获取网格和材质列表,然后通过输入搜索列表中的项目并挑选具有相同输入的项目。 获取输出的新网格并将其存储在新的材质/网格中。 这背后的想法是利用孤立的网格和材质创建一个字典,这意味着某些网格将仅使用基于其命名约定的某些材质。

我已经设法对网格进行了处理,它们将对象作为新网格返回。

然而,另一方面,即使它们遵循相同的逻辑,材料也会输出错误“错误 CS1729:'Material' 不包含采用 0 个参数的构造函数”

任何人都可以提出解决方案,因为我一直在努力寻找解决方案。

我看了一遍,似乎找不到解决问题的方法,我觉得它会很简单。 我查看了许多文档并通读了统一文档,但对我来说没有任何意义。

编辑:我正在使用通用渲染管线/卡通着色器

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.SceneManagement;
using System.Diagnostics;


public class CharacterCreationMaster : MonoBehaviour
{


    //reference for unity to check
    [Header("Meshes to change")]
    public List<MeshFilter> changeMesh = new List<MeshFilter>();

    //Drag all of the objects that you need edit 
    [Header("Meshes to cycle through")]
    public List<Mesh> meshOptions = new List<Mesh>();

    //all the materials that you need to edit
    [Header("Materials to cycle through")]
    public List<Material> materialOptions = new List<Material>();


    Material materialIsolator(string input)
    {

        Material peephairMat;

        //UnityEngine.Debug.Log("Hello");
        for (int i = 0; i < materialOptions.Count; i++)
        {
            //UnityEngine.Debug.Log("We are printing the name of the material. " + materialOptions[i].name);
            if (string.Compare(materialOptions[i].name, input) == 0)
            {
                peephairMat = materialOptions[i];
                UnityEngine.Debug.Log("we have selected " + materialOptions[i]);
                return peephairMat;
            }
        }
        return new Material();

    }


    Mesh meshIsolator(string input)
    {

        Mesh peepHair;

        //UnityEngine.Debug.Log("Hello");
        for (int i = 0; i < meshOptions.Count; i++)
        {
            //UnityEngine.Debug.Log(meshOptions[i].name);
            if (string.Compare(meshOptions[i].name, input) == 0)
            {
                peepHair = meshOptions[i];
                //UnityEngine.Debug.Log("we have selected " + meshOptions[i]);
                return peepHair;
            }
        }

        //UnityEngine.Debug.Log("We have created a new mesh.");
        return new Mesh();

    }


    void Start()
    {

        Mesh finsHair = meshIsolator("fin-Hair");
        Mesh quinsHair = meshIsolator("quin-Hair");
        Mesh nailsHair = meshIsolator("nail-Hair");


        //Material quin1HairMats = materialIsolator("Quin1_Hair");
        //Material quin2HairMats = materialIsolator("Quin2_Hair");
        //Material quin3HairMats = materialIsolator("Quin3_Hair");

    }
}

【问题讨论】:

  • docs.unity3d.com/ScriptReference/Material-ctor.html 请参见此处的参考资料 - 创建新的 Material 需要您传递 Shader 实例或现有的 Material 实例 - 没有接受 0 个参数的构造函数。听起来您可能想克隆现有材料?
  • 是的,材料列表的值中的材料与输入的值相同。我想克隆该材料,但不确定该怎么做。
  • 我不确定我是否理解 - 您正在材料列表中搜索与 input 值匹配的材料,然后您返回相同的材料(不是克隆)。只有当您没有找到该材料时,您才会尝试退回新材料。当你 a: 找到匹配的材料 b: 没有找到匹配的材料时会发生什么?
  • 当您找到匹配的材料时,我想将其作为新材料返回,以便我可以将该新材料用作字典中键和值对的值。如果找不到材料,我不希望脚本做任何事情,或者更确切地说我希望它停止。
  • 好的,所以返回 null 作为值。对于匹配的材料,如果你真的需要一个克隆,返回一个克隆或者只返回现有的材料(我看不到你是如何使用这个脚本的,所以我不能评论你是否需要一个克隆)。函数底部的return null 将返回一个不代表任何Material 的空对象 - 然后您可以在调用此函数时检查返回值是否为空,并据此决定做什么。

标签: c# unity3d


【解决方案1】:

好的,我会提出一些小的调整 - 我假设您将其用作编辑器面板或其他什么?

    Material materialIsolator(string input)
    {
        // First of all, you can use a foreach or Linq here to grab a matching instance
        // Looping over arrays using a for loop is not required when using List<T> types
        // so either...
        foreach(var material in materialOptions) 
        {
            if (material.name == input) {
                // Do you actually need a new material or just a ref to the existing material?
                return new Material(material);
        }

        // return null if nothing can be found with this name
        return null;
    }

或者只使用 LINQ:

    Material materialIsolator(string input)
    {
        return materialOptions.FirstOrDefault(material => material.name == input);
    }

    // which actually means you don't need the function in the first place and can just use

    Mesh nailsHair = materialOptions.FirstOrDefault(material => material.name == 'nail-Hair');

唯一的问题是,你需要一个新的材料还是原始材料的参考,在这种情况下你只需要用new Material(&lt;object here&gt;)包装返回的对象

【讨论】:

  • 所以我选择了 return null;选项。这主要是因为一旦我隔离了材料,我就不需要对它做任何事情,我只需要隔离它然后将它应用到字典中。为此,它已经奏效,我现在可以继续进行该项目。谢谢。
【解决方案2】:

问题出在以下行:

return new Material();

Material 需要将着色器传递给构造函数。因此,您要么必须将现有材质作为默认值返回,要么将着色器传递给构造函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    相关资源
    最近更新 更多