Bagaimana cara menggunakan BillboardRenderer di Unity?


11

Sejak versi 5 (?) Unity memiliki tipe komponen yang baru BillboardRenderer. Sayangnya dokumentasinya sangat buruk.

Itu dapat ditambahkan di inspektur dengan mengklik "Tambahkan Komponen -> Misceallaneous -> Billboard Renderer" tetapi tampaknya itu memerlukan Billboard Assetuntuk melakukan apa saja. Sepertinya tidak ada cara untuk membuatnya dari antarmuka Unity.

Salah satu dari beberapa kalimat dari dokumentasi BillboardAsset yang sama buruknya berbunyi:

imageCount Jumlah gambar pra-panggang yang dapat diaktifkan ketika papan iklan dilihat dari sudut yang berbeda.

Proyek terbaru saya akan memiliki grafik campuran sprite / poligon, sehingga komponen yang membuat papan iklan dengan sprite berbeda tergantung pada sudut pandang adalah sesuatu yang benar-benar dapat saya manfaatkan. Tapi sepertinya tidak ada metode untuk menambahkan gambar seperti itu.

Jadi saya bertanya-tanya apakah Anda dapat memposting contoh bagaimana komponen ini digunakan.


Apakah papan reklame melakukan apa yang saya harapkan? Atau sesuatu yang lain? (Saya mengharapkannya untuk menjaga gambar menghadap kamera.)
Evorlor

@Evorlor Itulah yang saya harapkan juga, tapi sejauh ini saya belum berhasil melakukan apa pun .
Philipp

Jawaban:


6

UPDATE (2018): Ada lebih banyak properti terbuka sejak saya menulis jawaban ini. Mungkin kita bisa membuatnya sekarang, mungkin juga tidak. Harus meneliti.

Anda tidak bisa menggunakannya.

Berikut ini adalah BillboardAssetkode yang diuraikan :

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);
    }
}

Secara harfiah tidak ada cara untuk mengatur gambar, bahkan dengan refleksi. Orang mungkin berpikir: "Oke, Anda tidak bisa melakukannya secara langsung, tetapi mungkin ada semacam pabrik yang disediakan?". Saya menekan Temukan Penggunaan dalam dekompiler dan dapatkan: BillboardAssetInspectordan BillboardRenderer.

Ini adalah 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()
        {
        }
    }
}

Wow, kelas ini bahkan bodoh. Hanya pemegang data tanpa logika. Jelas, semua pekerjaan dilakukan oleh Renderer. Lebih tepatnya, dengan satu atau beberapa [WraplessIcall]-metode di dalamnya. Saya tidak akan meletakkan kodenya di sini karena itu adalah daftar- [WraplessIcall]anggota yang panjang dan tidak berguna .

Tidak seperti konten UnityEngine.dll , BillboardAssetInspector(yang berada di UnityEditor.dll ) memiliki kode nyata di dalamnya. Sekali lagi, saya tidak akan meletakkan kodenya di sini, karena jelas dari namanya bahwa itu tidak lebih dari Inspektur .

Situasi yang sama dengan BillboardAssetInspector.


Mengerti, ini untuk penggunaan internal; tapi di mana tepatnya itu digunakan?

Dalam sistem SpeedTree (lihat gambar terakhir khususnya).

Mengapa dokumentasi menjelaskan hal-hal yang tidak berguna alih-alih memperingatkan agar tidak segera menggunakannya?

Mungkin, cukup salin-tempelkan semuanya dari dokumentasi pengembangan internal, peningkatan bagian-bagian yang penting bagi pendatang baru dan dalam penggunaan umum; kemudian terlalu sibuk berpartisipasi dalam hype VR untuk repot memoles sudut-sudut gelap dokumentasi.

Apa boleh buat?

Katakan kepada mereka bahwa mereka mengabaikan "sudut gelap" ini dalam dokumentasi, misalnya: Di Editor Persatuan, buka Help → Report a bug..., What is problem related topilih documentation, dll.

Apa yang bisa digunakan seseorang sebagai gantinya?

Opsi yang mungkin termasuk:


2
Sebagai alternatif lain: sering kali ketika saya perlu menempatkan banyak papan iklan, saya menggunakan sistem partikel, dengan emisinya & animasi dimatikan sehingga saya dapat secara manual memposisikan setiap papan iklan di tempat yang saya inginkan.
DMGregory

@DMGregory Tidak bisa tidak setuju, sistem partikel Unity sangat bagus untuk banyak hal yang bahkan tidak dekat dengan "partikel". Bahkan lebih baik, sejak Unity 5, dukungan untuk penyesuaian sistem partikel secara eksplisit ditingkatkan / dioptimalkan. Haruskah saya menambahkan opsi ini ke jawabannya, atau komentar ini sudah cukup, bagaimana menurut Anda?
Maxim Kamalov

Saya pikir tidak apa-apa untuk meninggalkan komentar. Jika seseorang menginginkan lebih detail tentang itu, saya pikir itu cukup gemuk untuk mengajukan pertanyaan baru.
DMGregory

Saya tidak percaya itu untuk penggunaan internal, dokter mengatakan: "Anda juga dapat membuat sendiri setelah Anda tahu bagaimana papan reklame dijelaskan." - docs.unity3d.com/ScriptReference/BillboardAsset.html
123iamking

@ 123iamking Dan sekarang ada lebih banyak properti yang terpapar. Jadi, ya, mungkin saja untuk menggunakannya secara langsung sekarang.
Maxim Kamalov

1

Untuk menggunakan BillboardRenderer, Anda memerlukan Aset Billboard, Anda dapat membuat Aset Billboard dengan skrip C #. Periksa pos ini .

Aset Billboard memiliki konten seperti ini: 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}

Berikut adalah kode C # yang digunakan untuk menghasilkan file di atas

 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
     }

untuk lebih jelasnya, silakan periksa posting yang saya berikan di awal jawaban.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.