วิธีการใช้ BillboardRenderer ใน Unity


11

ตั้งแต่เวอร์ชั่น 5 (?) BillboardRendererความสามัคคีมีองค์ประกอบใหม่ชนิด น่าเสียดายที่เอกสารค่อนข้างแย่

มันสามารถเพิ่มในการตรวจสอบโดยคลิกที่ "เพิ่มส่วนประกอบ -> ผิด -> บิลบอร์ด Renderer" แต่เห็นได้ชัดว่ามันต้องมีBillboard Assetการทำอะไร ดูเหมือนจะไม่มีวิธีใดที่จะสร้างได้จากอินเทอร์เฟซ Unity

หนึ่งในไม่กี่ประโยคจากเอกสารที่ไม่ดีเท่า ๆ กันของ BillboardAsset อ่าน:

imageCount จำนวนรูปภาพที่เตรียมไว้ล่วงหน้าที่สามารถเปลี่ยนได้เมื่อดูบิลบอร์ดจากมุมที่แตกต่างกัน

โปรเจ็กต์ใหม่ล่าสุดของฉันจะมีกราฟิกผสมสไปรต์ / รูปหลายเหลี่ยมดังนั้นส่วนประกอบที่แสดงป้ายโฆษณาที่มีสไปรต์ที่แตกต่างกันขึ้นอยู่กับมุมมองเป็นสิ่งที่ฉันสามารถใช้ประโยชน์ได้ แต่ดูเหมือนจะไม่มีวิธีใด ๆ ในการเพิ่มภาพดังกล่าว

ดังนั้นฉันสงสัยว่าคุณสามารถโพสต์ตัวอย่างวิธีการใช้องค์ประกอบนี้


ป้ายโฆษณาทำตามที่ฉันคาดหวังหรือไม่ หรืออย่างอื่น? (ฉันคาดว่ามันจะทำให้ภาพหันหน้าเข้าหากล้อง)
Evorlor

@ Evorlor นั่นคือสิ่งที่ฉันคาดหวัง แต่จนถึงตอนนี้ฉันยังไม่สามารถทำอะไรได้เลย
ฟิลิปป์

คำตอบ:


6

UPDATE (2018): มีคุณสมบัติที่เปิดเผยตั้งแต่ฉันเขียนคำตอบนี้ บางทีเราสามารถสร้างได้ตอนนี้อาจจะไม่ ต้องวิจัย

คุณไม่สามารถใช้งานได้

นี่คือBillboardAssetรหัสที่แปลแล้ว:

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

ไม่มีวิธีการตั้งค่าภาพอย่างแท้จริงแม้โดยการสะท้อน บางคนอาจคิดว่า:“ โอเคคุณทำไม่ได้โดยตรง แต่อาจจะมีโรงงานให้บริการบ้าง” ผมกดค้นหาประเพณีใน Decompiler และได้รับ: และBillboardAssetInspectorBillboardRenderer

นี่คือ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()
        {
        }
    }
}

ว้าวคลาสนี้ยังงี่เง่า มันเป็นเพียงผู้ถือข้อมูลโดยไม่ต้องใช้ตรรกะ Rendererเห็นได้ชัดว่าการทำงานทั้งหมดจะทำโดย แม่นยำยิ่งขึ้นโดยหนึ่งหรือสอง[WraplessIcall]วิธีในนั้น ฉันจะไม่ใส่รหัสที่นี่เพราะเป็นรายการที่ยาวและไร้ประโยชน์ของ[WraplessIcall]สมาชิก

ซึ่งแตกต่างจากเนื้อหาUnityEngine.dllBillboardAssetInspector (ที่อยู่ในUnityEditor.dll ) มีรหัสจริงในนั้น อีกครั้งผมจะไม่ใส่รหัสที่นี่เพราะมันเป็นที่ชัดเจนจากชื่อของมันว่ามันเป็นอะไรมากไปกว่าสารวัตรแล้ว

BillboardAssetInspectorสถานการณ์เดียวกันกับ


เข้าใจแล้วมีไว้สำหรับการใช้งานภายใน แต่มันใช้ตรงไหน?

ในระบบ SpeedTree (ดูภาพสุดท้ายโดยเฉพาะ)

ทำไมเอกสารอธิบายสิ่งที่ไร้ประโยชน์แทนการเตือนไม่ให้ใช้งานทันที

อาจเป็นเพียงการคัดลอกทุกอย่างจากเอกสารการพัฒนาภายในชิ้นส่วนที่ปรับปรุงแล้วซึ่งมีความสำคัญสำหรับผู้มาใหม่และการใช้งานทั่วไป จากนั้นก็ยุ่งเกินไปที่จะเข้าร่วม VR hype เพื่อไม่ให้ขัดกับมุมมืดของเอกสาร

เราสามารถทำอะไรกับมันได้บ้าง

บอกพวกเขาว่าพวกเขามองข้าม“ มุมมืด” นี้ในเอกสารประกอบเช่น: ใน Unity Editor เปิดHelp → Report a bug...ให้What is problem related toเลือกdocumentationฯลฯ

สิ่งหนึ่งสามารถใช้แทน

ตัวเลือกที่เป็นไปได้รวมถึง:

  • การใช้งานของคุณเอง ขึ้นอยู่กับCameraFacingBillboard ของ UnifyCommunityตัวอย่างเช่น
  • รับหรือซื้อระบบบุคคลที่สามในความสามัคคีร้านสินทรัพย์

2
อีกทางเลือกหนึ่ง: บ่อยครั้งเมื่อฉันต้องการวางแผงป้ายโฆษณาจำนวนมากฉันใช้ระบบอนุภาคโดยที่มีการปล่อยและแอนิเมชั่นของมันปิดอยู่
DMGregory

@DMGregory ไม่เห็นด้วยระบบอนุภาคของ Unity นั้นยอดเยี่ยมสำหรับหลาย ๆ สิ่งที่ไม่ได้อยู่ใกล้กับ“ อนุภาค” ในระยะไกล ยิ่งไปกว่านั้นตั้งแต่ Unity 5 การสนับสนุนสำหรับการปรับแต่งระบบอนุภาคได้รับการปรับปรุง / ปรับให้เหมาะสมอย่างชัดเจน ฉันควรเพิ่มตัวเลือกนี้ในคำตอบหรือความคิดเห็นเหล่านี้เพียงพอคุณคิดอย่างไร
Maxim Kamalov

ฉันคิดว่ามันเป็นเรื่องดีที่จะแสดงความคิดเห็น หากใครต้องการรายละเอียดเพิ่มเติมฉันคิดว่ามันเนื้อมากพอที่จะถามคำถามใหม่
DMGregory

ฉันไม่เชื่อว่าสำหรับการใช้งานภายในหมอกล่าวว่า: "คุณสามารถสร้างของคุณเองได้เมื่อคุณรู้วิธีอธิบายป้ายโฆษณา" - docs.unity3d.com/ScriptReference/BillboardAsset.html
123iamking

@ 123iamking และตอนนี้มีคุณสมบัติที่เปิดเผยมากขึ้น ดังนั้นใช่อาจเป็นไปได้ที่จะใช้พวกเขาโดยตรง
Maxim Kamalov

1

ในการใช้งาน BillboardRenderer คุณต้องมีสินทรัพย์ของป้ายโฆษณาคุณสามารถสร้างสินทรัพย์บิลบอร์ดด้วยสคริปต์ C # ตรวจสอบโพสต์นี้

เนื้อหาของ Billboard มีเนื้อหาเช่นนี้: 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}

นี่คือรหัส C # ที่ใช้สร้างไฟล์ด้านบน

 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
     }

สำหรับรายละเอียดเพิ่มเติมโปรดตรวจสอบโพสต์ที่ฉันให้ไว้ในตอนต้นของคำตอบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.