Come usare BillboardRenderer in Unity?


11

Dalla versione 5 (?) Unity ha un nuovo tipo di componente BillboardRenderer. Purtroppo la documentazione è piuttosto scadente.

Può essere aggiunto nella finestra di ispezione facendo clic su "Aggiungi componente -> Miscelanea -> Renderer cartellone" ma a quanto pare richiede Billboard Assetdi fare qualsiasi cosa. Non sembra esserci alcun modo per crearne uno dall'interfaccia di Unity.

Una delle poche frasi della altrettanto scarsa documentazione di BillboardAsset recita:

imageCount Numero di immagini precotte che possono essere commutate quando il tabellone per le affissioni viene visualizzato da diverse angolazioni.

Il mio ultimo progetto avrà una grafica mix sprite / poligono, quindi un componente che rende un cartellone con uno sprite diverso a seconda dell'angolo di vista è qualcosa che potrei davvero usare. Ma non sembra esserci alcun metodo per aggiungere tali immagini.

Quindi mi chiedevo se potessi pubblicare un esempio di come viene utilizzato questo componente.


Il cartellone fa quello che mi aspetto? O qualcos'altro? (Mi aspetto che mantenga l'immagine rivolta verso la telecamera.)
Evorlor,

@Evorlor Questo è quello che mi aspetterei anche io, ma finora non sono riuscito a farlo fare nulla .
Philipp,

Risposte:


6

AGGIORNAMENTO (2018): ci sono più proprietà esposte da quando ho scritto questa risposta. Forse possiamo crearlo ora, forse no. Devo fare delle ricerche.

Non puoi usarlo.

Ecco il BillboardAssetcodice decompilato :

using System;

namespace UnityEngine
{
    /// <summary>
    ///   <para>BillboardAsset describes how a billboard is rendered.</para>
    /// </summary>
    public sealed class BillboardAsset : Object
    {
        /// <summary>
        ///   <para>Height of the billboard that is below ground.</para>
        /// </summary>
        public float bottom
        {
            [WrapperlessIcall]
            get;
            [WrapperlessIcall]
            set;
        }

        /// <summary>
        ///   <para>Height of the billboard.</para>
        /// </summary>
        public float height
        {
            [WrapperlessIcall]
            get;
            [WrapperlessIcall]
            set;
        }

        /// <summary>
        ///   <para>Number of pre-baked images that can be switched when the billboard is viewed from different angles.</para>
        /// </summary>
        public int imageCount
        {
            [WrapperlessIcall]
            get;
        }

        /// <summary>
        ///   <para>Number of indices in the billboard mesh. The mesh is not necessarily a quad. It can be a more complex shape which fits the actual image more precisely.</para>
        /// </summary>
        public int indexCount
        {
            [WrapperlessIcall]
            get;
        }

        /// <summary>
        ///   <para>The material used for rendering.</para>
        /// </summary>
        public Material material
        {
            [WrapperlessIcall]
            get;
            [WrapperlessIcall]
            set;
        }

        /// <summary>
        ///   <para>Number of vertices in the billboard mesh. The mesh is not necessarily a quad. It can be a more complex shape which fits the actual image more precisely.</para>
        /// </summary>
        public int vertexCount
        {
            [WrapperlessIcall]
            get;
        }

        /// <summary>
        ///   <para>Width of the billboard.</para>
        /// </summary>
        public float width
        {
            [WrapperlessIcall]
            get;
            [WrapperlessIcall]
            set;
        }

        /// <summary>
        ///   <para>Constructs a new BillboardAsset.</para>
        /// </summary>
        public BillboardAsset()
        {
        }

        [WrapperlessIcall]
        internal extern void MakeMaterialProperties(MaterialPropertyBlock properties, Camera camera);

        [WrapperlessIcall]
        internal extern void MakePreviewMesh(Mesh mesh);

        [WrapperlessIcall]
        internal extern void MakeRenderMesh(Mesh mesh, float widthScale, float heightScale, float rotation);
    }
}

Non c'è letteralmente modo di impostare le immagini, nemmeno per riflesso. Si potrebbe pensare: "okay, non puoi farlo direttamente, ma forse c'è una specie di fabbrica fornita?". Premo Trova Usi in decompilatore e ottenere: BillboardAssetInspectore BillboardRenderer.

Ecco qui BillboardRenderer:

using System;

namespace UnityEngine
{
    /// <summary>
    ///   <para>Renders a billboard.</para>
    /// </summary>
    public sealed class BillboardRenderer : Renderer
    {
        /// <summary>
        ///   <para>The BillboardAsset to render.</para>
        /// </summary>
        public BillboardAsset billboard
        {
            [WrapperlessIcall]
            get;
            [WrapperlessIcall]
            set;
        }

        /// <summary>
        ///   <para>Constructor.</para>
        /// </summary>
        public BillboardRenderer()
        {
        }
    }
}

Caspita, questa classe è persino più stupida. È solo un supporto dati senza logica. Ovviamente, tutto il lavoro è svolto da Renderer. Più precisamente, con uno o un paio di [WraplessIcall]metodi in esso. Non [WraplessIcall]inserirò qui il suo codice perché è un elenco lungo e inutile di -membri.

A differenza del contenuto di UnityEngine.dll , BillboardAssetInspector(che risiede in UnityEditor.dll ) contiene un codice reale. Ancora una volta, non inserirò qui il suo codice, perché è chiaro dal suo nome che non è altro che Inspector , comunque.

Stessa situazione con BillboardAssetInspector.


Capito, è per uso interno; ma dove viene usato esattamente?

Nel sistema SpeedTree (guarda l'ultima immagine in particolare).

Perché la documentazione spiega cose inutili invece di avvertire di non usarle subito?

Probabilmente, ho appena incollato tutto dalla documentazione di sviluppo interna, parti migliorate che sono importanti per i nuovi arrivati ​​e nell'uso generale; poi era troppo impegnato a partecipare alla campagna pubblicitaria VR per disturbare a lucidare angoli così oscuri della documentazione.

Cosa possiamo fare al riguardo?

Di 'loro che hanno trascurato questo "angolo oscuro" nella documentazione, ad esempio: In Unity Editor, apri Help → Report a bug..., What is problem related toscegli documentation, ecc.

Cosa si può usare invece?

Le opzioni possibili includono:


2
Come altra alternativa: spesso quando ho bisogno di posizionare un gruppo di cartelloni pubblicitari, uso un sistema di particelle, con le sue emissioni e l'animazione disattivate in modo da poter posizionare manualmente ogni quadrante cartellone dove lo voglio.
DMGregory

@DMGregory Non posso essere in disaccordo, il sistema di particelle di Unity è ottimo per molte cose che non sono nemmeno lontanamente vicine alle "particelle". Ancora meglio, da Unity 5, il supporto per la personalizzazione del sistema particellare è stato esplicitamente migliorato / ottimizzato. Devo aggiungere questa opzione alla risposta, o questi commenti sono sufficienti, cosa ne pensi?
Maxim Kamalov

Penso che vada bene lasciare nei commenti. Se qualcuno vuole maggiori dettagli, penso che sia abbastanza carnoso per porre una nuova domanda.
DMGregory

Non ci credo per uso interno, il documento ha detto: "Puoi anche crearne uno tuo una volta che sai come viene descritto il cartellone". - docs.unity3d.com/ScriptReference/BillboardAsset.html
123

@ 123iamking E ora ci sono più proprietà esposte. Quindi, sì, probabilmente è possibile utilizzarli direttamente ora.
Maxim Kamalov,

1

Per usare BillboardRenderer, hai bisogno di Billboard Asset, puoi costruire Billboard Asset con script C #. Controlla questo post .

Le risorse di Billboard hanno contenuti come questo: Billboard.asset

 %YAML 1.1
 %TAG !u! tag:unity3d.com,2011:
 --- !u!226 &22600000
 BillboardAsset:
   m_ObjectHideFlags: 0
   m_CorrespondingSourceObject: {fileID: 0}
   m_PrefabInternal: {fileID: 0}
   m_Name: Billboard_Original
   serializedVersion: 2
   width: 10.350581
   bottom: -0.2622106
   height: 7.172371
   imageTexCoords:
   - {x: 0.230981, y: 0.33333302, z: 0.230981, w: -0.33333302}
   - {x: 0.230981, y: 0.66666603, z: 0.230981, w: -0.33333302}
   - {x: 0.33333302, y: 0, z: 0.33333302, w: 0.23098099}
   - {x: 0.564314, y: 0.23098099, z: 0.23098099, w: -0.33333302}
   - {x: 0.564314, y: 0.564314, z: 0.23098099, w: -0.33333403}
   - {x: 0.66666603, y: 0, z: 0.33333302, w: 0.23098099}
   - {x: 0.89764804, y: 0.23098099, z: 0.230982, w: -0.33333302}
   - {x: 0.89764804, y: 0.564314, z: 0.230982, w: -0.33333403}
   vertices:
   - {x: 0.47093, y: 0.020348798}
   - {x: 0.037790697, y: 0.498547}
   - {x: 0.037790697, y: 0.976744}
   - {x: 0.52906996, y: 0.020348798}
   - {x: 0.95930207, y: 0.498547}
   - {x: 0.95930207, y: 0.976744}
   indices: 040003000000010004000000050004000100020005000100
   material: {fileID: 2100000, guid: 6e680dda9368db5418f19388474277a2, type: 2}

Ecco il codice C # utilizzato per generare il file sopra

 using System.Collections;
 using System.Collections.Generic;
 using UnityEditor;
 using UnityEngine;

     public class BillboardBaker : MonoBehaviour
     {
 #if UNITY_EDITOR
         public BillboardAsset m_outputFile;
         public Material m_material;

         [ContextMenu("Bake Billboard")]
         void BakeBillboard()
         {
             BillboardAsset billboard = new BillboardAsset();

             billboard.material = m_material;
             Vector4[] texCoords = new Vector4[8];
             ushort[] indices = new ushort[12];
             Vector2[] vertices = new Vector2[6];
             texCoords[0].Set(0.230981f, 0.33333302f, 0.230981f, -0.33333302f);
             texCoords[1].Set(0.230981f, 0.66666603f, 0.230981f,-0.33333302f);
             texCoords[2].Set(0.33333302f, 0.0f, 0.33333302f,0.23098099f);
             texCoords[3].Set(0.564314f, 0.23098099f, 0.23098099f,-0.33333302f);
             texCoords[4].Set(0.564314f, 0.564314f, 0.23098099f,-0.33333403f);
             texCoords[5].Set(0.66666603f, 0.0f, 0.33333302f,0.23098099f);
             texCoords[6].Set(0.89764804f, 0.23098099f, 0.230982f,-0.33333302f);
             texCoords[7].Set(0.89764804f, 0.564314f, 0.230982f,-0.33333403f);

             indices[0] = 4;
             indices[1] = 3;
             indices[2] = 0;
             indices[3] = 1;
             indices[4] = 4;
             indices[5] = 0;
             indices[6] = 5;
             indices[7] = 4;
             indices[8] = 1;
             indices[9] = 2;
             indices[10] = 5;
             indices[11] = 1;

             vertices[0].Set(0.47093f, 0.020348798f);
             vertices[1].Set(0.037790697f, 0.498547f);
             vertices[2].Set(0.037790697f, 0.976744f);
             vertices[3].Set(0.52906996f, 0.020348798f);
             vertices[4].Set(0.95930207f, 0.498547f);
             vertices[5].Set(0.95930207f, 0.976744f);

             billboard.SetImageTexCoords(texCoords);
             billboard.SetIndices(indices);
             billboard.SetVertices(vertices);

             billboard.width = 10.35058f;
             billboard.height = 7.172371f;
             billboard.bottom = -0.2622106f;

             if (m_outputFile != null)
             {
                 EditorUtility.CopySerialized(billboard, m_outputFile);
             }
             else
             {
                 string path;
                 path = AssetDatabase.GetAssetPath(m_material) + ".asset";
                 AssetDatabase.CreateAsset(billboard, path);
             }
         }
 #endif
     }

per maggiori dettagli, controlla il post che ho dato all'inizio della risposta.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.