Как использовать BillboardRenderer в Unity?

11

Начиная с версии 5 (?) В Unity появился новый тип компонента BillboardRenderer. К сожалению, документация довольно скудная.

Его можно добавить в инспекторе, нажав «Добавить компонент -> Разное -> Billboard Renderer», но, по-видимому, Billboard Assetдля выполнения чего-либо требуется . Кажется, нет никакого способа создать его из интерфейса Unity.

Одно из немногих предложений из столь же плохой документации BillboardAsset гласит:

imageCount Количество предварительно запеченных изображений, которые можно переключать при просмотре рекламного щита под разными углами.

Мой новый проект будет содержать графику со спрайтом и многоугольником, поэтому я действительно могу использовать компонент, который отображает рекламный щит с другим спрайтом в зависимости от угла обзора. Но, похоже, нет способа добавить такие изображения.

Поэтому я подумал, не могли бы вы опубликовать пример, как этот компонент используется.

Philipp
источник
Рекламный щит делает то, что я ожидал? Или что-то другое? (Я ожидаю, что это сохранит изображение лицом к камере.)
Evorlor
@ Evorlor Это то, что я тоже ожидал, но пока мне не удалось заставить его что- либо сделать .
Филипп

Ответы:

6

ОБНОВЛЕНИЕ (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);
    }
}

Буквально нет возможности устанавливать изображения, даже с помощью отражения. Кто-то может подумать: «Хорошо, вы не можете сделать это напрямую, но, может быть, есть какая-то фабрика?». Я нажимаю Find Usages в декомпиляторе и получаю: BillboardAssetInspectorи BillboardRenderer.

Вот 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.dll , BillboardAssetInspector(которое находится в UnityEditor.dll ) содержит настоящий код. Опять же, я не буду помещать здесь его код, потому что из его названия ясно, что в любом случае это не что иное, как инспектор .

Та же ситуация с BillboardAssetInspector.


Понял, это для внутреннего использования; но где именно он используется?

В системе SpeedTree (посмотрите на последнее изображение в частности).

Почему документация объясняет бесполезные вещи, а не предостерегает от их использования сразу?

Вероятно, просто скопируйте все из внутренней документации по разработке, улучшенных частей, которые важны для новичков и общего использования; затем был слишком занят, участвуя в шумихе над VR, чтобы потрудиться над темными полями документации.

Что мы можем с этим поделать?

Скажите им, что они пропустили этот «темный угол» в документации, например: в редакторе Unity откройте Help → Report a bug..., What is problem related toвыберите documentationи т. Д.

Что можно использовать вместо этого?

Возможные варианты включают в себя:

Максим Камалов
источник
2
В качестве другой альтернативы: часто, когда мне нужно разместить кучу рекламных щитов, я использую систему частиц с отключенной эмиссией и анимацией, чтобы я мог вручную расположить каждый квадрат с рекламными щитами там, где он мне нужен.
DMGregory
@DMGregory Не могу не согласиться, система частиц Unity отлично подходит для многих вещей, которые даже близко не расположены к «частицам». Еще лучше, начиная с Unity 5, поддержка настройки системы частиц была явно улучшена / оптимизирована. Должен ли я добавить эту опцию в ответ, или этих комментариев достаточно, что вы думаете?
Максим Камалов
Я думаю, что это хорошо, чтобы оставить в комментариях. Если кто-то хочет получить больше подробностей, я думаю, что это достаточно сложно, чтобы задать новый вопрос.
DMGregory
Я не верю в это для внутреннего использования, сказал доктор: «Вы также можете создать свой собственный, как только узнаете, как описывается рекламный щит». - docs.unity3d.com/ScriptReference/BillboardAsset.html
123iamking
@ 123iamking А теперь еще больше свойств выставлено. Так что, да, возможно, возможно использовать их прямо сейчас.
Максим Камалов
1

Чтобы использовать BillboardRenderer, вам нужен Billboard Asset, вы можете создать Billboard Asset с помощью скрипта C #. Проверьте этот пост .

У Billboard Asset есть такой контент: 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
     }

для более подробной информации, пожалуйста, проверьте пост, который я дал в начале ответа.

123iamking
источник