Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
2
Question by esitoinatteso · Oct 15, 2013 at 09:50 PM · fliptilingtextureing

Flip a Texture?

Hi there! Allow me to ask you another newbie question please... In photoshop I flip a 2d image like this: edit -> transform -> flip; how would I do that in Unity? I mean WITH code.

See, I did some web researches but every click draw me even more far away, toward topics related to textures but not to the solution. I know every Shader has this Tiling and Offset thing, and I've read that to flip a texture horizontally you just need to change to -1 the Tiling in your inspector... fact is that I couldn't be able to grasp how to do that with code.

I tried a brutish renderer.lightmapTilingOffset = new Vector4(-1,1,0,0) but nothing happens, I also tried renderer.material.mainTextureTiling = new Vector2(-1,0) but ofcourse mainTextureTiling doesn't exist ( why?).

I'm ignorant but eager to know how, I'm not asking for plain code, maybe just a push in the right direction... my searches brought me here: http://docs.unity3d.com/Documentation/Manual/ShaderTut1.html; This is pertinent but non exactly what I need here, am I wrong? I also stumbled upon this http://docs.unity3d.com/Documentation/ScriptReference/Material.html but as you can see, there is mainTextureOffset but not Tiling.

I'm missing something... thanks a lot for your patience ( AND if it turns out an answer already exist, forgive my thoughtlessness)!

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
4
Best Answer

Answer by robertbu · Oct 15, 2013 at 10:01 PM

 renderer.material.SetTextureScale("_MainTex", new Vector2(-1,1));

Note this assumes that your shaders main texture is defined as _MainTex. This is true of most shaders but not all. While not specific to your question, changing material properties takes a shared material and generates a new material instance and therefore breaks draw call batching. An alternate method of flipping the texture that does not break batching is to change the UV coordinates directly in the mesh (more complicated).

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 esitoinatteso · Oct 15, 2013 at 10:16 PM 0
Share

Hi robertbu! Thanks a lot, it certainly works! I've read something about the complicated method you say... I'll try to learn something more about this whole texture world ( again, my knowledge is scarce)... meantime, if you happen to be in a very generous mood and feel to bestow me some more informations about the topic, I'd be pleased to read them. Thanks again!

avatar image robertbu · Oct 15, 2013 at 10:41 PM 0
Share

Here is a bit of code that flips a texture using the UVs of the mesh. It will only work on a two triangles, four vertices planes. The new Quad game object (Game Object > Create Other > Quad) meets this criteria. Also the CreatePlane editor script will work as long as 'Width Segments' and 'Length Segments' are both set to 1. A 'V' key will flip it vertically, a 'H' key will flip it horizontally, and a 'B' key will flip it both directions.

 #pragma strict
 
 function Update() {
     if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.H))
         FlipQuadUV(true, false);
     else if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.V))
         FlipQuadUV(false, true);
     else if (Input.Get$$anonymous$$eyDown($$anonymous$$eyCode.B))
         FlipQuadUV(true, true);
 }
 
 function FlipQuadUV(horzFlip : boolean, vertFlip : boolean) {
     var mesh : $$anonymous$$esh = GetComponent($$anonymous$$eshFilter).mesh;
     var uvs = mesh.uv;
     if (uvs.Length != 4) {
         Debug.Log("Error: not a four vertices mesh");
         return;
     }
     for (var i = 0; i < uvs.Length; i++) {
         if (horzFlip) {
             if ($$anonymous$$athf.Approximately(uvs[i].x, 1.0))
                 uvs[i].x = 0.0;
             else
                  uvs[i].x = 1.0;
         }
         if (vertFlip) {
             if ($$anonymous$$athf.Approximately(uvs[i].y, 1.0)) 
                 uvs[i].y = 0.0;
             else
                 uvs[i].y = 1.0;
         }
     }
     mesh.uv = uvs;
 }
 


avatar image esitoinatteso · Jan 15, 2015 at 12:17 PM 0
Share

Right now I've resolved by using the same trick developers of Unity 2d sample project.

We must know the facing of our 2d sprite in the beginning, and make a bool to check if it's true. $$anonymous$$y assets have sprites only facing right, so my boolean is facingRight ( true).

Then, when something happens and the sprite must change facing, I use this code:

     void Flip(){
         facingRight = !facingRight;
         
         //Time to change your scale, best way is doing it with a method that works both ways around as above...
         Vector3 theScale = transform.localScale;
         theScale.x *= -1;
         transform.localScale = theScale;
         //Thanks Unity for this trick
     }

So... if you have an enemy that checks its target ( player) position, the code looks like this in the end:

     void Update () {
         Facing();
         if(isTargetRight && !facingRight){
             Flip();
         }
         if(!isTargetRight && facingRight){
             Flip ();
         }
     }
 
     void Facing () {
         //Check if the target is Right or Left
         float targetX = target.x;
         float myX = transform.position.x;
 
         if(targetX<myX){
             isTargetRight = false;
         }
         else{
             isTargetRight = true;
         }
     }

It works good :D

avatar image
1

Answer by Simonius Skjorn · Aug 12, 2014 at 11:05 PM

Another method would be to set the scale of the SpriteRenderer object directly:

 Vector3 scale = renderer.transform.localScale;
 scale.x = -scale.x;
 renderer.transform.localScale = scale;

Easiest by far and will get batched since Unity 4.5.X. Or the same thing via rotation (see the comment below that the scale might be problematic in some cases):

 Vector3 angles = renderer.transform.localEulerAngles;
 angles.y = 180;
 renderer.transform.localEulerAngles = angles;

Of course, this will depend on the pivot of the Sprite. If set to center, it will behave as expected. Otherwise you'll need to move it a bit.

Comment
Add comment · Show 4 · 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 robertbu · Aug 12, 2014 at 11:08 PM 0
Share

@Simonius Skjorn - I've seen a number of questions come across this list where colliders did not behave as they should when using -x to flip. Since sprites are rendered on both sides, rotating 180 on the 'y' may be a better choice.

avatar image Simonius Skjorn · Aug 13, 2014 at 04:41 AM 0
Share

@robertbu That's interesting. I haven't come across this problem yet, but I'll keep it in $$anonymous$$d. I would have thought it doesn't matter (aside from the rotation computation being a bit more extensive).

avatar image Percy-Pea · Jan 15, 2015 at 11:23 AM 0
Share

i'm using 4.6X and find the scale.x version does break batching, where as using the rotating method doesn't, so appears to be the better solution.

avatar image esitoinatteso · Jan 15, 2015 at 12:19 PM 0
Share

I'm now using the method posted in my comment to the answer, what do you think of it?

avatar image
0

Answer by silentreaver · Aug 14, 2020 at 03:10 PM

Sadly no solution is going to be really efficient without going into threading, which you may or may not be able to do, as to flip the texture you have to move all the pixels in the image around to truly "flip" the image. I've attempted to create the most efficient method for flipping a texture horizontally. This avoids performing multiple get or set pixels, and processes the pixels 2 at a time. This should work for your project:

  public static Texture2D FlipTexture(this Texture2D original)
     {
         int textureWidth = original.width;
         int textureHeight = original.height;
     
         Color[] colorArray = original.GetPixels();
                    
         for (int j = 0; j < textureHeight; j++)
         {
             int rowStart = 0;
             int rowEnd = textureWidth - 1;
     
             while (rowStart < rowEnd)
             {
                 Color hold = colorArray[(j * textureWidth) + (rowStart)];
                 colorArray[(j * textureWidth) + (rowStart)] = colorArray[(j * textureWidth) + (rowEnd)];
                 colorArray[(j * textureWidth) + (rowEnd)] = hold;
                 rowStart++;
                 rowEnd--;
             }
         }
                   
         Texture2D finalFlippedTexture = new Texture2D(original.width, original.height);
         finalFlippedTexture.SetPixels(colorArray);
         finalFlippedTexture.Apply();
     
         return finalFlippedTexture;
     }
 
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.

Follow this Question

Answers Answers and Comments

16 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

Related Questions

how to change image texture using C# 2 Answers

Circular zoom control? 1 Answer

Fp controller, ios bug. 0 Answers

How to make Dual Joysticks for Android and IOS? 1 Answer

Using gyro to move with something? 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