惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Securelist
C
Cybersecurity and Infrastructure Security Agency CISA
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security Affairs
Hacker News: Ask HN
Hacker News: Ask HN
L
Lohrmann on Cybersecurity
PCI Perspectives
PCI Perspectives
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
Recent Commits to openclaw:main
Recent Commits to openclaw:main
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
MyScale Blog
MyScale Blog
月光博客
月光博客
W
WeLiveSecurity
T
Threat Research - Cisco Blogs
Martin Fowler
Martin Fowler
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recorded Future
Recorded Future
The GitHub Blog
The GitHub Blog
Webroot Blog
Webroot Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
TaoSecurity Blog
TaoSecurity Blog
P
Proofpoint News Feed
Google DeepMind News
Google DeepMind News
F
Full Disclosure
U
Unit 42
Jina AI
Jina AI
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
L
LINUX DO - 最新话题
宝玉的分享
宝玉的分享
大猫的无限游戏
大猫的无限游戏
The Hacker News
The Hacker News
The Last Watchdog
The Last Watchdog
T
Troy Hunt's Blog
腾讯CDC
T
Threatpost
H
Hacker News: Front Page
P
Palo Alto Networks Blog
博客园 - 聂微东
Last Week in AI
Last Week in AI
有赞技术团队
有赞技术团队
Help Net Security
Help Net Security
L
LINUX DO - 热门话题
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Spread Privacy
Spread Privacy

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Unity vs Unreal: 5 Things I Had to Relearn the Hard Way
Game Dev Not · 2026-05-22 · via DEV Community

The first time I opened Unreal after years of living in Unity, I sat there for a full ten minutes trying to figure out where the play button was. Not because I couldn't see it. Because I didn't trust that pressing it would do what I expected. Every muscle memory I'd built up — drag a script onto a GameObject, hit play, see the thing wiggle — was suddenly worthless. The viewport looked similar enough to lull me into a false sense of familiarity, and then five seconds later I was fighting the editor over what "save" even means.

Going the other direction is just as bad. Unreal devs who jump into Unity often spend their first week asking why the engine keeps eating their references on hot reload, or why the Inspector won't show their perfectly reasonable struct.

I've shipped work in both engines at this point, and the honest truth is that the syntax barrier (C# vs C++) is the easy part. What actually slows you down is the dozens of small mental model mismatches that nobody warns you about until you've already lost a weekend to them. The engines look like they solve the same problems, so you assume the shape of the solution is the same. It isn't.

Here are five things our studio had to genuinely rewire our brains around. Not engine trivia — the stuff that quietly costs you days if you don't catch it early.

1. Garbage Collection Lives in Different Universes

Unity gives you C# and the .NET GC. Unreal gives you C++ and a custom mark-and-sweep GC that only knows about objects you've explicitly told it about. These sound similar. They are not.

In Unity, you write a class, you new it up, and the GC takes care of it whenever it feels like. The classic gotcha is performance (allocations in Update = GC spikes), but the correctness model is straightforward. Everything's an object, everything's tracked.

In Unreal, the GC only tracks UObject subclasses, and only through references it can see — meaning references marked with UPROPERTY(). If you store a UObject* as a raw pointer without that macro, the GC has no idea you care about it, and your pointer becomes a dangling reference the next sweep. The object literally gets collected out from under you.

UCLASS()
class AEnemy : public AActor {
    GENERATED_BODY()

    // Safe: GC knows you reference this
    UPROPERTY()
    UWeapon* EquippedWeapon;

    // Time bomb: GC will happily delete this
    UWeapon* SecretWeapon;
};

Enter fullscreen mode Exit fullscreen mode

The mental rewire: in Unity, the GC is a performance concern. In Unreal, the GC is a correctness concern. You don't fight it for frame time, you fight it for object lifetime. Once that clicked, half of my "why is my pointer null" bugs disappeared.

The flip side: Unity devs jumping to Unreal often reach for TWeakObjectPtr reflexively because they're scared of the GC. Most of the time you just want a UPROPERTY()-marked pointer — it keeps the object alive and tracked. Save TWeakObjectPtr for the case it's actually designed for: you want to reference something without preventing its destruction (a UI panel watching a target actor that might die first).

2. Tick Is Not Update (And Lifecycle Is Not Awake)

On paper, MonoBehaviour.Update() and AActor::Tick() look like the same idea. Per-frame callback, runs every frame, do your thing. In practice the lifecycle and scope rules around them are different enough that you can't just port habits across.

Unity's MonoBehaviour has a fairly chatty lifecycle (Awake, OnEnable, Start, Update, LateUpdate, OnDisable, OnDestroy) and most of those fire reliably in the editor too. You can lean on Start for cheap initialization and forget about it.

Unreal splits actor lifetime across PostInitializeComponents, BeginPlay, Tick, EndPlay, with components having their own OnRegister / InitializeComponent flow. BeginPlay only fires when the game actually starts, which catches a lot of Unity converts off guard the first time they try to do initialization in the constructor and wonder why nothing's wired up yet.

AEnemy::AEnemy() {
    // Constructor runs for the CDO at engine init, and again for every instance.
    // In both cases the world isn't valid — no gameplay state, no other actors.
    // Defaults only; gameplay setup goes in BeginPlay.
    PrimaryActorTick.bCanEverTick = true;
}

void AEnemy::BeginPlay() {
    Super::BeginPlay();
    // Now the world exists. Do gameplay setup here.
}

Enter fullscreen mode Exit fullscreen mode

And then there's the other direction, which bites just as hard. Unreal devs coming into Unity expect a staged lifecycle and instead get a flat one with a bunch of quietly-different rules. Awake runs early, sure, but it runs before the scene's other objects are guaranteed to be wired up — so anything that reaches across to a sibling MonoBehaviour belongs in Start, not Awake. Start itself doesn't fire when you Instantiate the object; it waits for the first frame the object is active. OnEnable and OnDisable fire every time you toggle the GameObject, not just at creation — which is great for pooling and a trap if you treated them as one-shot setup hooks. And the C++ instinct to "just put real init in the constructor" has to be unlearned outright: Unity reserves the right to construct MonoBehaviours for serialization purposes when no scene exists, so gameplay code in the constructor is at best ignored, at worst crashes the editor on domain reload. On top of all that, Update runs at a variable rate; physics-coupled logic belongs in FixedUpdate, and that distinction is one of those things you only learn after your character starts vibrating at high frame rates.

The rewire: in Unity, lifecycle is flat and most things fire on a single timeline. In Unreal, lifecycle is staged: constructor for defaults, BeginPlay for runtime, and Tick is opt-in (you have to enable it explicitly, which is honestly a feature, not a bug). Treat them as different shaped tools.

3. Reflection Is the Whole Engine

This is the one I underestimated the longest.

Unity uses [SerializeField], [Serializable], and [SerializeReference] to drive its inspector and YAML serializer. It feels lightweight — public fields serialize by default, private ones need a single attribute — but the rules quietly bite: polymorphic references need [SerializeReference], custom classes need [Serializable] to appear in the inspector at all, and IL2CPP will happily strip any type only reached via reflection unless you preserve it with a link.xml or [Preserve]. It's lower-ceremony than Unreal, but it's not free.

Unreal's UPROPERTY(), UFUNCTION(), and UCLASS() macros look like the same idea but they're load-bearing structural pillars. They feed the reflection system that powers serialization, the editor, Blueprint exposure, network replication, GC tracking (see #1), and the property system. A field without UPROPERTY is invisible to all of it. A function without UFUNCTION can't be called from Blueprint or RPCs. A class without UCLASS doesn't exist to the engine at all.

UCLASS(Blueprintable)
class AEnemy : public AActor {
    GENERATED_BODY()

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Combat")
    float Health = 100.f;

    UFUNCTION(BlueprintCallable, Category="Combat")
    void TakeHit(float Damage);
};

Enter fullscreen mode Exit fullscreen mode

Each meta specifier (EditAnywhere, BlueprintReadWrite, Category, Replicated, etc.) is a load-bearing instruction to a different subsystem. You'll find yourself reading the Unreal docs on property specifiers more than any other page.

The rewire: in Unity, attributes are sugar. In Unreal, macros are the API. When something doesn't show up in the editor, doesn't replicate, doesn't appear in Blueprint, or gets GC'd unexpectedly, 90% of the time it's because you forgot a specifier. Build the habit of writing the macro first, the field second.

4. Editor Extension Is a Different Sport

Both engines let you extend the editor. Both will let you build custom inspectors, tool windows, asset processors. But the shape of how you do it diverges so hard that your tooling knowledge basically doesn't carry over.

Unity editor scripting is mostly C# in an Editor/ folder, using UnityEditor APIs, EditorWindow, CustomEditor, and either IMGUI for quick stuff or UI Toolkit (UXML/USS) for anything you'd actually want to maintain. It's the same language as your gameplay code, which makes it cheap to start writing. Half our internal tools at the studio started as a 50-line EditorWindow someone wrote during lunch.

Unreal splits editor code into separate modules (you'll be editing .Build.cs files), and the UI is Slate, a declarative C++ DSL that looks like nothing else you've ever written. It's powerful, but the learning curve is real.

// Slate looks like this. Yes, really.
SNew(SVerticalBox)
+ SVerticalBox::Slot()
  .AutoHeight()
  [
      SNew(STextBlock)
      .Text(FText::FromString("Hello, tools"))
  ];

Enter fullscreen mode Exit fullscreen mode

You can avoid Slate for a while using Editor Utility Widgets (UMG in the editor) or Editor Utility Blueprints, which is honestly where I tell anyone starting out to live. Pure Slate is for when you need something that genuinely belongs in the editor chrome.

The rewire: in Unity, "I'll write a quick editor tool" is a fifteen-minute commitment. In Unreal, it's an afternoon if you go native, or fifteen minutes if you accept that Editor Utility Widgets are good enough for 80% of cases. Pick the right tier for the job. Don't try to write Slate for a button that just renames some assets.

5. The Asset Pipeline Has Opinions

The thing nobody tells you: your project structure isn't just organization. It's a contract with the build system.

Unity treats anything in Assets/ as fair game. You move things around freely, the .meta files keep references intact, AssetBundles are an opt-in deployment thing you set up when you need streaming or DLC. The pipeline is forgiving. Maybe too forgiving. Most Unity projects I've inherited had Assets/ folders that looked like a teenager's desktop.

Unreal's Content/ directory is a more structured place. Every asset is a .uasset with cooked variants, references are tracked by path, and moving things around outside the editor will absolutely break your references in ways that aren't always obvious until you try to package. The cook step at build time is a whole second pipeline you have to think about: what's referenced, what gets included, what gets stripped.

// Unity                  // Unreal
Assets/                   Content/
  Scripts/                  Blueprints/
  Prefabs/                  Maps/
  Scenes/                   Materials/
  Materials/                Characters/
  Resources/                ...
                          (Cooked output → Saved/Cooked/<Platform>/)

Enter fullscreen mode Exit fullscreen mode

Two specific traps worth flagging early:

  • Unity's Resources/ folder is convenient and almost always the wrong answer at scale. Anything in there ships in your build whether you reference it or not. For anything beyond a prototype, move to Addressables (or whichever streaming asset system your Unity version blesses — the recommendation has shifted more than once).
  • Unreal's hard-vs-soft references (UPROPERTY() of UObject* vs TSoftObjectPtr<>) determine what gets pulled into memory when. Get this wrong on a mid-size project and your initial map load time will quietly balloon.

The rewire: Unity's pipeline lets you defer thinking about deployment until late. Unreal's pipeline forces you to think about it early. Neither approach is wrong, but pretending you're in the other engine's model is how you ship a 4 GB build that should've been 800 MB.

Closing Thoughts

The pattern across all five of these: the engines look like they solve the same problems with slightly different syntax, and that's the trap. They actually have different philosophies about who owns what — the GC, the editor, the build, the lifecycle, the reflection system. Once you stop trying to translate Unity habits into Unreal (or vice versa) and start learning each engine's actual mental model, everything gets faster.

The other thing this taught me: every time I assumed two systems were "basically the same," I was about to lose a day. Now when I jump into something new, I make myself find the one thing that's structurally different from what I'm used to, before I touch any code. Saves a lot of grief.

If you've made the jump in either direction, I'd genuinely love to hear what tripped you up the worst. The five above are the ones that hit our studio hardest, but I'm sure there's a sixth waiting for the next person who switches engines. Probably something about input systems, knowing my luck.

This blog's where we plan to write down the small, unglamorous stuff we keep learning the hard way. No newsletter pitch — just more of these when we hit the next one.