Let me preface this by saying I’m a game dev neophyte, so “Duh… that’s the way it works.” is valid, but a link to resource would be appreciated in addition.
Here’s the situation:
I have a ball prefab object that has a base sphere mesh and I have a texture/material that is basically a texture atlas. The default prefab has the material tiling set to show the first skin. The ball also has a sphere collider and physic material (though I assume that’s not relevant).
In order to change the “skin” on the ball I am changing the UV offsets of the mesh. I take a copy of the original mesh (static copy on first instatiation) then use that to create the offset UVs. See example code below for what I’m doing roughly. Works a charm, uses the same material (which is great) but I’m getting a draw call for each ball I instantiate on screen (and no batching). The meshes are of course mesh instances since they are being done in code. I was expecting less draw calls or batching by using the same material.
using UnityEngine;
using System;
using System.Collections;
public class MyBall : MonoBehaviour
{
private int ballSkinId = 1;
private bool dirty = false;
public int BallSkinId
{
get {return ballSkinId;}
set
{
ballSkinId = value;
dirty = true;
}
}
private MeshFilter mesh;
private static Vector2[] originalUVs;
private Vector2[] uvs;
void Start ()
{
//Get mesh to edit
mesh = GetComponent<MeshFilter>();
if(mesh!=null)
{
if(originalUVs == null)
{
originalUVs = new Vector2[mesh.mesh.uv.Length];
mesh.mesh.uv.CopyTo (originalUVs,0);
}
uvs = new Vector2[mesh.mesh.uv.Length]; //initialize array for modified UVs
dirty = true;
}
}
void Update()
{
if(dirty)
{
if(ballSkinId<1) return;//sanity check.. all positive number are fine, though results may vary
int xOffset = (int)Math.Floor((ballSkinId-1)/15.0);
int yOffset = (ballSkinId+14)%15;
Vector2 offset = new Vector2(xOffset,yOffset);
for(int i = 0; i < mesh.mesh.uv.Length; i++)
{
uvs _= originalUVs *+ offset;*_
* }*
* mesh.mesh.uv = uvs; *
* dirty = false; *
* }*
* }*
}
Is this expected behavior? Is there a better way to go about this?
All balls are created programmatically (none in scene at start). There will however be a known max number of balls in a scene at any one time.