Viking Village Won't Compile in Unity 6? Every Error, Explained and Fixed

Open Unity’s classic Viking Village URP demo in Unity 6 and you get a wall of red — and a sea of pink. The Asset Store reviews tell the story: the most recent ones are one-star reports like “Abandoned asset – will not work in Unity 6” and “Needs the RTHandle system, the one it comes with is obsolete and not a simple fix.”

They’re not wrong about the errors. They’re wrong that it’s not fixable. This post walks through every error the project throws on Unity 6000.5, what each one actually means, and the exact fix — first by hand, then the way we actually did it: letting a migration tool rewrite the files and compile-verify the result.

Unity 6 Console showing six errors in Viking Village: CS0619 RenderTargetHandle is obsolete, CS0115 override errors, and two DirectBDRF shader errors

And this is what the bay looks like before any fixes — the Boat Attack water shaders fail to compile, so every water surface falls back to Unity’s magenta error shader:

Viking Village scene view in Unity 6 with the entire bay rendering solid magenta because the water shaders fail to compile

The full damage report

A scan of the freshly-imported project surfaces five blockers (PerfLint groups them under Migration; your Console shows the same facts as loose errors):

PerfLint scan of Viking Village on Unity 6: five Critical findings — two failing shaders, one script that fails to compile, GetInstanceID and RenderTargetHandle deprecations

  1. RenderTargetHandle is obsolete (CS0619)WaterSystemFeature.cs, the custom render feature behind the water. Deprecated in Unity 2022.1, error-level in 2023.1+/Unity 6. The three CS0115 errors underneath it are collateral: once the type is gone, the pass’s overrides stop matching their base signatures.
  2. 'DirectBDRF': no matching 4 parameter function — both Water.shader and WaterTessellated.shader, via the shared WaterCommon.hlsl include. URP 12 renamed the misspelled DirectBDRF to DirectBRDF. One character swap, two dead shaders, all the magenta above.
  3. GetInstanceID is obsolete (CS0619)BuoyantObject.cs uses it as a lookup key for the buoyancy job system. Newer Unity 6 releases replace it with GetEntityId(), and there is no legal conversion from EntityId back to int, which makes this less trivial than a rename.

Fixing it by hand

If you’d rather do it manually, here’s the honest version of each fix.

RenderTargetHandle → RTHandle

This is the one the reviews call “not a simple fix” — and structurally, they’re right. It’s not a rename: allocation, release, and the pass callbacks all change.

  • Declarations: RenderTargetHandle m_Temp;RTHandle m_Temp;
  • Allocation moves into OnCameraSetup, via RenderingUtils.ReAllocateIfNeeded(ref m_Temp, desc, …) (newer URP renames it ReAllocateHandleIfNeeded).
  • m_Temp.Identifier() → pass the handle itself; cmd.GetTemporaryRT / ReleaseTemporaryRT → delete, release explicitly in Dispose() with m_Temp?.Release().
  • On Unity 6, check which pass shape your URP actually exposes: if OnCameraSetup/Execute are gone from ScriptableRenderPass, the pass logic must move into RecordRenderGraph (the Render Graph API) — a genuinely different structure.

DirectBDRF → DirectBRDF

Open WaterCommon.hlsl, line 274, and swap two characters. That’s the whole fix — if you know that’s the fix. The compiler error (no matching 4 parameter function) doesn’t mention the rename, which is why this one eats an afternoon of forum-searching.

GetInstanceID → don’t chase EntityId

BuoyantObject only uses the id as a unique key — it never needs the actual Unity object identity. Migrating the key to EntityId would ripple through two more files (the job system’s dictionaries and method signatures all take int). The minimal, behavior-identical fix is a static counter:

private static int _nextGuid;
// in OnEnable — was: _guid = gameObject.GetInstanceID();
_guid = ++_nextGuid;

Reserve the real GetEntityId() migration for code that genuinely needs object identity.

Fixing it in a few clicks

We built PerfLint’s Migration Assistant for exactly this shape of problem, so here’s the same project fixed with it. Each Critical finding carries an AI Migrate button. For the shaders, it targets the file the compiler error actually lives in — WaterCommon.hlsl, not the .shader shell — shows the whole-file diff, and summarizes in-line changes so a two-character rename can’t hide:

AI Migrate diff for the water shader: the in-line change summary highlights DirectBDRF renamed to DirectBRDF on line 274

The C# side works the same way — the whole file goes to the model along with the exact compiler error list, and the result only sticks if the project compiles afterwards (a failed rewrite rolls back automatically):

AI Migrate panel for BuoyantObject.cs: rewrites the file guided by its compiler errors, compile-verified with automatic rollback

A few Generate → review diff → Apply cycles later — one per broken file — the Critical list is empty. Fixing the shared WaterCommon.hlsl healed both water shaders in one pass; the BuoyantObject fix landed exactly as the static-counter version above:

PerfLint after the migration: zero Critical findings, health score climbed from 0 to 40

The village, back from the pink

Same bay as the magenta screenshot, after the shader fix — Gerstner waves, shoreline foam, mountain reflections and all:

The same Viking Village bay after the fix, water rendering correctly with reflections in the scene view

Viking Village in the game view after migration, sunset over the docks with the water system running

Two honest footnotes from the process:

  • After a shader is rewritten, the editor sometimes shows black water or missing ambient light until the scene reloads — that’s editor state (the water system’s C# feeds shader globals on scene load), not broken assets. PerfLint offers a one-click scene reload after a shader migration for exactly this.
  • A compile pass can’t judge visual correctness. Eyeball your scene after any migration, automated or manual. (Here, the water came back exactly as it should.)

The takeaway

“Abandoned asset – will not work in Unity 6” is really five small, well-understood API breaks stacked on top of each other. Every one of them is fixable in minutes once something tells you which file, which line, and what the modern replacement is — which is precisely the gap between a wall of red and a working project.

PerfLint’s scan (free) finds all of the above locally — nothing is uploaded. The one-click AI migrations are part of Pro. Try it on your own stuck upgrade →

Rule reference: MAT001 · SHDR004


← Back to all posts