Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • 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 /
avatar image
5
Question by MibZ · Jan 17, 2013 at 09:24 PM · textureruntimesystem.ioimport settings

Changing texture import settings during runtime

I'm working on a painting game that has to copy texture files during runtime, but I'm running into problems getting everything to work as desired.

After a lot of goofing around with all kinds of different copy, delete, and load functions I figured out that I need to be able to change import settings on individual textures during runtime. (OR at the very least I need to be able to enable read/write to a texture file)

Also: I want to avoid a situation that enables read/write for every texture in the game, ideally I would like to only flag the files I want for read/write.

Any insight?

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

3 Replies

· Add your reply
  • Sort: 
avatar image
7

Answer by MirrorIrorriM · Aug 04, 2013 at 06:05 PM

I ran into a similar problem in my own little paint program. I have figured out how to change their settings by using the AssetPostprocessor. As an example :

 using UnityEngine;
 using UnityEditor;
 
 public class TexturePostProcessor : AssetPostprocessor
 {
     
     void OnPreprocessTexture()
     {
         
         if(assetPath.Contains("DirectoryOfInterest"))
         {
             TextureImporter importer = assetImporter as TextureImporter;
             importer.textureType  = TextureImporterType.Advanced;
             importer.textureFormat = TextureImporterFormat.AutomaticTruecolor;
             importer.isReadable = true;
             importer.filterMode = FilterMode.Point;
             importer.npotScale = TextureImporterNPOTScale.None;
      
             Object asset = AssetDatabase.LoadAssetAtPath(importer.assetPath, typeof(Texture2D));
             if (asset)
             {
                 EditorUtility.SetDirty(asset);
             }
             else
             {
                importer.textureType  = TextureImporterType.Advanced ;   
             }
         }
         
     }
 }


You see here I'm able to change tons of different settings for the texture, including but not limited to read/write capability. What we are doing here is highjacking the importer before it actually applies the default settings, and applying our OWN default settings. This script must be placed inside a folder called "Editor" inside your asset hierarchy. By using if(assetPath.Contains("YourDirectoryHere")) you can change the import settings of files in a particular folder only. You can also have this check the name. For example if the name of your file was always going to be TempImageFIle, you could use assetPath.Contains("TempImageFile") to find it.

Finally, if create an image during runtime and want to be able to load the file without actually restarting the program, you need to refresh the unity assets. To do this you use AssetDataBase.Refresh(); Make sure whatever script calls AssetDataBase.Refresh() is using UnityEditor!

Comment
Add comment · Show 3 · 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
avatar image DaveA · Aug 04, 2013 at 06:55 PM 0
Share

You can also call this in Start on a script that is ExecuteInEdit$$anonymous$$ode

avatar image alok-kr-029 · Apr 03, 2015 at 11:25 AM 0
Share

HI $$anonymous$$irrorIrorri$$anonymous$$ how to call this function at runtime as I have a texture co$$anonymous$$g from server and I have to change its texture to readable and wri$$anonymous$$ble at runtime

avatar image panoramabeats · May 07, 2019 at 07:36 AM 0
Share

Worked great - Thank you so much! I only needed to set the NPOT to none, so I stripped away most of the rest.

avatar image
1

Answer by jogo13 · Jan 17, 2013 at 09:53 PM

The imported texture in the editor is not the texture that will be available in the runtime. (You can't change it during a real game build's runtime as there's no longer a untouched source texture to work from.)

You can manipulate it anyway you wish using Texture2D.SetPixels, etc. Keep in mind it creates additional ram/cpu usage. http://docs.unity3d.com/Documentation/ScriptReference/Texture2D.html

If you can achieve the desired effects using shaders instead that's recommended.

Comment
Add comment · Show 2 · 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
avatar image MibZ · Jan 17, 2013 at 10:05 PM 0
Share

I'm already using setpixels to paint on the texture, but setpixels is a very slow way to do a clear function, individually modifying 4 floats for each pixel in the texture. $$anonymous$$y solution to speed it up is to have a blank transparent texture that never gets modified kept in the textures folder and when Clear is called the current painting texture is deleted, the copy file is copied, and the new copy gets the same location and name of the old painting texture.

All of that works fine, but once I create the copy I can no longer use setpixels to change it because it is read only. Is there a way to set default texture importer settings so new files automatically get the values I want?

avatar image DaveA · Aug 04, 2013 at 06:51 PM 0
Share

http://docs.unity3d.com/Documentation/ScriptReference/Texture2D.SetPixels32.html says "Using SetPixels32 is faster than calling SetPixels."

avatar image
1

Answer by Pangamini · May 07, 2019 at 10:24 AM

I've made painting using GPU, that's what it's for, right? Obviously, you can't change import settings during runtime (it's IMPORT settings, just a way how to translate a png or other format to a texture. Once it's done it's done). You don't have to enable read/write, you can just blit / render your texture to a renderTexture (and then if you really want, you can read pixels from that). But for painting, i'd suggest entirely gpu-based solution, by sequentially rendering into a renderTexture and not clearing it.

Anyway here's my texture painting tool, as is

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class TexturePaint : System.IDisposable
 {
     private Texture2D m_targetTexture;
     private RenderTexture m_rt;
     private bool m_painting;
 
     public Material brush;
 
     public event System.Action<Texture> onDisplayTextureChanged;
 
     public bool painting
     {
         get { return m_painting; }
         set
         {
             if (m_painting == value) return;
             m_painting = value;
             if (m_painting)
                 OnBeginPainting();
             else
                 OnEndPainting();
         }
     }
 
     private void OnBeginPainting()
     {
         if (!m_rt)
             m_rt = new RenderTexture(2,2,24, RenderTextureFormat.ARGBFloat);
         m_rt.width = m_targetTexture.width;
         m_rt.height = m_targetTexture.height;
         m_rt.Create();
         
         Graphics.Blit(m_targetTexture, m_rt);
         if (onDisplayTextureChanged != null)
             onDisplayTextureChanged(m_rt);
     }
 
     private void OnEndPainting()
     {
         var tempLdr = RenderTexture.GetTemporary(m_rt.width, m_rt.height, 0, RenderTextureFormat.ARGB32);
         try
         {
             Graphics.Blit(m_rt, tempLdr);
             RenderTexture.active = tempLdr;
             m_targetTexture.ReadPixels(new Rect(0, 0, tempLdr.width, tempLdr.height), 0, 0, false);
             m_targetTexture.Apply(true);
             RenderTexture.active = null;
             m_rt.Release();
         }
         finally
         {
             RenderTexture.ReleaseTemporary(tempLdr);
             if (onDisplayTextureChanged != null)
                 onDisplayTextureChanged(m_targetTexture);
         }
     }
 
     public void Dispose()
     {
         painting = false;
     }
 
     ~TexturePaint()
     {
         Dispose();
     }
 
     public Texture2D targetTexture
     {
         get { return m_targetTexture;  }
         set
         {
             if (m_targetTexture == value)
                 return;
             m_targetTexture = value;
         }
     }
 
     public void Paint(Vector2 uv, float radius, float amount)
     {
         if (!painting) throw new System.InvalidOperationException();
         Paint(uv, radius, amount, brush, m_rt);
     }
 
     public static void Paint(Vector2 uv, float radius, float amount, Material brush, RenderTexture target )
     {
         var origColor = brush.color;
         try
         {
             var color = origColor;
             color.a *= amount;
             brush.color = color;
 
             Vector2 radius2 = new Vector2(radius, radius);
 
             Graphics.SetRenderTarget(target);
             GL.LoadOrtho();
             brush.SetPass(0);
             GL.Begin(GL.TRIANGLE_STRIP);
             GL.TexCoord2(1, 0);
             GL.Vertex(new Vector2(uv.x + radius2.x, uv.y - radius2.y));
             GL.TexCoord2(0, 0);
             GL.Vertex(new Vector2(uv.x - radius2.x, uv.y - radius2.y));
             GL.TexCoord2(1, 1);
             GL.Vertex(new Vector2(uv.x + radius2.x, uv.y + radius2.y));
             GL.TexCoord2(0, 1);
             GL.Vertex(new Vector2(uv.x - radius2.x, uv.y + radius2.y));
             GL.End();
         }
 
         finally
         {
             brush.color = origColor;
         }
     }
 
 
 }


Comment
Add comment · Show 1 · 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
avatar image Pangamini · May 07, 2019 at 10:28 AM 0
Share

It creates a renderTarget when you set painting to true. You are then allowed to paint using Paint() (even thousands of paints are fast, to draw a smooth line using a custom texture brush). Setting painting to false switches from renderTexture to a texture2D, generating mipmaps for nicer display. onDisplayTextureChanged event is called to notify the renderer of these texture swaps (so you know which texture should be displayed)

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.

Follow this Question

Answers Answers and Comments

15 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

Related Questions

Apply transparent texture to plain at runtime 1 Answer

Runtime Normal Map Import Issues 0 Answers

Assigning UV Map to model at runtime 0 Answers

Reverse of Texture.EncodeToEXR in unity? 0 Answers

Make a Texture2D gradient during run-time 1 Answer


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