/// <summary>
        /// Sets new Daggerfall material and recreates mesh.
        /// Will use an atlas if specified in DaggerfallUnity singleton.
        /// </summary>
        /// <param name="dfUnity">DaggerfallUnity singleton. Required for content readers and settings.</param>
        /// <param name="archive">Texture archive index.</param>
        /// <param name="record">Texture record index.</param>
        /// <param name="frame">Frame index.</param>
        /// <param name="dungeon">This is a dungeon billboard.</param>
        /// <returns>Material.</returns>
        public Material SetMaterial(int archive, int record, int frame, bool dungeon)
        {
            // Get DaggerfallUnity
            DaggerfallUnity dfUnity = DaggerfallUnity.Instance;

            if (!dfUnity.IsReady)
            {
                return(null);
            }

            // Get references
            meshRenderer = GetComponent <MeshRenderer>();

            Vector2  size;
            Mesh     mesh     = null;
            Material material = null;

            if (dfUnity.MaterialReader.AtlasTextures)
            {
                material = dfUnity.MaterialReader.GetMaterialAtlas(
                    archive,
                    0,
                    4,
                    2048,
                    out summary.AtlasRects,
                    out summary.AtlasIndices,
                    4,
                    true,
                    0,
                    false);
                mesh = dfUnity.MeshReader.GetBillboardMesh(
                    summary.AtlasRects[summary.AtlasIndices[record].startIndex],
                    archive,
                    record,
                    out size,
                    dungeon);
                summary.AtlasedMaterial = true;
                if (summary.AtlasIndices[record].frameCount > 1)
                {
                    summary.AnimatedMaterial = true;
                }
                else
                {
                    summary.AnimatedMaterial = false;
                }
            }
            else
            {
                material = dfUnity.MaterialReader.GetMaterial(
                    archive,
                    record,
                    frame,
                    0,
                    out summary.Rect,
                    4,
                    true);
                mesh = dfUnity.MeshReader.GetBillboardMesh(
                    summary.Rect,
                    archive,
                    record,
                    out size,
                    dungeon);
                summary.AtlasedMaterial  = false;
                summary.AnimatedMaterial = false;
            }

            // Update material properties
            MaterialReader.SetBlendMode(material, MaterialReader.CustomBlendMode.Cutout);

            // Set summary
            summary.InDungeon = dungeon;
            summary.FlatType  = MaterialReader.GetFlatType(archive);
            summary.Archive   = archive;
            summary.Record    = record;
            summary.Size      = size;

            // Set editor flat types
            if (summary.FlatType == FlatTypes.Editor)
            {
                summary.EditorFlatType = MaterialReader.GetEditorFlatType(summary.Record);
            }

            // Assign mesh and material
            MeshFilter meshFilter = GetComponent <MeshFilter>();
            Mesh       oldMesh    = meshFilter.sharedMesh;

            if (mesh)
            {
                meshFilter.sharedMesh       = mesh;
                meshRenderer.sharedMaterial = material;
            }
            if (oldMesh)
            {
                // The old mesh is no longer required
                DestroyImmediate(oldMesh);
            }

            // Standalone billboards never cast shadows
            meshRenderer.shadowCastingMode = ShadowCastingMode.Off;

            return(material);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates mesh and material for this enemy.
        /// </summary>
        /// <param name="dfUnity">DaggerfallUnity singleton. Required for content readers and settings.</param>
        /// <param name="archive">Texture archive index derived from type and gender.</param>
        private void AssignMeshAndMaterial(DaggerfallUnity dfUnity, int archive)
        {
            // Get mesh filter
            if (meshFilter == null)
            {
                meshFilter = GetComponent <MeshFilter>();
            }

            // Vertices for a 1x1 unit quad
            // This is scaled to correct size depending on facing and orientation
            float hx = 0.5f, hy = 0.5f;

            Vector3[] vertices = new Vector3[4];
            vertices[0] = new Vector3(hx, hy, 0);
            vertices[1] = new Vector3(-hx, hy, 0);
            vertices[2] = new Vector3(hx, -hy, 0);
            vertices[3] = new Vector3(-hx, -hy, 0);

            // Indices
            int[] indices = new int[6]
            {
                0, 1, 2,
                3, 2, 1,
            };

            // Normals
            Vector3 normal = Vector3.Normalize(Vector3.up + Vector3.forward);

            Vector3[] normals = new Vector3[4];
            normals[0] = normal;
            normals[1] = normal;
            normals[2] = normal;
            normals[3] = normal;

            // Create mesh
            Mesh mesh = new Mesh();

            mesh.name      = string.Format("MobileEnemyMesh");
            mesh.vertices  = vertices;
            mesh.triangles = indices;
            mesh.normals   = normals;

            // Assign mesh
            meshFilter.sharedMesh = mesh;

            // Load material atlas
            Material material = dfUnity.MaterialReader.GetMaterialAtlas(
                archive,
                0,
                4,
                1024,
                out summary.AtlasRects,
                out summary.AtlasIndices,
                4,
                true,
                0,
                false);

            // Update material properties
            MaterialReader.SetBlendMode(material, MaterialReader.CustomBlendMode.Cutout);

            // Set new enemy material
            GetComponent <MeshRenderer>().sharedMaterial = material;
        }