Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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
0
Question by aegis911 · Aug 27, 2018 at 07:43 AM · spritetexture2dsetpixel

Erasing a part of an image using SetPixel without gaps

I am creating a project in which a part of an image can be erased with a mouse click/drag. I have already made the mouse click. However, when the mouse is dragged quickly, there are gaps between the erased part like this. alt text Is there a solution for this? Below is my code which was taken from here.

 void Update () {
         hit = Physics2D.Raycast (Camera.main.ScreenToWorldPoint (Input.mousePosition), Vector2.zero);
         if (Input.GetMouseButton (0) && hit) {
             UpdateTexture ();
         }
     }
 
     public void UpdateTexture() {
         spriteRend = gameObject.GetComponent<SpriteRenderer> ();
         tex = CopyTexture (spriteRend.sprite.texture);
         string tempName = spriteRend.sprite.name;
         spriteRend.sprite = Sprite.Create (tex, spriteRend.sprite.rect, new Vector2 (0.5f, 0.5f));
         spriteRend.sprite.name = tempName;
     }
 
     public Texture2D CopyTexture(Texture2D copiedTexture) {
         float dX, dY;
         Texture2D newTex = new Texture2D (copiedTexture.width, copiedTexture.height);
         newTex.filterMode = FilterMode.Bilinear;
         newTex.wrapMode = TextureWrapMode.Clamp;
 
         int mX = (int)((hit.point.x - hit.collider.bounds.min.x) * (copiedTexture.width / hit.collider.bounds.size.x));
         int mY = (int)((hit.point.y - hit.collider.bounds.min.y) * (copiedTexture.height / hit.collider.bounds.size.y));
 
         for (int x = 0; x < newTex.width; x++) {
             for (int y = 0; y < newTex.height; y++) {
                 dX = x - mX;
                 dY = y - mY;
 
                 if (dX * dX + dY * dY <= erSize * erSize) {
                     newTex.SetPixel (x, y, zeroAlpha);
                 } else {
                     newTex.SetPixel (x, y, copiedTexture.GetPixel (x, y));
                 }
             }
         }
         newTex.Apply ();
         return newTex;
     }


unity.png (133.4 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

2 Replies

· Add your reply
  • Sort: 
avatar image
5
Best Answer

Answer by Bunny83 · Aug 27, 2018 at 11:09 AM

Don't do a check againt a point but against a line segment. The only difference is that before you do the distance check you have to project the coordinate of the current pixel you're testing onto the line segment . Of course this projected point need to be clamped between the start and end points of the line. Once you have that point you can simply subtract the projected point from x and y instead of just the new point. This will naturally draw a "line" with a width of twice your radius. It's basically the shadow of a capsule.


So all you need is to save the last position while dragging so you have that line segment you need. Note that currently you iterate over all pixels in the image. This could be optimised by just iterating over the bounding rectangle of your line segment. So just figure out the min and max values of your start and end coordinates and add / subract the radius and finally clamp the result to the image resolution. Finally you shouldn't use SetPixel in a loop. It's much more efficient to use GetPixels once in Start, modify the array and use SetPixels after your processing.


Also you shouldn't create a new texture each time. Unused Textures need to be destroyed or you will run out of memory. You may also want to create a single texture which you are going to modify in start and reuse that texture..


edit

I just created a script based on your approach but heavily modified it with the changes i've mentioned.


Here's an example of the script in action. The first radius is 10, the second is 40

Gif: https://www.dropbox.com/s/qlanau5rm1y7xdl/TextureLineDrawing.gif


Note the image used here is "1024x240" and works smoothly. Though if you have a larger image you may run into performance issues as updating such large images is always a problem as it has to be uploaded to the GPU each time. You might get better performance when creating an actual mask mesh and only apply the drawn lines every now and then. Though for relatively small images the current approach seems to work fine.

Comment
Add comment · Show 5 · 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 aegis911 · Aug 28, 2018 at 07:18 AM 0
Share

Thank you so much for your answer. I never thought you would modify the script. I had a hard time understanding your explanation because I am new in Unity and it is advanced for me. But based on your script I kinda understand it now. It worked perfectly. Again, thank you so much.

avatar image Nevel · Sep 28, 2020 at 11:53 AM 0
Share

Amazing answer, but could you please explain for real newbie: 1) Is this script should be attached to Image that have Sprite Renderer? 2) What type of collider i have to use?

I create sprite renderer object, assign to sprite my texture, in texture setting made it readable and type of Sprite then add your script and looks likes it needs collider 2d? Because "Drawing" bool variable never true without it. After adding Box 2d collider i can only cut center part, but can't drag or something like you show.

Could you help please?

avatar image Bunny83 Nevel · Sep 30, 2020 at 09:01 AM 0
Share

Yes, a BoxCollider2d should work just fine as long as it covers the whole image. Please keep in $$anonymous$$d that this is a 2d solution. Also check what value you have in your "erSize" variable. It defines the drawing / "erasing" radius.


Please note that this script was meant as an example for the described technique. It can and might need to be adjusted to your specific usecase. You are free to use the script as it is but this was never meant to be a universally and robust solution.

avatar image ygocmen98 Bunny83 · Oct 24, 2020 at 05:53 PM 0
Share

Hi man i am trying to do same thing with aegis.

I couldn't reach ur script i think that link is broken, can you share it with me? or you can tell me ur way to do this.

avatar image Julia_sho · Aug 16, 2021 at 01:12 AM 0
Share

@Bunny83 thank you so much. It is working perfectly. I have one request. Would you please tell us here — how to calculate the pixel amount which have been erased (how much portion is erased). For my game I want to show LEVEL COMPLETE after fully erased the sprite. Sorry for my bad English. Btw I am very new in unity. Thanks.

avatar image
0

Answer by KrazyTeam · Nov 05, 2020 at 03:09 PM

@Bunny83 alt textbrother your code is very clean and good in working thanks for that but, this work fine in a single sprite when I try this with sprite sheet it work something wrong could you please help.

,your code is very clean and good in working thanks for that but, this work fine in a single sprite when I try this with sprite sheet it work something wrong could you please help alt text


1-1.png (109.1 kB)
1-1.png (109.1 kB)
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

127 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

Related Questions

SetPixel on a sprite texture without changing it globally 1 Answer

Painting sprite in unity 1 Answer

Texture2D Power of 2 0 Answers

Image is crushed --- Sprite 2 Answers

Clearing pixel from texture changes the asset as well? 2 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