通过脚本c#更改纹理

时间:2013-12-26 22:25:30

标签: c# unity3d textures

我在将纹理切换到网格时遇到问题,当我接近网格时,应该出现新的纹理:

string name = picture.name;
Texture2D tex = (Texture2D)Resources.Load(name, typeof(Texture2D));
picture.GetComponent<Renderer>().material.mainTexture = tex;

我想做的是在我走远时恢复旧纹理,我无法以任何方式做到这一点...... 我认为问题在于

Texture old = picture.GetComponent<Renderer>().material.GetTexture ("_MainTex");

每次都会得到图片的名称,即使它已经改变了,所以保存了当前的纹理名称,我无法恢复原来的纹理名称。

PS:我的纹理是动态的,我无法在检查器中设置它们。

using UnityEngine;
using System.Collections;

public class pictures : MonoBehaviour {
    public GameObject[] pictures;
    public GameObject player;

    void Start() {
        player = GameObject.FindGameObjectWithTag("Player");
        pictures = GameObject.FindGameObjectsWithTag("pictures");
    }

    void MyFunction(GameObject picture, string name) {
        Texture2D tex = (Texture2D)Resources.Load(name, typeof(Texture2D));
        picture.GetComponent<Renderer>().material.mainTexture = tex;
        Debug.Log("change the texture " + name);
    }

    void Update() {
        foreach (GameObject picture in pictures) {
            if (Vector3.Distance(picture.transform.position, player.transform.position) < 20) {
                MyFunction(picture, picture.name);
            } else {
                Texture old = picture.GetComponent<Renderer>().material.GetTexture("_MainTex");
                Debug.Log(old.name);
                MyFunction(picture, old.name);
            }
        }
    }
}

3 个答案:

答案 0 :(得分:1)

好吧我自己解决了,我创建了一个数组旧名,在函数Start中用旧的纹理名称填充它,然后在Update中如果函数中的距离越大,则称为旧名称的数组索引与纹理相同,因为数组图片中的所有纹理都有一个名称:)

PS:所有纹理都必须在资源文件夹中!

现在是时候检查它是否需要太多资源以及选择触发方式是否更好......

我希望能帮助有这个解决方案的人。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class pictures : MonoBehaviour {

    public GameObject[] pictures;   
    public GameObject player;

    List<string> oldnames = new List<string>();
    public Texture  old;
    public string oldName;

    // Use this for initialization
    void Start () {

        player = GameObject.FindGameObjectWithTag("Player");    
        pictures = GameObject.FindGameObjectsWithTag( "pictures" );

        foreach(GameObject picture in pictures)
        {
            old = picture.renderer.material.GetTexture ("_MainTex");
            oldName = old.name;
            oldnames.Add(oldName);
        }
    }

    void MyFunction(GameObject picture, string name) {

        Texture2D tex = (Texture2D) Resources.Load(name, typeof(Texture2D));
        picture.renderer.material.mainTexture = tex;
    }

    // Update is called once per frame
    void Update () {

        for(int i = 0; i < pictures.Length; i++)
        { 
            GameObject picture = vetrine[i];            

            if (Vector3.Distance(picture.transform.position, player.transform.position) < 10)
            {
                MyFunction(picture, picture.name);
            } 
            else 
            { 
                MyFunction(picture, oldnames[i]);
            }
        }
    }       
}

注意:.renderer已弃用(改为使用.GetComponent<Renderer>()

答案 1 :(得分:0)

MyFunction2永远不会更改纹理或名称。你在哪里得到其他纹理?我真的不明白。

这个怎么样:

using UnityEngine;
using System.Collections;

public class Vetrine : MonoBehaviour
{
    public Texture2D textn;
    public GameObject[] pictures;
    public GameObject player;

    void Start()
    {
        player = GameObject.FindGameObjectWithTag("Player");
        marker = GameObject.FindGameObjectsWithTag("infowindow");
        pictures = GameObject.FindGameObjectsWithTag("picture");
    }

    void MyFunction(GameObject picture, string name)
    {
        Texture2D tex = (Texture2D)Resources.Load(name, typeof(Texture2D));
        picture.renderer.material.mainTexture = tex;
    }

    void Update()
    {
        foreach (GameObject picture in pictures)
        {
            if (Vector3.Distance(picture.transform.position, player.transform.position) < 20)
            {
                MyFunction(picture, picture.name);
            }
            else
            {
                MyFunction(picture, "someOtherNameHere");
            }
        }
    }
}

请注意,pictures正在获得FindGameObjectsWithTag的结果,因为它之前是空的。

答案 2 :(得分:0)

*将脚本另存为ChangeTexture1.cs

// Change renderer's texture each changeInterval/
// seconds from the texture array defined in the inspector.

using UnityEngine;
using System.Collections;

public class ChangeTexture1 : MonoBehaviour
{
public Texture[] textures;
public float changeInterval = 0.33F;
public Renderer rend;

void Start()
{
rend = GetComponent<Renderer>();
}

void Update()
{
if (textures.Length == 0)
return;

int index = Mathf.FloorToInt(Time.time / changeInterval);
index = index % textures.Length;
rend.material.mainTexture = textures[index];
}
}

/ *此脚本以设定的间隔自动更改对象的纹理, 循环遍历分配给对象的所有材料。 - 将它连接到要更改纹理的对象。 不幸的是,PS,Unity使用相同的名称ExampleClass.cs命名其文档中的每个脚本,因此我将其重命名为ChangeTexture1.cs。 * /

- 通过修改代码来满足您的需求,您将更好地理解Unity的材料脚本API ...