Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Procedural Sprite Generation and Placement

Discussion in 'Scripting' started by Richard_Ingalls, Oct 5, 2023 at 9:58 PM.

  1. Richard_Ingalls

    Richard_Ingalls

    Joined:
    Dec 16, 2021
    Posts:
    85
    I am trying to make a script that will allow me to input a shape (ellipse, triangle, rectangle, rhombus, pentagon, hexagon, etc.), upper and lower bounds for sprite size, a color (using a hex code), a minimum distance, and a size for the generation area, and output a bunch of pixelated sprites scattered around an area (which is a regular version of whatever shape I inputted, for example, circle for ellipse, equilateral triangle for triangle, square for rectangle, etc.) using poisson disk sampling to prevent them from coming within the minimum distance I set for it, and it also creates colliders for each sprite, matching the shape of each sprite (as if it weren't pixelated, so that an object can slide along it), or, if possible, one big collider that covers each sprite and creates a border around everything, so that objects with colliders collide with the sprites and the border. I have included an image of example sprites. The sprites are pixelated, and have a border of roughly 9 pixels. This border should be included in the size of the sprite. The border should be the same color as the main body of the sprite, but slightly darker. If anyone knows of a free asset that can do this, or can give me the code to do this, or at least a code structure that makes it easy to do this, that would be great.
    SampleSprites.png
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,283
    Just try your hand at it, pick random spot, Instantiate the sprite, then start adding your layers of constraints.

    If you want to make a new sprite out of these, RenderTextures are your go-to solution.

    If you want more random procgen examples, I think I may have already told you about my MakeGeo project.

    MakeGeo is presently hosted at these locations:

    https://bitbucket.org/kurtdekker/makegeo

    https://github.com/kurtdekker/makegeo

    https://gitlab.com/kurtdekker/makegeo

    https://sourceforge.net/p/makegeo
     
  3. Richard_Ingalls

    Richard_Ingalls

    Joined:
    Dec 16, 2021
    Posts:
    85
    I don't know what in MakeGeo would be useful to me. I am not advanced enough in my coding skills to understand it yet, and I can't tell what does what. My biggest obstacle is creating pixelated sprites (pixel art, if that wasn't clear enough before) with the various shapes. I don't know how I would implement the creation of a random closed shape with a specific number of sides, fitting into a specific area, with pixels, and coloring the inside so that there is a ~9 pixel wide border, then the middle being a different color from the border.
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,638
    Can you not just... make the sprites in any art program, and make prefabs out of them?
     
  5. Richard_Ingalls

    Richard_Ingalls

    Joined:
    Dec 16, 2021
    Posts:
    85
    I could theoretically, but that would take hours upon hours. And I would need to do that every time I wanted a new set of parameters. Recoloring would be the only thing I could do quickly. Beyond that, it would take up a massive quantity of storage space. I need to automate the process. The part I need desperately is the pixel sprite generation. I need to be able to have various shapes with various sizes, each with a ~9 pixel wide border. I would also like to be able to create a pixelated grid (with gridlines ~4 pixels wide) in the shape of a regular polygon, with the gridlines tiling the plane with a regular polygon, or a regular polygon and a lot of triangles.
     
  6. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,638
    I feel like you're over complicating things, but if you don't know, Unity has a package for making sprite shapes: https://docs.unity3d.com/Packages/com.unity.2d.spriteshape@10.0/manual/index.html

    I would just make a prefab for each shape, and then these can be styled with different shape profiles.

    Then you just write some code to scatter them about the specified area, and apply the desired style. Should be fairly trivial.

    Otherwise you're going to have to elaborate on what you mean by this:
     
  7. Richard_Ingalls

    Richard_Ingalls

    Joined:
    Dec 16, 2021
    Posts:
    85
    What I mean by that is if I make pixel art prefabs, then I have to make a lot of various shaped ones for each shape that I want, and each size that I want. Let's say I want 3 possible shapes, each with 3 variants, and 3 sizes. That means I have to create 27 pixel arts in total. Ideally, I want at least 8 shapes, with at least 12 variants each, and at least 24 sizes. This would mean 2,304 prefabs. And if I decide to increase any or all parameters, the number gets even bigger. Not only would it take months at least to create all of this (which would be very boring), it would be very storage intensive, which is completely unreasonable for any game.
     
  8. Richard_Ingalls

    Richard_Ingalls

    Joined:
    Dec 16, 2021
    Posts:
    85
    Each shape variant will have different side lengths and angles, as long as it remains the same shape.
     
  9. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,638
    Then just use the sprite shape API to generate shapes via code.

    Or, perhaps easier, make a prefab for each 'normal' shape, triangle, square, pentagon, etc. And once you instance them, just move their control points around a bit to generate some form of randomness to their shape.
     
  10. Richard_Ingalls

    Richard_Ingalls

    Joined:
    Dec 16, 2021
    Posts:
    85
    That would work, but they have to be pixel art, and they have to have a border, and the pixels all have to be a certain size so that the border won't look like it's on a different grid. And I will also need to have rectangle, rhombus, and trapezoid separated. Also, I don't know how I would manipulate the control points.
     
  11. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,283
    And this is taking less time???

    Don't reach for automation until you can do the thing at least once by hand, start to finish, soup to nuts.

    Only then can you even consider automating.

    Fair point but every single scene / example in there pretty much does one thing. The code is generally commented and simple and clean, generally one instruction per line. If you're unable to learn from that, you really need to step up your learning game. This process may be helpful to you, particularly Step #2:

    Tutorials and example code are great, but keep this in mind to maximize your success and minimize your frustration:

    How to do tutorials properly, two (2) simple steps to success:

    Step 1. Follow the tutorial and do every single step of the tutorial 100% precisely the way it is shown. Even the slightest deviation (even a single character!) generally ends in disaster. That's how software engineering works. Every step must be taken, every single letter must be spelled, capitalized, punctuated and spaced (or not spaced) properly, literally NOTHING can be omitted or skipped.

    Fortunately this is the easiest part to get right: Be a robot. Don't make any mistakes.
    BE PERFECT IN EVERYTHING YOU DO HERE!!


    If you get any errors, learn how to read the error code and fix your error. Google is your friend here. Do NOT continue until you fix your error. Your error will probably be somewhere near the parenthesis numbers (line and character position) in the file. It is almost CERTAINLY your typo causing the error, so look again and fix it.

    Step 2. Go back and work through every part of the tutorial again, and this time explain it to your doggie. See how I am doing that in my avatar picture? If you have no dog, explain it to your house plant. If you are unable to explain any part of it, STOP. DO NOT PROCEED. Now go learn how that part works. Read the documentation on the functions involved. Go back to the tutorial and try to figure out WHY they did that. This is the part that takes a LOT of time when you are new. It might take days or weeks to work through a single 5-minute tutorial. Stick with it. You will learn.

    Step 2 is the part everybody seems to miss. Without Step 2 you are simply a code-typing monkey and outside of the specific tutorial you did, you will be completely lost. If you want to learn, you MUST do Step 2.

    Of course, all this presupposes no errors in the tutorial. For certain tutorial makers (like Unity, Brackeys, Imphenzia, Sebastian Lague) this is usually the case. For some other less-well-known content creators, this is less true. Read the comments on the video: did anyone have issues like you did? If there's an error, you will NEVER be the first guy to find it.

    Beyond that, Step 3, 4, 5 and 6 become easy because you already understand!
     
  12. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,638
    Christ, are you going to ramble on about your requirements forever or actually sit down and try and implement something?

    Yes you can have a border. That's what the sprite controller does. And you just need to look at the scripting API to see how you can modify the points.

    C'mon mate, get to it.
     
    Kurt-Dekker likes this.
  13. Nad_B

    Nad_B

    Joined:
    Aug 1, 2021
    Posts:
    270
    You may have more luck with ChatGPT (at least giving you ideas) than this forum, as your request is not clear/precise but pretty vague and covers lot of programming topics. Generally developers just don't give (complex) code for free.

    What you're trying to achieve can be resumed in this pseudo-code:

    Code (CSharp):
    1. public void GenerateRandomArt(int partsCount = 5)
    2. {
    3.     // All parts, we could assign it from Editor, or use Resources.LoadAll<ArtPart>()
    4.     // You could also have different lists for heads, bodies, legs... where you can pick
    5.     // one random item from each list
    6.     ArtPart[] allArtParts = GetAllArtParts();
    7.  
    8.     // Create a new list holding the parts we want to assemble
    9.     var artParts = new List<ArtPart>();
    10.  
    11.     while (artParts.Count < partsCount)
    12.     {
    13.         var randomPart = allArtParts[Random.Range(0, allArtParts.Length);
    14.    
    15.         // We check if the part is valid/compatible with
    16.         // the other parts we already have...
    17.         if (IsValidArtPart(randomPart, artParts))
    18.             artParts.Add(randomPart);
    19.     }
    20.  
    21.     // Draw the sprite from the parts we have
    22.     DrawSprite(artParts);
    23. }
    24.  
    25. [MenuItem("Art Part", "Art/Art Part")]
    26. public class ArtPart : ScriptableObject
    27. {
    28.     public Sprite Sprite;
    29.     public Vector2 AttachmentPoint;
    30.     // Or a reference to a Prefab containing the necessary data...
    31. }
    32.  
     
    Last edited: Oct 6, 2023 at 11:39 PM
    Kurt-Dekker likes this.
  14. Richard_Ingalls

    Richard_Ingalls

    Joined:
    Dec 16, 2021
    Posts:
    85
    Yes, it is taking less time. I am doing other things as I am doing this, which I could not do if i just did it. I literally do not have time to do this, or the patience. The only reason I would ever do this by hand is if I didn't know that automation is theoretically possible. Automation is best at menial tasks. This certainly falls into that category.
    Not necessarily true. It is entirely possible, though at this point, admittedly, unlikely, that I am the first to run into a problem, likely from trying to do something that no one has ever thought of before, at least not in the way I am trying to do things. After all, someone had to be the first to run into these issues.
    I am aware of this. Refer to this statement from my original post: "If anyone knows of a free asset that can do this, or can give me the code to do this, or at least a code structure that makes it easy to do this, that would be great." The only reason I didn't only ask for pseudo code is because, who knows? Maybe there's someone who would be willing. Unlikely, but you never know.
    I keep mentioning my requirements because you keep seeming to forget them. If you aren't forgetting them, you aren't explaining how they are fulfilled. Or you seem to misunderstand what I meant, so I was attempting to rephrase to make it easier to understand. Thanks to all of you for what help you have given me, though. I think I can figure out the random shapes. But none of this helps me with trying to make pixel art. The one thing I have trouble with is how to turn whatever shapes they are into pixel art. I don't have the faintest idea of where to begin. You have all completely ignored that most crucial aspect, which is the only reason I posted on the forums at all.
    True, but nothing ever fits my project exactly (why should I expect it to? I don't do things exactly the same as anyone else, and don't have the same ideas as anyone else. If someone manages to create something that fits my project exactly without ever talking to me, or even knowing of my existence, I would be greatly shocked), and I generally try modifying things, which rarely turns out well for me.
    I tried. For several hours. I got nothing I could figure out. Then I tried to google to see if anyone else had solved this problem in a free solution. Then I came here, hoping someone here would have the knowledge to help me. I apologize if any of my responses have caused confusion.
     
  15. Nad_B

    Nad_B

    Joined:
    Aug 1, 2021
    Posts:
    270
    I posted pseudo-code, it should get you started. Then when you're stuck in a particular point, you can ask help on these forums and we'll be glad to help you!
     
  16. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,638
    The point of my answers was to circumvent the need to generate sprites, which you seem laser focused on despite being probably quite difficult.

    Because, you know, sometimes you don't need to solve a problem but circumvent it. Or just come up with something that looks good enough as a stand in to the average person.

    So I would just make some pixel art to be used in a sprite shape profile, and splatter them on the screen. Then they can all easily have polygon colliders to work alongside the 2d physics engine.
    upload_2023-10-8_9-23-26.png

    Looks good to me.
     
  17. Richard_Ingalls

    Richard_Ingalls

    Joined:
    Dec 16, 2021
    Posts:
    85
    Kurt-Dekker and Nad_B have both given be solutions to generate shapes. And what you have looks nice, yes, but it doesn't look like pixel art. Also, you aren't very clear on how I would go about doing things. It's probably just me having trouble seeing through my preconceived notions/me going through my weird thought process, but your answers are considerably less helpful to me than the answers of the other two.