更改对象会更改所有实例化对象

时间:2015-04-18 08:48:34

标签: c# unity3d material

我知道问题的主题已经被提出并且已经给出了一些答案,但我再次问它,因为当我尝试应用其他主题的答案时,我失败了。

我遇到的问题是,我有一个带有材料的预制(四边形)'Star'和一个脚本,它会在一段时间后改变颜色:

using UnityEngine;

public class Star: MonoBehaviour {
  public enum StarType {
    BRIGHT,
    DARK,
    F,
    K,
    L,
    P
  }

  private Ship ship;
  private StarType starType;
  private float timeLimit = .30f, timer;
  private System.Random rand;

  public void Awake() {
    ship = FindObjectOfType<Ship>();

    timer = .0f;
    rand = new System.Random();
  }

  public void Start() {
    refactor();
  }

  public void Update() {
    timer += Time.deltaTime;
    if(timer > timeLimit) {
        refactor();
        timer = .0f;
    }
  }

  public void LateUpdate() {
    transform.eulerAngles = new Vector3(ship.transform.eulerAngles.x,
                                        ship.transform.eulerAngles.y,
                                        ship.transform.eulerAngles.z);
  }

  public void refactor() {
    starType = (StarType) rand.Next(0, 
             System.Enum.GetValues(typeof(StarType)).Length);
    switch(starType ) {
    case StarType.BRIGHT:
        renderer.material.color = Color.white;
        break;
    case StarType.DARK:
        renderer.material.color = Color.black;
        break;
    case StarType.F:
        renderer.material.color = Color.red;
        break;
    case StarType.K:
        renderer.material.color = Color.cyan;
        break;
    case StarType.L:
        renderer.material.color = Color.green;
        break;
    case StarType.P:
        renderer.material.color = Color.magenta;
        break;
    }
  }

  public StarType getStarType() {
    return starType;
  }
}

这个星星在Chunk类中被实例化:

public class Chunk : MonoBehaviour {
  public Star star;

  private IList<Star> stars;

  public void Awake() {
    stars = new List<Star>();

    Star auxStar = (Star) Instantiate(star, transform.position, 
                      Quaternion.identity);
    auxStar.transform.SetParent(transform);

    stars.Add(auxStar);
  }
}

我假设每颗星都会独立地改变颜色,但不是都会改变颜色。

我尝试使用sharedMaterial而不是材料,因为我在某些asnwers上读取它,虽然结果和行为看起来相同?,我尝试给星星提供随机初始颜色,但我得到的最多是他们中的一些变成了与其他颜色不同的颜色,但它们之间仍然相同(而且我一直试图改变颜色,而不仅仅是在创作时)。 我也读过创建材料并在实例化时对每个材料进行了解释,但我没有运气:

auxStar.renderer.material = (Material) 
                                 Instantiate(star.renderer.material);

有人知道如何处理问题?

2 个答案:

答案 0 :(得分:0)

根据Unity API reference,你正在做正确的事。 您的代码中的问题是您正在实例化MonoBehaviour

public Star star;
...
Star auxStar = (Star) Instantiate(star, transform.position, Quaternion.identity);

其中 star 是MonoBehaviour,您没有使用网格渲染和/或材质实例化实际的GameObject。相反,请确保您正在实例化正确的GameObject Prefab,而不仅仅是组件,如下所示:

public GameObject starPrefab;
...
GameObject starClone = (GameObject) Instantiate (starPrefab);
Star auxStar = starClone.GetComponent<Star> ();

通过这种方式,您可以控制GameObject(如果需要),以及与克隆对象关联的每个组件,在本例中为 Star 。您不必实例化预制材料,因为它已经被实例化。 这是一个简单的例子:

using UnityEngine;
using System.Collections;

public class SpawnStar : MonoBehaviour {

    public GameObject StarPrefab;
    public bool InstantiateStar = false;

    void Update () {
        if (InstantiateStar) {
            GameObject starClone = (GameObject)Instantiate (StarPrefab);

            float r = Random.Range (0f, 1f);
            float g = Random.Range (0f, 1f);
            float b = Random.Range (0f, 1f);
            float a = Random.Range (0f, 1f);

            starClone.renderer.material.color = new Color (r, g, b, a);
            InstantiateStar = false;
        }
    }
}

附注:确保在游戏过程中不要修改预制件,因为它是所有其他克隆对象的来源。

答案 1 :(得分:-1)

尝试使用Random.Range()与System.Random一样,由系统时间生成。我们知道时间不是真的随机。它仍然取决于mil秒的时间并产生随机的逻辑,因为我们无法确定随机将运行哪个mil。

由于System.Random在脚本使用的1个时间轴上运行。 Random.Range()是您可以考虑的赌注,因为它使用SystemTime和平台的独立时间On Run。与Time.DeltaTime共享。