Replacing Textures in Scene with Textures from a Server (C#)

Hi all,

I’m working on this capstone project for my master’s degree. It’s a virtual reality browser. I am new to programming and need your help.

I set up an array of 44 mesh blocks with textures applied to them with a c# script. The array appears to be working properly when I start the game. I see the array in my Inspector and I can see the generated messages in the console.

using UnityEngine;
using System.Collections;

[System.Serializable]
public class Arrays : MonoBehaviour
{
    public GameObject[] meshes;
    // Use this for initialization
    void Start ()
    {
        meshes = GameObject.FindGameObjectsWithTag("quilt_block");

        for(int i = 0; i < meshes.Length; i++)
        {
            Debug.Log("quilt_block Number "+i+" is named "+meshes[i].name);}

    }
}

Everything is not ordered correctly, though. When I try editing the array, nothing happens, but that’s a separate secondary issue.

What I’ve been trying to figure out is how to replace all of the textures already in the scene with textures from a server whenever a trigger is set off. The trigger will essentially be a trip-line that the player walks through. I got the WWWclass code from the Unity doc working for one of the blocks (this was before I set up the array).

using UnityEngine;
using System.Collections;

public class GetURL : MonoBehaviour {
    public string url = "http://images.earthcam.com/ec_metros/ourcams/fridays.jpg";
    IEnumerator Start() {
        WWW www = new WWW(url);
        yield return www;
        Renderer renderer = GetComponent<Renderer>();
        renderer.material.mainTexture = www.texture;
    }
}

It pulls a new texture from the server at Start. I could apply the code to all 44 blocks manually, but I was looking for a more automatic method, since there’s a total of 5000+ images/textures that need to be loaded into the scene.

My instructor told me to use this code above. Then he said:

Ok, but what I’m confused about is the filenames for the images on the server already have padded 0s. So wouldn’t I need to do the reverse and convert a 0-padded string to an int?

And how would I add that to the GetURL script? And then apply everything to my array so that all the textures are in an ordered sequence for the player to look at?

I would appreciate any help because I’m completely lost right now. Can anyone point me in the right direction?

I suspect your instructor was thinking about the problem in reverse of how you seem to be. If you can refer to a mesh by index number then you just need to convert that index number to a zero padded string to get the correct image from the web server.

I think you should set up the array in unity so that an indexer can be used to iterate over the meshes in order. Perhaps try starting with a script which will cause each mesh to change colors in order, one per frame. You can worry about the zero-padding and downloading of images once you’ve got your array set up in the correct order and know how to iterate over them.

Thanks! I’ll try that and come back with an update.

Ok, I got the array set up in order. I used the “lock the Inspector and drag over” method to drag my meshes over to the array. For awhile, I couldn’t figure out why my array in the Inspector was being replaced by another array.

It turns out, all I had to do was delete the “FindGameObjectwithTag” line. Also, I removed the references to ‘meshes’ in my code. Here was it looks like now:

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

[System.Serializable]
public class Arrays : MonoBehaviour
{
    public GameObject[] Quilt_Blocks;
    // Use this for initialization
    void Start ()
    {
        for(int i = 0; i < Quilt_Blocks.Length; i++)
        {
            Debug.Log ("quilt_block Number "+i+" is named "+ Quilt_Blocks.name);
        }
    }
}

Now, I just need to figure how to iterate over it. But I’m not even sure if my array can be managed. I have the script attached to a “Game Manager” object that I created. When I reassign the elements in the array at runtime, no changes take affect. Any ideas?

You’re basically already doing that, just not touching the individual items in the array.

for(int i = 0; i < Quilt_Blocks.Length; i++)
{
  Debug.Log ("quilt_block Number "+i+" is named "+ Quilt_Blocks.name);
}

Instead of getting Quilt_Blocks.name (not even sure what that is – most likely a compile error) you should get the name of the item in Quilt_Blocks at position i; like this:

for(int i = 0; i < Quilt_Blocks.Length; i++)
{
  Debug.Log ("quilt_block Number "+i+" is named "+ Quilt_Blocks[i].name);
}

I’m not sure what that means. You are reassigning elements at runtime? How? What “effects” are you expecting?

Thanks for your reply. I just checked my script in Unity and I do have the item Quilt_Blocks at position i. Not sure what happened when I posted the code here.

I tried changing my elements in the Inspector at runtime by loading a new prefab as a test to see if anything would happen. I guess I was wrong in expecting changes to take affect. What I really need is a script that that tells Unity what changes to make before I hit play. I realize now that I was only changing the assignments in the index.

So I guess what I need now is to tell Unity to change each item a different color as a test like you initially suggested. I couldn’t find a tutorial or anything in the forums that would help me do that.

Each item in my array is arranged like this: block_00, block_01, block_02, etc., and it ends with the 44th item, which is block_43.

Textures and rederers are a bit out of my league but I think you’ve got the iterating code down. Just look at some tutorials for changing the color of a GameObject. I think it might be as simple as:

for(int i = 0; i < Quilt_Blocks.Length; i++)
{
  var renderer = Quilt_Blocks[i].GetComponent<Renderer>();
  renderer.material.color = Color.red;
}

To get a more interesting visual effect, you could change just one block each frame.

int i = 0;
void update()
{
  var renderer = Quilt_Blocks[i%44].GetComponent<Renderer>();
  renderer.material.color = i / 44 % 2 == 0?Color.red:Color.green;
  i ++;
}