• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by joshisironman · Apr 28, 2020 at 01:40 PM · texture2datlasprocedural generation

Cannot apply texture2D to material,How to apply Texture2D to material at runtime

Hi all. I'm trying to create a cubeworld-like game in which I'm programatically creating a texture atlas to combine all of my textures into one. I'm then creating cubes (made of quads) that I want to apply the texture atlas to (specifying uvs too of course). The problem I'm having is that the rendered cubes (or chunks) have the default silver material applied with none of my textures. Can someone see where I am going wrong.

Here is a repo for all the code: https://github.com/JoshPJackson/BlockGame

result

The general flow of logic:

  1. Create texture atlas (and store rects)

  2. Create 6 quads to make a cube

  3. Add mesh renderer to quads

  4. Specify uvs

  5. Apply texture atlas texture to quad mesh renderer

At the bottom few lines of the Block.cs file is where I'm applying the texture atlas to the mesh renderer material

My texture atlas creator: using System.Collections.Generic; using System.IO; using UnityEngine; using System;

 namespace Game.Textures
 {
     public class TextureAtlasMapper
     {
         public Texture2D atlas;
 
         public Texture2D[] textures;
 
         public Rect[] rects;
 
         public Dictionary<string, Rect> mappedTextures;
 
         protected float individualHeight = 32.0f;
 
         protected float individualWidth = 32.0f;
 
         public TextureAtlasMapper()
         {
             UnityEngine.Object[] objects = Resources.LoadAll("textures") as UnityEngine.Object[];
             textures = new Texture2D[objects.Length];
 
             for (int i = 0; i < objects.Length; i++)
             {
                 textures[i] = (Texture2D) objects[i];
             }
             
             atlas = new Texture2D(2048, 2048);
             atlas.name = "myatlas";
             rects = atlas.PackTextures(textures, 2);
             mappedTextures = new Dictionary<string, Rect>();
 
             for (int i = 0; i < rects.Length; i++)
             {
                 mappedTextures[textures[i].name] = rects[i];
             }
         }
 
         public float GetImageHeight()
         {
             return atlas.height;
         }
 
         public float GetImageWidth()
         {
             return atlas.width;
         }
 
         public Vector2[] GetMappedUVs(string textureName)
         {
             if (!mappedTextures.ContainsKey(textureName))
             {
                 Debug.Log("missing entry: " + textureName);
             }
 
                 Rect rect = mappedTextures[textureName];
             
 
             Vector2[] list = new Vector2[4];
 
             float u1 = rect.x + rect.width;
             float u2 = rect.x;
             float u3 = u2;
             float u4 = u1;
 
             float v1 = rect.y + rect.height;
             float v2 = v1;
             float v3 = rect.y;
             float v4 = v3;
 
             list.SetValue(new Vector2(u1, v1), 0);
             list.SetValue(new Vector2(u2, v2), 1);
             list.SetValue(new Vector2(u3, v3), 2);
             list.SetValue(new Vector2(u4, v4), 3);
 
             return list;
         }
     }
 }
 

My quad mesh class: using System.Collections; using System.Collections.Generic; using UnityEngine; using Game.Textures; using Game.Blocks;

namespace Game.Meshes { public class QuadMesh { Vector3[] allVertices = new Vector3[8];

     Vector3[] vertices = new Vector3[4];

     Vector3[] normals = new Vector3[4];

     Vector2[] uvs = new Vector2[4];

     public Mesh mesh; 

     int[] triangles = new int[6] { 3, 1, 0, 3, 2, 1 };

     public QuadMesh(Block.Cubeside side)
     {
         SetAllVertices();

         mesh = new Mesh();
         
         normals = GetNormalCollection(Vector3.up);

         switch (side)
         {
             case Block.Cubeside.BOTTOM:
                 vertices = GetVertexCollection(new int[] { 0, 1, 2, 3});
                 normals = GetNormalCollection(Vector3.down);
                 break;
             case Block.Cubeside.TOP:
                 vertices = GetVertexCollection(new int[] { 7, 6, 5, 4 });
                 break;
             case Block.Cubeside.LEFT:
                 vertices = GetVertexCollection(new int[] { 7, 4, 0, 3 });
                 normals = GetNormalCollection(Vector3.left);
                 break;
             case Block.Cubeside.RIGHT:
                 vertices = GetVertexCollection(new int[] { 5, 6, 2, 1 });
                 normals = GetNormalCollection(Vector3.right);
                 break;
             case Block.Cubeside.FRONT:
                 vertices = GetVertexCollection(new int[] { 4, 5, 1, 0 });
                 break;
             case Block.Cubeside.BACK:
                 vertices = GetVertexCollection(new int[] { 6, 7, 3, 2 });
                 break;
         }

         mesh.vertices = vertices;
         mesh.normals = normals;
         // mesh.uv = uvs;

         Vector2 uv00 = new Vector2(0f, 0f);
         Vector2 uv10 = new Vector2(1f, 0f);
         Vector2 uv01 = new Vector2(0f, 1f);
         Vector2 uv11 = new Vector2(1f, 1f);
         mesh.uv = new Vector2[] { uv11, uv01, uv00, uv10 };

         mesh.triangles = triangles;
         mesh.RecalculateBounds();
     }

     private void SetAllVertices()
     {
         allVertices.SetValue(new Vector3(-0.5f, -0.5f, 0.5f), 0);
         allVertices.SetValue(new Vector3(0.5f, -0.5f, 0.5f), 1);
         allVertices.SetValue(new Vector3(0.5f, -0.5f, -0.5f), 2);
         allVertices.SetValue(new Vector3(-0.5f, -0.5f, -0.5f), 3);
         allVertices.SetValue(new Vector3(-0.5f, 0.5f, 0.5f), 4);
         allVertices.SetValue(new Vector3(0.5f, 0.5f, 0.5f), 5);
         allVertices.SetValue(new Vector3(0.5f, 0.5f, -0.5f), 6);
         allVertices.SetValue(new Vector3(-0.5f, 0.5f, -0.5f), 7);
     }

     private Vector3[] GetVertexCollection(int[] indices)
     {
         Vector3[] toReturn = new Vector3[4];

         for (int i = 0; i < indices.Length; i++)
         {
             toReturn.SetValue(allVertices[indices[i]], i);
         }

         return toReturn;
     }

     private Vector3[] GetNormalCollection(Vector3 normal)
     {
         return new Vector3[4]
         {
             normal,
             normal,
             normal,
             normal
         };
     }
 }

}

And my base block class:

 using System.Collections;
 using System.Collections.Generic;
 using System;
 using UnityEngine;
 using UnityEngine.U2D;
 using Game.Meshes;
 using Game.Textures;
 using Game.Chunks;
 
 namespace Game.Blocks
 {
     abstract public class Block
     {
         // cube sides
         public enum Cubeside { BOTTOM, TOP, LEFT, RIGHT, FRONT, BACK };
 
         // block types
         public enum BlockType { AIR, DIRT, GRASS }
 
         // uvs
         public virtual string[] textureNames { get; }
 
         public bool isSolid = true;
 
         // global position
         public Vector3 globalPosition;
 
         public Vector3 localPosition;
 
         // parent chunk
         public Chunk chunk;
 
         // position inside chunk
         public Vector3 positionInChunk;
 
         public Cubeside[] renderedSides;
 
         public Mesh mesh;
 
         public GameObject parent;
         
         public WorldBuilder worldBuilder()
         {
             return chunk.parent.parent;
         }
 
         public void Render()
         {
             if (this.GetType() != typeof(Air)) {
                 if (HasAirBack())
                 {
                     CreateQuad(Cubeside.BACK);
                 }
 
                 if (HasAirBelow())
                 {
                     CreateQuad(Cubeside.BOTTOM);
                 }
 
                 if (HasAirFront())
                 {
                     CreateQuad(Cubeside.FRONT);
                 }
 
                 if (HasAirAbove())
                 {
                     CreateQuad(Cubeside.TOP);
                 }
 
                 if (HasAirLeft())
                 {
                     CreateQuad(Cubeside.LEFT);
                 }
 
                 if (HasAirRight())
                 {
                     CreateQuad(Cubeside.RIGHT);
                 }
             }
         }
 
         public bool HasAirAbove()
         {
             int maxHeight = ChunkColumn.chunksPerColumn * Chunk.size;
 
             if (globalPosition.y + 1 > maxHeight - 1)
             {
                 return true;
             }
 
             Block blockAbove = worldBuilder().GetBlockAtGlobalPosition(new Vector3(
                 globalPosition.x,
                 globalPosition.y + 1,
                 globalPosition.z
             ));
             
             return blockAbove.GetType() == typeof(Air);
         }
 
         public bool HasAirBelow()
         {
             if (globalPosition.y - 1 >= 0)
             {
 
                 Block blockAbove = worldBuilder().GetBlockAtGlobalPosition(new Vector3(
                     globalPosition.x,
                     globalPosition.y - 1,
                     globalPosition.z
                 ));
 
                 return blockAbove.GetType() == typeof(Air);
             }
 
             return true;
         }
 
         public bool HasAirLeft()
         {
             if (globalPosition.x - 1 >= 0)
             {
                 Block blockAbove = worldBuilder().GetBlockAtGlobalPosition(new Vector3(
                     globalPosition.x - 1,
                     globalPosition.y,
                     globalPosition.z
                 ));
 
 
                 return blockAbove.GetType() == typeof(Air);
             }
 
             return true;
         }
 
         public bool HasAirRight()
         {
             if (globalPosition.x + 1 < worldBuilder().Size.x * Chunk.size)
             {
                 Block blockAbove = worldBuilder().GetBlockAtGlobalPosition(new Vector3(
                     globalPosition.x + 1,
                     globalPosition.y,
                     globalPosition.z
                 ));
 
                 return blockAbove.GetType() == typeof(Air);
             }
 
             return true;
         }
 
         public bool HasAirBack()
         {
             if (globalPosition.z - 1 >= 0)
             {
                 Block blockAbove = worldBuilder().GetBlockAtGlobalPosition(new Vector3(
                     globalPosition.x,
                     globalPosition.y,
                     globalPosition.z - 1
                 ));
 
                 return blockAbove.GetType() == typeof(Air);
             }
 
             return true;
         }
 
         public bool HasAirFront()
         {
             if (globalPosition.z + 1 < worldBuilder().Size.x * Chunk.size - 1)
             {
                 Block blockAbove = worldBuilder().GetBlockAtGlobalPosition(new Vector3(
                     globalPosition.x,
                     globalPosition.y,
                     globalPosition.z + 1
                 ));
 
                 return blockAbove.GetType() == typeof(Air);
             }
 
             return true;
         }
 
         public virtual void CreateQuad(Cubeside side)
         {
             string[] textures = new String[6];
 
             if (textureNames.Length == 1)
             {
                 for (int j = 0; j < 6; j++)
                 {
                     textures[j] = textureNames[0];
                 }
             } else
             {
                 textures = textureNames;
             }
 
             for (int i = 0; i < textures.Length; i++)
             {
                 QuadMesh quadMesh = new QuadMesh(side);
 
                 TextureAtlasMapper mapper = Game.currentGame.mapper;
                 Vector2[] uvs = mapper.GetMappedUVs(textures[i]);
                 
                 GameObject quad = new GameObject("Quad");
 
                 quad.transform.position = globalPosition;
                 quad.transform.parent = chunk.GameObject.transform;
                 MeshFilter meshFilter = (MeshFilter)quad.AddComponent(typeof(MeshFilter));
                 Mesh myMesh = quadMesh.mesh;
                 myMesh.uv = uvs;
                 myMesh.RecalculateBounds();
                 myMesh.name = "my mesh";
                 meshFilter.mesh = myMesh;
 
                 MeshRenderer renderer = quad.AddComponent(typeof(MeshRenderer)) as MeshRenderer;
                 renderer.material = new Material(Shader.Find("Standard"));
                 renderer.material.mainTexture = mapper.atlas;
             }
         }
     }
 }
 


untitled.png (34.0 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Cuttlas-U · Apr 29, 2020 at 05:52 AM

hey; thats hell of a code :D

u should be new to unity right ? but your codes are so far beyond me :P

i just thought i can maybe help ;

so first of all its better you create the quad like this :

  Instantiate(GameObject.CreatePrimitive(PrimitiveType.Quad));

so it has all the things it needs;

for changing the texture i suggest u use Texture and not Texture2D;

for assigning u better do it this way :

    quad.GetComponent<Renderer>().sharedMaterial.mainTexture = yourTexture;


try this with a ready texture first ; if it works then apply it to your runtime Texture and see if it works there too ;

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

206 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Question for @Mavina , What Program? 1 Answer

How to get a readable sprite from a unreadable sprite that is packed into an sprite atlas in player builds 0 Answers

OpenGL textures always show up black 0 Answers

How to draw a texture on another texture 0 Answers

How to get rgb from Texture2D faster? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges