在Unity中,如何通过值复制GameObject,以便在实例化之前对其进行修改?

时间:2017-08-25 09:33:35

标签: c# unity3d unity5

我正在尝试创建一个城市建设者,而我正在编写游戏的一部分,在您实际放置它之前创建一个透明的建筑物渲染。我想做的只是在代码中复制GameObject,修改材质的透明度,删除一些组件,然后实例化它。

存在一个问题:Unity中的所有内容都是通过引用传递的。有没有办法做我想做的事情,或者没有这样的方式吗?

4 个答案:

答案 0 :(得分:2)

如果要通过组合在运行时实例化的几个GameObject来创建场景,可以创建一个名为generateEnviroment.cs的脚本(只是一个示例名称),然后您应该将一个或多个GameObjects作为属性从检查器传递给该脚本

下一步是实例化正确的gameObject,然后根据需要修改其属性(位置,大小,材料......)。每个实例都是独立的,具有您可以根据需要修改的属性,并且不会更改同一GameObject的其他实例。

public GameObject customGameObject1;
public GameObject customGameObject2;

void Start()
{
    generateEnviroment()
}


void generateEnviroment()
{
    //In case you want to add other type of GameObject, like a car or sth you have created:
    GameObject myInstantiatedGameObject = GameObject.Instantiate (customGameObject1);

    //You change its position
    myInstantiatedGameObject.transform.position = new Vector3(0, 0.5F, 0);

    // Widen the object by 0.1
    myInstantiatedGameObject.transform.localScale += new Vector3(0.1F, 0, 0);

    //Change material properties, assuming it has a material component
    Renderer rend = myInstantiatedGameObject.GetComponent<Renderer>();
    rend.material.shader = Shader.Find("Specular");
    rend.material.SetColor("_SpecColor", Color.red);
    ...

}

你甚至可以在GameObject中添加一个脚本组件,你也可以独立地为每个GameObject实例访问和修改该脚本中的每个属性(变量)(只要你不声明)该属性为静态)

答案 1 :(得分:0)

您无需创建游戏对象的副本。只需实例化它并将值更改为临时放置状态。与设置材料属性一样,在最终放置建筑物时禁用子对象等,只需重置更改。

答案 2 :(得分:0)

实例化是你在Unity中复制对象的方式。

如果实例化对你来说很慢,只需在场景加载时实例化你需要的每个对象,并在需要时禁用/启用它们。

这样您就可以在启用和/或将其移动到最终位置之前更改属性。

以下调用应使其透明。

instantiatedObject.GetComponent<MeshRenderer>().material.color = new Color(0.0f, 0.0f, 0.0f, 0.0f);

请查看以下3个链接:

https://docs.unity3d.com/Manual/InstantiatingPrefabs.html

https://unity3d.com/de/learn/tutorials/topics/scripting/instantiate

https://docs.unity3d.com/ScriptReference/Color.html

答案 3 :(得分:0)

正如大家已经说过的那样,使用GameObject.Instantiate可以创建预制件或场景对象的副本。您无法延迟对象的 instanitiation (将其置于场景中),但您可以延迟其启动调用(例如StartAwake)。您只需复制一个不活动的对象,修改您想要的任何内容,然后手动激活它。那是你在找什么?

static GameObject InstanitateDelay(GameObject source)
{
    bool isActive = source.activeSelf;
    source.SetActive(false); // disable it temporarly
    var go = Instantiate(source); // create inactive copy
    source.SetActive(isActive); // return to previous state
    return go;  // remeber to activate manually via go.SetActive(true)
}