I am having trouble with making bullet holes in an airplane model I put together in Maya. The crux of the issue seems to be the speed at which either SetPixels() or mainTex.Apply() operate since that is what all my debugging points to. Right now a single bullet hole will slow the game to a very sad 0.9 seconds per frame. The textures being edited are both 2048 X 2048 which I know is quite large (I am thinking about cutting this up into smaller textures and mapping them separately on each part of the airplane).
Without too much talking, I present my commented code for your help and ask this one question: “How can I speed up the operations?”
var mainTex : Texture2D[]; // all editable textures of the object (some objects will have two or more) added before runtime
private var holesArray = new Array(); // x (x position), y (y position), z (radius)
private var holeTimers = new Array(); // cooling timer
function Update () {
UpdateBulletHoles(); // cycle through the bullet holes that already exist and aply their texture changes
}
// this function is called by the bullet, explosive, or other such object which comes in contact with this object
function AddHole (xPos : float, yPos : float, rad : float) {
holesArray.Push(Vector3(xPos * mainTex[0].width, yPos * mainTex[0].height, rad)); // x and y are set up for positioning the hole on the texture; z takes the radius of the projectile
holeTimers.Push(0.0); // all bullet holes start at zero cooling time
}
function UpdateBulletHoles () {
if (holesArray.length == 0) // if there are no active bullet holes then don't do anything
return;
// this block of code is used to remove holes that have fully cooled and to ensure that the hole is drawn as being fully cooled
var holesToRemove = new Array();
for (i = 0; i < holesArray.length; i++)
{
holeTimers _+= Time.deltaTime * 10;_
_ if (holeTimers >= 20)_
* {*
* holesToRemove.Push(i);*
_ holeTimers = 20;
* }
}*_
* // cycle through textures*
* for (l = 0; l < mainTex.length; l++)*
* {*
* // cycle through holes*
* for (k = 0; k < holesArray.length; k++)*
* {*
* // don’t draw holes on parts of the geometry that have not had their UV coordinates layed out perfectly (nor ever will)*
* if (holesArray[k].x >= 5 || holesArray[k].y <= 2040)*
* {*
* var pix : Color;*
* // get a square of pixels from the texture that is as wide and as tall as the drawn hole and centered on that hole*
_ var pixels = mainTex[l].GetPixels(holesArray[k].x - holesArray[k].z - 3, holesArray[k].y + holesArray[k].z + 3, (holesArray[k].z * 2) + 6, (holesArray[k].z * 2) + 6, 0);
* var pixPos : Vector2;*_
* // set up ring color to show its cooling progress*
* if (holeTimers[k] <= 10)*
* pix = Color.Lerp(Color(1, 1, 0, 1), Color(1, 0.5, 0, 1), holeTimers[k] / 10);*
* else*
* pix = Color.Lerp(Color(1, 0.5, 0, 1), Color(0.5, 0.5, 0.5, 1), (holeTimers[k] - 10) / 10);*
* // cycle through the square of pixels just extracted from the texture*
* for (i = 0; i < pixels.length; i++)*
* {*
* // this block of code finds the distance of each pixel from the center of the hole*
* var dist : float;*
_ pixPos.x = ((i / (holesArray[k].z + 3)) - Mathf.Floor(i / (holesArray[k].z + 3))) * (holesArray[k].z + 3);
* pixPos.y = Mathf.Floor(i / (holesArray[k].z + 3));
dist = Mathf.Sqrt(Mathf.Pow(pixPos.x - (holesArray[k].z + 3), 2) + Mathf.Pow(pixPos.y - (holesArray[k].z + 3), 2));*_
* // draw the ring on the outside of the hole 3 pixels thick and punch a hole with the previously given radius*
* if (dist <= holesArray[k].z + 3 && dist > holesArray[k].z)*
_ if (pixels*.a > 0.5)
pixels = pix;
if (dist <= holesArray[k].z)
{
pixels = pix;
pixels.a = 0;
}
}*_
* // set the square of pixels with the altered pixels*
_ mainTex[l].SetPixels(holesArray[k].x - holesArray[k].z - 3, holesArray[k].y + holesArray[k].z + 3, (holesArray[k].z * 2) + 6, (holesArray[k].z * 2) + 6, pixels, 0);_
* }*
* }*
* mainTex[l].Apply(); // send the pixel changes to the graphics card*
* }*
* // remove fully cooled holes from the arrays*
* for (i = 0; i < holesToRemove.length; i++)*
* {*
* holesToRemove.RemoveAt(i);*
* holesArray.RemoveAt(i);*
* holeTimers.RemoveAt(i);*
* }*
}
Thanks,
-Conan Horus