Can we read data from a binary file? Could be used for vertex animation.

I was wondering if there was any way to import a binary file format and read its data into a script. A text file would be easier as you can use TextAsset.text, but what if the file is not text?

The only other way of reading a file is TextAsset.bytes, but I can’t find a way to interpret those bytes into any value type (except a String). If this works it could allow us to import a point cache file and use it to animate a mesh.

I can create a string from the Byte array using this:

//fileHeader is a byte[]
string s = System.Text.ASCIIEncoding.ASCII.GetString(fileHeader)

However, I have not found a way of turning 4 consecutive bytes (32 bits) into an int. Has anyone done this? If it can’t be done then what is the purpose of a byte array and TextAsset.bytes?

Everything is made from bytes, so they can represent whatever you want. One way is to use System.BitConverter, though it’s not endian-aware so you need to account for big-endian and little-endian systems yourself.

–Eric

This is right off the top of my head so it might not be perfect, but I imagine you’d do something similar to:

function FourBytesToInt( byte : Whatever[] ) : int {
  return parseInt(byte[3]) + parseInt(byte[2] * 256) + parseInt(byte[1]*256*256) + parseInt(byte[0]*256*256*256);
}

Could be 0,1,2,3 if your endian-ness is the other one.

Edit: Oh hai, Eric, didn’t see you there. Xd

Thanks for those comments. I didn’t realise we could use BitConverter, but it works perfectly. I didn’t have to use the manual method, but that will be a good idea if no other class can do it for me.

BitConverter works, but is it ever slow! I’m trying to convert a byte array into a series of Vector3’s, so I’m doing things like this:

for (var i : int = 0; i < verts.length; +i)
{
  verts[i].x = BitConvert.ToSingle(bytes, i*12);
  verts[i].y = BitConvert.ToSingle(bytes, i*12+4);
  verts[i].z = BitConvert.ToSingle(bytes, i*12+8);
}

For a 16,625 element array it takes nearly a minute! That means each call to BitConvert.ToSingle() is taking over a millisecond, which seem ridiculous considering what it must be doing (which is not very much).

Anyone encountered this before? Am I missing something? And are there faster alternatives?

In C, I would of course just do

    verts[i].x = *((float *) &bytes[i*12]);

but I don’t think I can do that kind of casting in Unityscript or C#.

Found a solution:

	var s = new MemoryStream(www.bytes);
	var b = new BinaryReader(s);

	var verts = new Vector3[smr.sharedMesh.vertices.length];  // new vertex array
	for (var i : int = 0; i < verts.length; ++i)
	{
		verts[i].x = b.ReadSingle();
		verts[i].y = b.ReadSingle();
		verts[i].z = b.ReadSingle();
	}
	
	b.Close();
	s.Close();

… much, much faster. Still no idea why mono’s BitConverter is so slow.

What is “BitConvert.ToSingle”? Using System.BitConverter.ToSingle, I can do over 25000 calls in 1 ms on my computer.

–Eric