Тема будет в большей степени полезна людям, кто делает 2д игру и кому важно уменьшить draw call'ы в проекте.
Ни для кого не секрет, что изменяя св-ва материалов ( например цвет ) юнити автоматически создает клон этого материала, что добавляет + 1 к draw calls. Однако изменяя цвет объекта повертексно можно добиться того, что draw call увеличиваться не будут.
Не со всеми шейдерами получится такой трюк, если лень писать свой, то лучше использовать /particles/alpha blended . Либо любой другой шейдер который поддерживает изменение цвета вертексов. ( мы меняем НЕ цвет материала, а напрямую цвета меша ).
Применение способу - масса. Можно например использовать не только для окраски, но и для смещения прозрачности.
Начнем.
сделаем скрипт Core
#pragma strict
class obColors //объявляем класс{ //переменные private varprefab: GameObject; private var currentColor: Color; //текущий цвет //конструктор function obColors(prefab: GameObject) { this.prefab= prefab; }
//текущий цвет
function Addcurrentcolor(currentColor:Color) { this.currentColor = currentColor; }
//меняем цвет function change_color(to:Color) {
var mesh: Mesh = this.prefab.GetComponent.<MeshFilter>().mesh; //меш нашего объекта varvertices: Vector3[] = mesh.vertices; //вертексы меша varcolors: Color[] = newColor[vertices.Length]; // объявлям массив цветов кол-вом наших вертексов.
for (var i=0;i<30;i++)//быдлкод;-) в течении данного времени сделать замену цвета.{ yield; // коротин, для плавности смены цвета. (Цикл будет выполняться через промежутки времени) //В моем случае с плашкой всего 4 вертекса. Разумеется никто вас не заставляет писать вот так вот. Однотипные действия можно загнать в for
colors[0] = Color.Lerp(this.currentColor,to,i*0.04); colors[1] = Color.Lerp(this.currentColor,to,i*0.04); colors[2] = Color.Lerp(this.currentColor,to,i*0.04); colors[3] = Color.Lerp(this.currentColor,to,i*0.04); mesh.colors = colors; //добавляем наши цвета к цветам меша } } }
Теперь сделаем скрипт для объекта. (например ob_scr)
var selfcolor: obColors;
function Awake() { selfcolor = obColors(gameObject); selfcolor.Addcurrentcolor(Color(255/255f, 255/255f, 255/255f,253/253f)); }
function Start() { StartCoroutine(selfcolor.change_color(Color(97/255f, 253/255f, 0.0f,199/253f))); //меняет текущий цвет объекта на зеленый }
Таким образом можно убить ненужные drawcalls. Однако настоятельно не рекомендуется использовать этот способ повсеместно (дорого). Это больше подходит для учебного примера. Так же настоятельно рекомендую ознакомиться с SpriteManager 1, выложенным с исходниками на форумах юнити. ACTORS - мой фреймворк на Unity Until We Die - игра над которой работаю
Сообщение отредактировал pixeye - Воскресенье, 10 Апреля 2011, 11:52