Hello, I have read the documentation of unity about billboard asset and how to create them, but I do not get the result that I expect, there must be something that I am leaving aside.
for some reason, it is not displayed at the scale indicated by the asset, and although it has the coordinates of the textures in place, it is not displayed as expected but the entire texture is there
Here is the code I used to generate the asset:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class MyBillboard : MonoBehaviour
{
[Header("Initial preparations")]
[Tooltip("This should be a billboard material")]
[SerializeField] Material mat;
[Tooltip("This dictates the center of the render for the object")]
[SerializeField] Transform cameraBillboardPivot;
[Tooltip("The camera should be a child of the Camera Billboard Pivot")]
[SerializeField] Camera cam;
[Header("Object Setup")]
[Tooltip("Units in height of the object, roughly, this can be fine-tuned later on the final asset")]
[SerializeField] float objectHeight = 5.0f;
[Tooltip("Units in width of the object, roughly, this can be fine-tuned later on the final asset")]
[SerializeField] float objectWidth = 4.0f;
[Tooltip("Usually negative and small, to make it sit in the ground slightly, can be modifed on final asset")]
[SerializeField] float bottomOffset = 0.0f;
[Header("Mesh Re-Dimention")]
[Range(0, 1)]
public float topWidth = 3;
[Range(0, 1)]
public float midWidth = 3;
[Range(0, 1)]
public float botWidth = 9;
[Header("Image Setup")]
[SerializeField] int atlasPixelWidth = 1024;
[SerializeField] int atlasPixelHeight = 1024;
[Min(1)]
[SerializeField] int atlasRowImageCount = 1;
[Min(1)]
[SerializeField] int atlasColumnImageCount = 1;
[Min(1)]
[SerializeField] int totalImageCount = 1;
[Tooltip("Color to replace with complete alpha - set Camera to depth only and this to black")]
[SerializeField] Color clearColor = Color.black;
[Header("Create")]
[SerializeField] bool create;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (create)
{
StartCoroutine(CreateBillboard());
create = false;
}
}
IEnumerator CreateBillboard()
{
BillboardAsset newBillboard = new BillboardAsset();
newBillboard.material = mat;
Rect[] photoRect = new Rect[totalImageCount];
Vector4[] textCoords = new Vector4[totalImageCount];
ushort[] meshtriangles = new ushort[12];
Vector2[] vertex = new Vector2[6];
//create a texture
Texture2D texture = new Texture2D(atlasPixelWidth, atlasPixelHeight, TextureFormat.ARGB32, false);
//set all pixels to tranparent
Color[] allpixels = texture.GetPixels();
for(int i =0;i<allpixels.Length;i++)
{
allpixels[i].a = 0.0f;
}
texture.SetPixels(allpixels);
//inicialize rotation
cameraBillboardPivot.eulerAngles = Vector3.zero;
int imageat = 0;
//atlas them left-right, top-bottom, 0,0 is bottom left
for (int j = 0; j < atlasRowImageCount; j++)
{
for (int i = 0; i < atlasColumnImageCount; i++)
{
if (imageat < totalImageCount)
{
float xRatio = (float)i / atlasColumnImageCount;
float yRatio = (float)(atlasRowImageCount - j - 1) / atlasRowImageCount;
//photoRect[imageat].Set(xRatio, yRatio, (float)1 / atlasColumnImageCount, (float)1 / atlasRowImageCount);
textCoords[imageat] = new Vector4(xRatio, yRatio, 1f / atlasColumnImageCount, 1f / atlasRowImageCount);
cam.targetTexture = RenderTexture.GetTemporary(Mathf.FloorToInt(atlasPixelWidth/ atlasColumnImageCount), Mathf.FloorToInt(atlasPixelHeight/ atlasRowImageCount), 16);
float xPos = xRatio * atlasPixelWidth;
float yPos = yRatio * atlasPixelWidth;
yield return new WaitForEndOfFrame();
Rect rect = new Rect(0, 0, Mathf.FloorToInt(atlasPixelWidth / atlasColumnImageCount), Mathf.FloorToInt(atlasPixelHeight / atlasRowImageCount));
RenderTexture.active = cam.targetTexture;
texture.ReadPixels(rect, Mathf.FloorToInt(xPos), Mathf.FloorToInt(yPos), false);
texture.Apply();
var eulerStore = cameraBillboardPivot.eulerAngles;
eulerStore.y -= (360f / totalImageCount);
cameraBillboardPivot.eulerAngles = eulerStore;
print(imageat);
imageat++;
}
}
}
//Set triangles from vertex
meshtriangles[0] = 4;
meshtriangles[1] = 3;
meshtriangles[2] = 0;
meshtriangles[3] = 1;
meshtriangles[4] = 4;
meshtriangles[5] = 0;
meshtriangles[6] = 5;
meshtriangles[7] = 4;
meshtriangles[8] = 1;
meshtriangles[9] = 2;
meshtriangles[10] = 5;
meshtriangles[11] = 1;
//Set Vertex positions
vertex[0].Set(-botWidth / 2 + 0.5f, 0);
vertex[1].Set(-midWidth / 2 + 0.5f, 0.5f);
vertex[2].Set(-topWidth / 2 + 0.5f, 1);
vertex[3].Set(botWidth / 2 + 0.5f, 0);
vertex[4].Set(midWidth / 2 + 0.5f, 0.5f);
vertex[5].Set(topWidth / 2 + 0.5f, 1);
//assing billbord Data
newBillboard.SetImageTexCoords(textCoords);
newBillboard.SetIndices(meshtriangles);
newBillboard.SetVertices(vertex);
newBillboard.width = objectWidth;
newBillboard.height = objectHeight;
newBillboard.bottom = bottomOffset;
print(newBillboard.imageCount);
string path;
int nameLength = AssetDatabase.GetAssetPath(mat).Length;
//take out ".mat" prefix
path = AssetDatabase.GetAssetPath(mat).Substring(0, nameLength - 4) + ".asset";
AssetDatabase.CreateAsset(newBillboard, path);
path = AssetDatabase.GetAssetPath(mat).Substring(0, nameLength - 4) + ".png";
byte[] byteArray = ImageConversion.EncodeToPNG(texture);
System.IO.File.WriteAllBytes(path, byteArray);
Debug.Log("Billboard Asset Created & PNG File Bytes Saved: " + path);
}
}
Please Help!
