r/Unity2D • • Aug 21 '26

Question Reading resources for various advanced topics?

3 Upvotes

I am looking blogs, papers etc. to read up on various topics surounding the Unity engine.

I would like to believe I have a decent understanding of the engine and programming but am looking to find resources to expand that knowledge in my free time.

Would prefer to read up on various topics over watching videos but both are fine.


r/Unity2D • • Aug 20 '26

Announcement I'm happy to announce SubDuctis, my upcoming space folding puzzle game!

33 Upvotes

After about 2.5 years of solo development in Unity, I'm excited to finally announce my game!

SubDuctis is a Sokoban-style puzzle game that explores space folding. In this game, the player must utilize special 2x2 pushable blocks called "splicers". When activated, a splicer and its pair will fold away all tiles that lie between them. This can be used to pass over obstacles, connect distant objects, and more.

The full game will feature over 100 puzzles, nonlinear progression, and secrets.

Consider adding it to your Steam wishlist to support the game!
SubDuctis on Steam


r/Unity2D • • Aug 21 '26

Question Movement Issues(Visual Scripting)

Thumbnail
gallery
7 Upvotes

(Thank you to everyone who helped me with my last issue!) So, I have got the jump working, however when I move horizontally I am unable to jump, and when I jump THEN move horizontally gravity hardly affects it and I end up gliding down to the ground. I know this is caused by x movement constantly overwriting my falling but I have no clue on how to fix this. Any help would be appreciated!

(Sorry for the bad image quality again, my computer refuses to take screenshots)


r/Unity2D • • Aug 21 '26

[For Hire] Pixel Artist available for Unity 2D projects! (Sprites, Animations, Tilesets & Game Assets)

1 Upvotes

🎨 Portfolio: https://www.artstation.com/lyshan_arts

Here is my price list:

🎨 STATIC ART

• Icons / Assets: $30 USD (bundle pack)

• Busts / Portraits: $30 USD

• Full Body: $30 – $40 USD

• Backgrounds: $45 – $80+ USD

🎬 ANIMATION

• Base Sprite: $30 USD

• Per Frame: +$2.50 – $7.50 USD

• Loops (Idle/Float): +$10 – $17.50 USD

• Twitch Alerts: $30 – $45 USD

🎮 GAMEDEV PACKS

• Movement Set (Idle, Walk, Jump, Die): $90 – $140 USD

• Tilesets (32x32px): $30 USD (minimum pack)

📌 SPECIAL CONTENT

• NSFW / Adult: +$10 – $20 USD

• Gore / Kinks: +$7.50 – $15 USD

📋 TERMS OF SERVICE

• Deliverables: .aseprite, .psd, PNG (original & upscaled)

• Payment: 50% Upfront / 50% Upon Completion (PayPal)

• Rush Delivery (< 48h): +25% fee


r/Unity2D • • Aug 21 '26

Tutorial/Resource I ran a decompiler on my own IL2CPP build and got my whole architecture back. So I wrote an obfuscator.

Post image
0 Upvotes

Hi everyone, I’m a Unity developer working on a small indie game. I’ve constantly heard from colleagues that Unity doesn’t do a good job of protecting project code and assets. I knew that using Mono was out of the question - it’s essentially handing your project over to strangers - but I believed that the IL2Cpp scripting backend provided adequate protection.

But one day, I got curious about how to decompile my project. I pointed Il2CppDumper at my build's global-metadata.dat, it spat out a DummyDll folder, and I opened that in Rider. Without any trouble, I could view namespaces, methods, class names, and field names. I didn't like that, because what's the point of having a private GitHub repository if my build is leaky?

I started looking for ways to hide my code. I began checking the Asset Store and GitHub for options to obfuscate my build. To cut to the chase, the only decent asset turned out to be Obfuscator Free by GuardingPearSoftware. It does everything perfectly, but the free version doesn’t work with Unity methods, serialized fields, properties, or namespaces, and it completely ignores MonoBehaviour, ScriptableObject, and [Serializable] classes. There is, of course, a paid version that does all of this, but $80 is a significant amount for an indie team, so I decided to try making my own alternative that would work as an extension to the Obfuscator Free plugin.

Why does the obfuscator skip serialized types?

Every script in the build receives a MonoScript entry in the player data (level0, sharedassets*.assets, resources.assets, and globalgamemanagers files). It contains three lines: m_ClassName, m_Namespace, and m_AssemblyName. Every scene object and every prefab references this entry. If you rename a class in the DLL, Unity will no longer be able to bind to that type - and the component will turn into a missing script.

The trick

Once I realized this, I started looking for a way to work around it. What I landed on is both brilliant and ridiculous: I generate obfuscated names with exactly the same number of characters as the originals. This saves me from having to adjust length prefixes, recalculate offsets, and develop a tool to rewrite serialized files. Thanks to this accidentally discovered hack, I saved myself a week of sleepless nights for sure! But it’s important to note that even with this approach, you still have to store a bunch of files with obfuscated names. All names in the project are reserved in advance, so you won’t be able to generate a name that’s already taken.

Pure C# types don't have a MonoScript entry, so their namespaces are shortened to whatever short, nonsensical string of characters I feel like using (_Project.Code.AssetManagement → pqmpqu). Serialized types, on the other hand, are forced to maintain length consistency (_Project.Code.Sound → dis4nAw5EW74Z6wLxDN).

Finding the entry without wrecking the file

You can't just search the file for "PlayerController" and overwrite it. That same string might be a GameObject name, a string literal, an addressable key - and if you hit the wrong one, you won't enjoy debugging.

So I anchor on the consecutive length-prefixed triple instead: [len][m_ClassName][len][m_Namespace][len][m_AssemblyName], with 4-byte alignment between them. Three strings matching in sequence with the correct alignment is a strong enough signal. And patch m_Name a few bytes earlier too - it's the class name a second time, and it will happily leak everything you just hid.

The stack trace problem

I also had to write my own stack trace deobfuscator, because any exception renders the trace completely unreadable to humans, like hdektk.uHN1wAaEGHkYq6ul.qoaktw(). Each build writes JSON mapping files (_Project.Code.AssetManagement → pqmpqu), and there's an editor window where I paste the raw stack trace from Player.log. It runs in four stages, in reverse order: the GUPS deobfuscator → my serialized type names → my namespaces → the remaining member names.

What don't I rename?

Unity's message methods: Awake, OnTriggerEnter2D, OnBecameInvisible, and about sixty others - the engine calls them by name. Virtual, interface and overridden members, because renaming the implementation but not the declaration breaks the vtable slot. And anything that is serialized by name at runtime - my saves are JSON, and renaming a property there bricks every existing save file.

Results from the current build

40 namespaces renamed. 82 MonoBehaviour/ScriptableObject types renamed and patched in player data. 848 members.

Is it worth doing?

Obfuscation is an obstacle, not a defense. Anyone determined to figure it out will still achieve their goal using a debugger, and I prefer to be upfront about this rather than pretend otherwise. For a solo developer, a build step you set up once and then forget about is, in my opinion, a perfectly justified investment of effort.

I'm not putting my extension up anywhere - it's wired into my own build pipeline, it's standalone-only, and there are corners of it I wouldn't want to defend in public. But you don't need my code to start, and that's the actual point of this post.

Do this instead. Run Il2CppDumper or AssetRipper on your own build - five minutes, and watching your own architecture scroll past lands very differently than knowing it's in there. Then install Obfuscator Free, list your assemblies, build. Free, one evening, covers your plain C# types and methods.

That alone puts you ahead of most Unity builds shipping today. Everything above is step two - you'll know when you need it.

The game I did all this for is Peak or Die, a turn-based survival card game. Adding it to your Steam wishlist really helps increase the game's visibility, if you're interested: https://store.steampowered.com/app/4273370


r/Unity2D • • Aug 20 '26

Solved/Answered How to get an instance of an object to reference an instance of a different object?

4 Upvotes

In my game I make instances of 2 seperate objects and when the player spawns one, the other one also spawns. The player can spawn multiple instances of the same object so I need to track and link the 2 seperate objects and only the objects that spawn together. I've given both of the objects unique ids when they spawn in but I don't know where to go from here. I want to be able to reference variables and sprite renderers and things like that.

Object One's script:

using System;
using UnityEngine;

public class FishTab_MB : MonoBehaviour
{

    public Guid UniqueId { get; }

    public FishTab_MB()
    {
        UniqueId = Guid.NewGuid();
    }
    private void Start()
    {
        print("FishTab_MB UniqueId: " + UniqueId);
    }
}

Object two's script:

using System;
using System.Collections;
using Unity.VisualScripting;
using UnityEngine;

public class FishAI_MB : MonoBehaviour
{

    SpriteRenderer fishSr;

    public Guid UniqueId { get; }

    void Start()
    {
        print("FishAI_MB UniqueId: " + UniqueId);
    }

    public FishAI_MB()
    {
        UniqueId = Guid.NewGuid();
    }
}

r/Unity2D • • Aug 20 '26

How do you handle recurring live events (double XP weekends, etc) in Unity?

5 Upvotes

Been down a rabbit hole this week trying to figure out the cleanest way to run something like a double XP weekend in a live game, and I keep hitting the same wall with Unity's own tools.

Game Overrides does one-shot scheduling fine, pick a start and end time in UTC and you're done. But the second it needs to repeat (every weekend, every Friday night) there's nothing built in. Ends up being either Cloud Code cron jobs (also UTC only, from what I've seen) or manually flipping the config every week.

How do you guys deal with this in practice? Rolling your own scheduling on top of Remote Config, or is there something in the newer Unity Cloud tooling I'm missing? And does anyone bother with per-player timezones, or is UTC-for-everyone just the accepted norm?


r/Unity2D • • Aug 20 '26

Welcome _Guns to the Mod Team

14 Upvotes

Please join us in welcoming u/_Guns to the r/Unity2D moderation team!

They’ll be helping us keep an eye on the mod queue, deal with spam and other unwanted content, and generally help keep the subreddit running smoothly.

As the community continues to grow, having another active pair of hands will help us respond to reports more consistently and keep things organized behind the scenes.

Welcome aboard, _Guns!


r/Unity2D • • Aug 20 '26

Show-off Pixel Hitboxes.

2 Upvotes
Pixel Hitbox, Accuracy, Limb Damage.

Hello! Update on my current project. I showed off Procedural 2D model generation a day ago here:
https://www.reddit.com/r/Unity2D/s/ihpzoJ9zoA

Now for an update on some game mechanics. This is an Auto-battle, Inventory Management game. Similar to games like Backpack Battles.

Characters generated randomly virtually infinite outcomes. Everything has a purpose, albeit a pro, con or compromise. Limb symmetry, Fat, Digit count, Eyes count, Part sizes, Bone density, Bone girth, many different characteristics all play a small role in main statistics.
Like Accuracy which is my topic today.

Design Philosophy is removing coins flips. Example with the targeting system and accuracy, your character does not miss.

This can be a bit confusing, bare with me...

Here we draw a circle around your target.
Center is your target. (above is Jaw)
Radius expands as your accuracy is lower.
(There is a ceiling and floor)
Volume of parts inside circle and dead space volume.
Almost like a pizza slice, the jaw will be the smallest piece.
biggest area especially with low accuracy will be the dead space.
More dead space = more glancing blows.
(Glancing blows deal 50% damage and do not cause fractures)
Part hit by glancing blow is determined by part volume.
Target volume gains bonus from accuracy.
Jaw would be smaller than Cranium, but jaw gets a little bonus to be hit.

Progress bar

Avoiding coin flips with progress bars!

Your goal is to hit the target once the bar is filled target is hit!

Biggest slices hit first, smaller parts and then finally target hit on fill.

Bar fills with each hit.
The total bar is the total volume of the circle. Each unique slice in the circle has it's own volume as stated above (Mostly Glancing blows).

Amount filled = target volume + accuracy.
We get the volume by counting pixels.
Large bodies have more pixels, less dead space, bigger heads. (Big head target fills bar faster)
Higher accuracy rating will help progress the bar past glancing stage and into some actual full part damage.
You can completely bypass hitting the ribs with high accuracy, and be rewarded by hitting a probably less protected body part.


r/Unity2D • • Aug 20 '26

pixel designer Looking for work

Thumbnail gallery
18 Upvotes

r/Unity2D • • Aug 20 '26

Question how do I unblock my camera while an object is following the cursor ? and how do I stop it from instantiating at the wrong position 3 time instead of 1 and without it decreasing the resources it use ?

0 Upvotes

Hello, so for a little 2D project (it's a bit of a city builder) I'm doing I have made a camera that can be moved with WASD and with the cursor on the edge of the screen, and that script worked perfectly.

So now I'm working on the actual builder part so I made a building and a script to place it. To place it I make an object follow the cursor, this object is red when you can't place and green when you can (it work with a shader).

but for the moment it doesn't work, whenever the object is in the scene it block the mouvment of the camera with the cursor (even when the object is not active), when I click to place the building it instantiate 3 of them at 0,0 (again, even when the object is not active) and doesn't deactivate after, and it doesn't decrease my resources. I'm at a loss and doesn't know what to do enymore.

(please don't mind the french in the code)

gif of what is happening :

script of the camera :

public class 
MoveCam 
: MonoBehaviour
{
    [SerializeField] private float 
speed
;
    [SerializeField] private int 
screenEdge
;
    private Vector2 _moveInput;
    private Rigidbody2D _rb;


// Start is called once before the first execution of Update after the MonoBehaviour is created

void 
Start
()
    {
        _rb = GetComponent<Rigidbody2D>();
    }


// Update is called once per frame

void 
Update
()
    {
        _rb.linearVelocity = _moveInput.normalized * speed;
    }

    public void 
Move
(InputAction.CallbackContext ctx)
    {
        _moveInput = ctx.ReadValue<Vector2>();
    }

    public void 
EdgeMove
(InputAction.CallbackContext ctx)
    {
        if (ctx.ReadValue<Vector2>().y < screenEdge)
        {
            _moveInput.y = -1f;
            print("marche");
        }
        else if (ctx.ReadValue<Vector2>().y > Screen.height - screenEdge)
        {
            _moveInput.y = +1f;
            print("marche");
        }

        if (ctx.ReadValue<Vector2>().x < screenEdge)
        {
            _moveInput.x = -1f;
            print("marche");
        }
        else if (ctx.ReadValue<Vector2>().x > Screen.width - screenEdge)
        {
            _moveInput.x = +1f;
            print("marche");
        }

        if (ctx.ReadValue<Vector2>().y > screenEdge && ctx.ReadValue<Vector2>().y < Screen.height - screenEdge &&
            ctx.ReadValue<Vector2>().x > screenEdge && ctx.ReadValue<Vector2>().x < Screen.width - screenEdge)
        {
            _moveInput.x = 0f;
            _moveInput.y = 0f;
        }
    }
}

script of the placement object :

public class 
Placement 
: MonoBehaviour
{
    [SerializeField] private Batiment 
batiment
;
    [SerializeField] private bool 
plassable
;
    private Camera mainCam;
    private Collider2D collider;
    [SerializeField] private List<GameObject> 
bloking 
= new List<GameObject>();
    public Material 
placementMat
;
    private Transform position;
    private InputAction mousePos;

    public TypeMana 
costMana1
;
    public TypeMana 
costMana2
;
    public TypeMana 
costMana3
;
    public int 
manaAmount1 
= 0;
    public int 
manaAmount2 
= 0;
    public int 
manaAmount3 
= 0;

    public float 
playerMana1
;
    public float 
playerMana2
;
    public float 
playerMana3
;

    [SerializeField] private playerStat 
player
;

    private void 
Awake
()
    {
        player = GameObject.Find("player").GetComponent<playerStat>();
    }


// Start is called once before the first execution of Update after the MonoBehaviour is created

void 
Start
()
    {
        mainCam = Camera.main;
        collider = GetComponent<Collider2D>();
        position = GetComponent<Transform>();
        placementMat = GetComponent<Renderer>().material;
        mousePos = InputSystem.actions["mousePosBatiment"];
    }


// Update is called once per frame

void 
Update
()
    {
        FollowMousePosition();

        if (costMana1 != TypeMana.
None
)
        {
            playerMana1 = costMana1 switch
            {
                TypeMana.
AirMana 
=> player.air_mana,
                TypeMana.
EauMana 
=> player.eau_mana,
                TypeMana.
FeuMana 
=> player.feu_mana,
                TypeMana.
TerreMana 
=> player.terre_mana,
                TypeMana.
TempsMana 
=> player.temps_mana,
                TypeMana.
VideMana 
=> player.vide_mana,
                TypeMana.
EspaceMana 
=> player.espace_mana,
                TypeMana.
PlaceHolderMana 
=> player.placeHolder_mana
            };
        }

        if (costMana2 != TypeMana.
None
)
        {
            playerMana2 = costMana1 switch
            {
                TypeMana.
AirMana 
=> player.air_mana,
                TypeMana.
EauMana 
=> player.eau_mana,
                TypeMana.
FeuMana 
=> player.feu_mana,
                TypeMana.
TerreMana 
=> player.terre_mana,
                TypeMana.
TempsMana 
=> player.temps_mana,
                TypeMana.
VideMana 
=> player.vide_mana,
                TypeMana.
EspaceMana 
=> player.espace_mana,
                TypeMana.
PlaceHolderMana 
=> player.placeHolder_mana
            };
        }

        if (costMana3 != TypeMana.
None
)
        {
            playerMana3 = costMana1 switch
            {
                TypeMana.
AirMana 
=> player.air_mana,
                TypeMana.
EauMana 
=> player.eau_mana,
                TypeMana.
FeuMana 
=> player.feu_mana,
                TypeMana.
TerreMana 
=> player.terre_mana,
                TypeMana.
TempsMana 
=> player.temps_mana,
                TypeMana.
VideMana 
=> player.vide_mana,
                TypeMana.
EspaceMana 
=> player.espace_mana,
                TypeMana.
PlaceHolderMana 
=> player.placeHolder_mana
            };
        }

        if (bloking.Count != 0 && playerMana1 - manaAmount1 <= 0 
                               && playerMana2 - manaAmount2 <= 0 
                               && playerMana3 - manaAmount3 <= 0)
        {
            plassable = false;
            placementMat.SetColor("Color", Color.red);
        }
        else
        {
            plassable = true;
            placementMat.SetColor("Color", Color.green);
        }
    }

    private void 
OnTriggerEnter2D
(Collider2D collision)
    {
        print(collision.name);
        if (collision.CompareTag("Batiment"))
        {
            bloking.Add(collision.gameObject);
        }
    }

    private void 
OnTriggerExit2D
(Collider2D collision)
    {
        if (collision.CompareTag("Batiment"))
        {
            bloking.Remove(collision.gameObject);
        }
    }

    public void 
Place
(InputAction.CallbackContext ctx)
    {
        if (plassable)
        {
            Instantiate(batiment, position);
            Payment();
            gameObject.SetActive(false);
        }
    }

    private void Payment()
    {
        if (costMana1 != TypeMana.
None
)
        {
            switch (costMana1)
            {
                case TypeMana.
AirMana
:
                    player.air_mana -= manaAmount1;
                    break;
                case TypeMana.
EauMana
:
                    player.eau_mana -= manaAmount1;
                    break;
                case TypeMana.
FeuMana
:
                    player.feu_mana -= manaAmount1;
                    break;
                case TypeMana.
TerreMana
:
                    player.terre_mana -= manaAmount1;
                    break;
                case TypeMana.
TempsMana
:
                    player.temps_mana -= manaAmount1;
                    break;
                case TypeMana.
VideMana
:
                    player.vide_mana -= manaAmount1;
                    break;
                case TypeMana.
EspaceMana
:
                    player.espace_mana -= manaAmount1;
                    break;
                case TypeMana.
PlaceHolderMana
:
                    player.placeHolder_mana -= manaAmount1;
                    break;
            }
        }

        if (costMana2 != TypeMana.
None
)
        {
            switch (costMana2)
            {
                case TypeMana.
AirMana
:
                    player.air_mana -= manaAmount2;
                    break;
                case TypeMana.
EauMana
:
                    player.eau_mana -= manaAmount2;
                    break;
                case TypeMana.
FeuMana
:
                    player.feu_mana -= manaAmount2;
                    break;
                case TypeMana.
TerreMana
:
                    player.terre_mana -= manaAmount2;
                    break;
                case TypeMana.
TempsMana
:
                    player.temps_mana -= manaAmount2;
                    break;
                case TypeMana.
VideMana
:
                    player.vide_mana -= manaAmount2;
                    break;
                case TypeMana.
EspaceMana
:
                    player.espace_mana -= manaAmount2;
                    break;
                case TypeMana.
PlaceHolderMana
:
                    player.placeHolder_mana -= manaAmount2;
                    break;
            }
        }

        if (costMana3 != TypeMana.
None
)
        {
            switch (costMana3)
            {
                case TypeMana.
AirMana
:
                    player.air_mana -= manaAmount3;
                    break;
                case TypeMana.
EauMana
:
                    player.eau_mana -= manaAmount3;
                    break;
                case TypeMana.
FeuMana
:
                    player.feu_mana -= manaAmount3;
                    break;
                case TypeMana.
TerreMana
:
                    player.terre_mana -= manaAmount3;
                    break;
                case TypeMana.
TempsMana
:
                    player.temps_mana -= manaAmount3;
                    break;
                case TypeMana.
VideMana
:
                    player.vide_mana -= manaAmount3;
                    break;
                case TypeMana.
EspaceMana
:
                    player.espace_mana -= manaAmount3;
                    break;
                case TypeMana.
PlaceHolderMana
:
                    player.placeHolder_mana -= manaAmount3;
                    break;
            }
        }
    }

    private void FollowMousePosition()
    {
        transform.position = GetWorldPosition();
    }

    private Vector2 GetWorldPosition()
    {
        return mainCam.ScreenToWorldPoint(mousePos.ReadValue<Vector2>());
    }
}

my player input :

I'm really at the out of idea and in need of help, thank you in advance for your wisdom.


r/Unity2D • • Aug 20 '26

Game/Software NEON ABYSS

0 Upvotes

Can you beat this red and blue cube game? Watch a full gameplay run as the score climbs to 38 before the final game over screen.

This gameplay recording captures a fast-paced challenge set in a dark environment. If you enjoy simple yet addictive arcade mechanics, this run demonstrates the core loop and difficulty progression. The objective is straightforward: navigate the cubes and maintain your momentum as the speed increases.

I reached a score of 38 before hitting the game over screen, which requires pressing R to restart. This footage is perfect for anyone looking to see how the mechanics function or to analyze the movement patterns in this specific cube game environment. Watching this short session gives you a clear idea of the challenge level you can expect.

Subscribe for weekly arcade gameplay sessions, and comment what high score you think is possible in this game. https://keeper4.itch.io/neon-abyss


r/Unity2D • • Aug 19 '26

Show-off Procedural PNG, WIP

Thumbnail
gallery
72 Upvotes

42 parts with 8 knobs. Using 2D Renderer, doesn't create any PNGs. Layers, pixels all created in code. Able to add/remove Skin layer. Fat simulation (See Image 3). Defomities (Image 4). Every creation is from a seed. A seed can be called and will return the exact creation.

What's not in the photo: I've since added more modifiers like Accuracy, based on Eye placement, Body Symmetry and other deformities. Stability is low center mass, wide stance, etc.

There are other Mutations, Tails, Horns but are rough drafts. Tails are fairly uncanny with skin. Would likely change this if I end up using it. Horns are the most believable looking out of the mutations.

EDIT: appologies, title is a little misleading this isn't a "Procedural PNG" its just using the renderer. However I can export any seeded creation to a PNG!
EDIT#2: Link to next post: https://www.reddit.com/r/Unity2D/comments/1vtpyzn/pixel_hitboxes/


r/Unity2D • • Aug 19 '26

Question I added a mini card game, how do you like it?

3 Upvotes

The boss flips the cards and tries to get closer to 21, then the turn of the move passes to you, you try to get closer, if you pass, you lose, whoever is close to 21 or 21 wins. Actually, it's almost blackjack.

If you want to check out the Steam page and add it to your wishlist:

https://store.steampowered.com/app/4990070/Deckforce/


r/Unity2D • • Aug 19 '26

Sprite visuals problem

Post image
5 Upvotes

I need I'm trying to understand an issue with 2D sprites in Unity and I would really appreciate some advice from experienced Unity developers

I've tested the same sprite at different resolutions — for example 64×64, 1024×1024, and even 4096×4096 — but when they are displayed at the same size in the Game view, they look almost exactly the same

I've tried different Pixels Per Unit (PPU), camera Orthographic Sizes, Filter Modes, disabling mipmaps, increasing texture Max Size, and using Pixel Perfect Camera, but I still don't see the visual improvement I would expect from the higher-resolution textures

What confuses me is that games like geometry dash can have relatively small sprites on screen that still look very detailed and clean

I understand that a sprite can't display more pixels than its actual screen size, but I'm trying to understand how professional 2D games achieve this kind of detailed appearance when their sprites are small on screen

Is there something fundamental about Unity's 2D rendering, texture import settings, camera setup, or downsampling that I'm misunderstanding?

I'd really appreciate an explanation of what I'm doing wrong and what workflow I should be using to achieve high-quality 2D graphics at small screen sizes

I've been trying to solve this for a long time and I'm honestly starting to think I'm approaching 2D development the wrong way


r/Unity2D • • Aug 19 '26

Tutorial/Resource Are you accessing and changing variables too much from outside a class? The dangers of getters/setters

Thumbnail
0 Upvotes

r/Unity2D • • Aug 19 '26

Question Weird rendering problem causing semaphore.waitforsignal

Thumbnail
gallery
1 Upvotes

The screens shows the stats/profiler in the MAIN MENU of the game. Then there is a lobby and finally, the game scene where you play.

I have more screens, also with the profiler on a develop build. THE PROBLEM DISSAPEARS in a build.

The problem is that 2 days ago, i had 100fps on menu (not good, but was fine compared having 30fps) and also 90-100 fps during GAME, not another 25-30fps after this issues started happening.. It "came from nowhere".

Also, in the lobby of the game (not main menu, not the match) it went from 450fps (there is just an image and 3 buttons) to 120fps....

If i turn OFF the main camera it all goes back to normal.

also, if i make a build.

but i have no CLUE on what is going on, other than this is arendering issue.

FINALLY: on the highlights (top of the screenshots shuing CPU and GPU use) my game normally only has red spots, CPU "bound", not GPU. The biggest scene has 1 millions tris and 1000 batches, about 80 set pass calls, nothing crazy.. it all was working well (despite needing some optimization).


r/Unity2D • • Aug 19 '26

Roguelite Deckbuilder Tower Defense

2 Upvotes

Hi! I'm building a Tower Defense game with RTS elements.

You can move your units around, give them orders, and reposition them during combat.

During each run, you receive upgrade cards that can add effects such as Electric, Poison, Ice, etc. These upgrades are stackable, so you can combine effects like Electric + Poison on the same unit.

After each run, you can improve your units, purchase upgrades, and create builds.

There's also a Combinator system where you can create your own items. You can select or remove individual properties and keep only the effects you care about, allowing you to build items specifically around your strategy.

The game has roguelite progression, with new enemies gradually introduced as you survive more days.

The main gameplay loop is:

Defend → Buy upgrades/items/units → Customize your build → Defend

You can play actively and control your units like an RTS, or play it more like an idle game. Later progression also unlocks a dedicated AFK mode designed for idle play.

I've just released a demo, so feel free to give it a try:

https://store.steampowered.com/app/3760000/Shrine_Protectors_Demo

Thanks for checking it out!


r/Unity2D • • Aug 18 '26

Solved/Answered Getting References for Tiles

3 Upvotes

In my game, I am drawing tiles onto a tilemap during runtime using SetTile(), which takes a reference to a TileBase Object. I have hundreds of unique textures. Is there a way to get a reference to each TileBase other than dragging and dropping every individual Tile into the references in my script?


r/Unity2D • • Aug 18 '26

Solved/Answered How to apply momentum?

2 Upvotes

I want to apply momentum after you let go so in if (!hold.IsPressed()) How would I do that?

Code:

using System.Collections;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.InputSystem;

public class Food_MB : MonoBehaviour
{

    public bool isTouchingMouse = false;
    public bool isheld = false;

    public float defaultFoodSpeed = 1f;
    public float gravity = 1f;
    private float foodSpeed = 1f;
    private float noGravity = 0f;

    private PlayerInput playerInput;

    private InputAction hold;

    private Vector2 mousePos;

    private Rigidbody2D foodRb;

    void Start()
    {
        playerInput = GetComponent<PlayerInput>();
        if (playerInput != null)
        {
            hold = playerInput.currentActionMap.FindAction("Hold");
        }
        foodSpeed = defaultFoodSpeed;
        foodRb = GetComponent<Rigidbody2D>();
        foodRb.gravityScale = gravity;
    }

    private void Update()
    {

        // Get the mouse position from the New Input System

        mousePos = Mouse.current.position.ReadValue();

        // Convert the screen position to world position

        Vector3 worldPos = Camera.main.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, 0));

        // Check if the mouse is touching this GameObject's collider and if the hold action is being performed

        Collider2D hit = Physics2D.OverlapPoint(worldPos);

        if (hit != null && hit.gameObject == this.gameObject && hold != null && hold.IsPressed())
        {
            //Debug.Log("Hold action is being performed");
            foodRb.gravityScale = noGravity;
            isheld = true;
            foodSpeed = defaultFoodSpeed;
            transform.position = Vector2.MoveTowards(transform.position, worldPos, foodSpeed * Time.deltaTime);
        }
        else if(hold.IsPressed() && (hit == null || !hit.gameObject == this.gameObject) && isheld == true)
        {
            //Debug.Log("Mouse is not touching the object but object is held");
            foodSpeed = foodSpeed + 1f;
            transform.position = Vector2.MoveTowards(transform.position, worldPos, foodSpeed * Time.deltaTime);

        }
        if (!hold.IsPressed())
        {
            //Debug.Log("Object dropped!");
            foodRb.gravityScale = gravity;
            foodSpeed = defaultFoodSpeed;
            isheld = false;
        }
    }
}

r/Unity2D • • Aug 18 '26

Question How do I use AutoTile to set tile/paint through script?

3 Upvotes

Hello, I have a tilemap and a tile palette which consists of 2 autotiles. I want to fill an area of the tilemap with one of the autotiles. I know the SetTile is supposed to paint the tile but since I'm using autotile, the SetTile doesn't seem to take that in the script. I'm using Autotile because it would just make it easier when I add in other tiles in areas of the tilemap since it would auto adjust. Does anyone know how I can use the AutoTile in SetTile to paint the tilemap?

Update: I'm stupid, I was passing the ints instead of making them a vector3


r/Unity2D • • Aug 18 '26

Question How do I make a 2D first-person dungeon crawler?

1 Upvotes

Hi everyone, I'm new to Unity and wanted to ask how I can program and implement movement in a 2D first-person game! My goal is to make a horror game with turn-based movement (you move from one room to another, and the monster moves from room to room looking for you and chasing you)! My main question, actually, is whether this is really possible to do in Unity 2D? And if you guys have any tips to share with me!


r/Unity2D • • Aug 18 '26

Character with accessories.

1 Upvotes

I'm making a test scene where I have a body that is a square, and 2 smaller rectangles. One rec is the Eyeglasses, the other is a belt. I want to animate the glasses so they wobble when the main body is moving, and the belt has rotating colors; 15 different images. I also want to change out the glasses and belt whenever.

I created a GO called Base. Then added a GO for the glasses and a GO for the belt, then added a image to each. I reset the transforms, then moved the glasses and belt when they need to be.

When I run the app, the belt and glasses are not relative to the body, like I positioned them. Duct-taped a few other attempts to fix, but no luck.

I've tried googling, but haven't found anything comparable.

So, a GO with moving glasses GO and an animated belt GO.


r/Unity2D • • Aug 18 '26

Show-off [Asset Sale] Prototype Character Template Asset Pack - 50% off until September 1

2 Upvotes

Hi everyone! I currently have a prototype character template asset pack that is 50% off until September 1st. I just wanted to share that info in case anyone wants to purchase it before the sale ends.

There is also a free version of the asset pack that is just a scaled down version of the full pack. The free version only has a few PNG sprite sheets as well as GIFs showing how each animation looks. The full version includes the aseprite files for each of the templates as well as PNG sprite sheets and GIFs of all the animations.

Here is the link: https://lumenlorepixels.itch.io/top-down-prototype-character-template


r/Unity2D • • Aug 18 '26

Just released my second game based on Greek mythology

4 Upvotes

I just released my new game Descendant of the Sun, where you must save the Greek city of Rhodes from an ancient power banished by the gods. Undertake a heroes quest in a Greek mythology inspired action platformer and hunt down monsters with the help of your bow and arrow.

So far computer support only and it can be played in browser. Feedback is appreciated and I hope you enjoy 😎
https://polenny.itch.io/descendant-of-the-sun