UNPKG

com.wallstop-studios.unity-helpers

Version:

Treasure chest of Unity developer tools

931 lines 217 kB
<!doctype html><html lang=en class=no-js> <head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=description content="Production-ready Unity utilities: 10-15x faster PRNGs, O(log n) spatial queries, zero-allocation pooling, Odin-level inspector tooling, and data-driven effects."><meta name=author content="Wallstop Studios"><link href=https://wallstop.github.io/unity-helpers/features/serialization/serialization-types/ rel=canonical><link href=../serialization/ rel=prev><link href=../../utilities/math-and-extensions/ rel=next><link rel=icon href=../../../assets/images/favicon.png><meta name=generator content="mkdocs-1.6.1, mkdocs-material-9.7.3"><title>Serializable Types - Unity Helpers</title><link rel=stylesheet href=../../../assets/stylesheets/main.484c7ddc.min.css><link rel=stylesheet href=../../../assets/stylesheets/palette.ab4e12ef.min.css><style>:root{--md-admonition-icon--note:url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20448%20512%22%3E%3C%21--%21%20Font%20Awesome%20Free%207.1.0%20by%20%40fontawesome%20-%20https%3A//fontawesome.com%20License%20-%20https%3A//fontawesome.com/license/free%20%28Icons%3A%20CC%20BY%204.0%2C%20Fonts%3A%20SIL%20OFL%201.1%2C%20Code%3A%20MIT%20License%29%20Copyright%202025%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M64%20480c-35.3%200-64-28.7-64-64V96c0-35.3%2028.7-64%2064-64h320c35.3%200%2064%2028.7%2064%2064v213.5c0%2017-6.7%2033.3-18.7%2045.3L322.7%20461.3c-12%2012-28.3%2018.7-45.3%2018.7zm325.5-176H296c-13.3%200-24%2010.7-24%2024v93.5z%22/%3E%3C/svg%3E');--md-admonition-icon--abstract:url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20448%20512%22%3E%3C%21--%21%20Font%20Awesome%20Free%207.1.0%20by%20%40fontawesome%20-%20https%3A//fontawesome.com%20License%20-%20https%3A//fontawesome.com/license/free%20%28Icons%3A%20CC%20BY%204.0%2C%20Fonts%3A%20SIL%20OFL%201.1%2C%20Code%3A%20MIT%20License%29%20Copyright%202025%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M384%20512H96c-53%200-96-43-96-96V96C0%2043%2043%200%2096%200h304c26.5%200%2048%2021.5%2048%2048v288c0%2020.9-13.4%2038.7-32%2045.3V448c17.7%200%2032%2014.3%2032%2032s-14.3%2032-32%2032zM96%20384c-17.7%200-32%2014.3-32%2032s14.3%2032%2032%2032h256v-64zm32-232c0%2013.3%2010.7%2024%2024%2024h176c13.3%200%2024-10.7%2024-24s-10.7-24-24-24H152c-13.3%200-24%2010.7-24%2024m24%2072c-13.3%200-24%2010.7-24%2024s10.7%2024%2024%2024h176c13.3%200%2024-10.7%2024-24s-10.7-24-24-24z%22/%3E%3C/svg%3E');--md-admonition-icon--info:url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20512%20512%22%3E%3C%21--%21%20Font%20Awesome%20Free%207.1.0%20by%20%40fontawesome%20-%20https%3A//fontawesome.com%20License%20-%20https%3A//fontawesome.com/license/free%20%28Icons%3A%20CC%20BY%204.0%2C%20Fonts%3A%20SIL%20OFL%201.1%2C%20Code%3A%20MIT%20License%29%20Copyright%202025%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M256%20512a256%20256%200%201%200%200-512%20256%20256%200%201%200%200%20512m-32-352a32%2032%200%201%201%2064%200%2032%2032%200%201%201-64%200m-8%2064h48c13.3%200%2024%2010.7%2024%2024v88h8c13.3%200%2024%2010.7%2024%2024s-10.7%2024-24%2024h-80c-13.3%200-24-10.7-24-24s10.7-24%2024-24h24v-64h-24c-13.3%200-24-10.7-24-24s10.7-24%2024-24%22/%3E%3C/svg%3E');--md-admonition-icon--tip:url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20384%20512%22%3E%3C%21--%21%20Font%20Awesome%20Free%207.1.0%20by%20%40fontawesome%20-%20https%3A//fontawesome.com%20License%20-%20https%3A//fontawesome.com/license/free%20%28Icons%3A%20CC%20BY%204.0%2C%20Fonts%3A%20SIL%20OFL%201.1%2C%20Code%3A%20MIT%20License%29%20Copyright%202025%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M292.9%20384c7.3-22.3%2021.9-42.5%2038.4-59.9C364%20289.7%20384%20243.2%20384%20192%20384%2086%20298%200%20192%200S0%2086%200%20192c0%2051.2%2020%2097.7%2052.7%20132.1%2016.5%2017.4%2031.2%2037.6%2038.4%2059.9h201.7zm-4.9%2048H96v16c0%2044.2%2035.8%2080%2080%2080h32c44.2%200%2080-35.8%2080-80zM184%20112c-39.8%200-72%2032.2-72%2072%200%2013.3-10.7%2024-24%2024s-24-10.7-24-24c0-66.3%2053.7-120%20120-120%2013.3%200%2024%2010.7%2024%2024s-10.7%2024-24%2024%22/%3E%3C/svg%3E');--md-admonition-icon--success:url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20448%20512%22%3E%3C%21--%21%20Font%20Awesome%20Free%207.1.0%20by%20%40fontawesome%20-%20https%3A//fontawesome.com%20License%20-%20https%3A//fontawesome.com/license/free%20%28Icons%3A%20CC%20BY%204.0%2C%20Fonts%3A%20SIL%20OFL%201.1%2C%20Code%3A%20MIT%20License%29%20Copyright%202025%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M434.8%2070.1c14.3%2010.4%2017.5%2030.4%207.1%2044.7l-256%20352c-5.5%207.6-14%2012.3-23.4%2013.1s-18.5-2.7-25.1-9.3l-128-128c-12.5-12.5-12.5-32.8%200-45.3s32.8-12.5%2045.3%200l101.5%20101.5%20234-321.7c10.4-14.3%2030.4-17.5%2044.7-7.1z%22/%3E%3C/svg%3E');--md-admonition-icon--question:url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20512%20512%22%3E%3C%21--%21%20Font%20Awesome%20Free%207.1.0%20by%20%40fontawesome%20-%20https%3A//fontawesome.com%20License%20-%20https%3A//fontawesome.com/license/free%20%28Icons%3A%20CC%20BY%204.0%2C%20Fonts%3A%20SIL%20OFL%201.1%2C%20Code%3A%20MIT%20License%29%20Copyright%202025%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M256%20512a256%20256%200%201%200%200-512%20256%20256%200%201%200%200%20512m0-336c-17.7%200-32%2014.3-32%2032%200%2013.3-10.7%2024-24%2024s-24-10.7-24-24c0-44.2%2035.8-80%2080-80s80%2035.8%2080%2080c0%2047.2-36%2067.2-56%2074.5v3.8c0%2013.3-10.7%2024-24%2024s-24-10.7-24-24v-8.1c0-20.5%2014.8-35.2%2030.1-40.2%206.4-2.1%2013.2-5.5%2018.2-10.3%204.3-4.2%207.7-10%207.7-19.6%200-17.7-14.3-32-32-32zm-32%20192a32%2032%200%201%201%2064%200%2032%2032%200%201%201-64%200%22/%3E%3C/svg%3E');--md-admonition-icon--warning:url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20512%20512%22%3E%3C%21--%21%20Font%20Awesome%20Free%207.1.0%20by%20%40fontawesome%20-%20https%3A//fontawesome.com%20License%20-%20https%3A//fontawesome.com/license/free%20%28Icons%3A%20CC%20BY%204.0%2C%20Fonts%3A%20SIL%20OFL%201.1%2C%20Code%3A%20MIT%20License%29%20Copyright%202025%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M256%200c14.7%200%2028.2%208.1%2035.2%2021l216%20400c6.7%2012.4%206.4%2027.4-.8%2039.5S486.1%20480%20472%20480H40c-14.1%200-27.2-7.4-34.4-19.5s-7.5-27.1-.8-39.5l216-400c7-12.9%2020.5-21%2035.2-21m0%20352a32%2032%200%201%200%200%2064%2032%2032%200%201%200%200-64m0-192c-18.2%200-32.7%2015.5-31.4%2033.7l7.4%20104c.9%2012.5%2011.4%2022.3%2023.9%2022.3%2012.6%200%2023-9.7%2023.9-22.3l7.4-104c1.3-18.2-13.1-33.7-31.4-33.7z%22/%3E%3C/svg%3E');--md-admonition-icon--failure:url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20384%20512%22%3E%3C%21--%21%20Font%20Awesome%20Free%207.1.0%20by%20%40fontawesome%20-%20https%3A//fontawesome.com%20License%20-%20https%3A//fontawesome.com/license/free%20%28Icons%3A%20CC%20BY%204.0%2C%20Fonts%3A%20SIL%20OFL%201.1%2C%20Code%3A%20MIT%20License%29%20Copyright%202025%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M55.1%2073.4c-12.5-12.5-32.8-12.5-45.3%200s-12.5%2032.8%200%2045.3L147.2%20256%209.9%20393.4c-12.5%2012.5-12.5%2032.8%200%2045.3s32.8%2012.5%2045.3%200l137.3-137.4%20137.4%20137.3c12.5%2012.5%2032.8%2012.5%2045.3%200s12.5-32.8%200-45.3L237.8%20256l137.3-137.4c12.5-12.5%2012.5-32.8%200-45.3s-32.8-12.5-45.3%200L192.5%20210.7z%22/%3E%3C/svg%3E');--md-admonition-icon--danger:url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20512%20512%22%3E%3C%21--%21%20Font%20Awesome%20Free%207.1.0%20by%20%40fontawesome%20-%20https%3A//fontawesome.com%20License%20-%20https%3A//fontawesome.com/license/free%20%28Icons%3A%20CC%20BY%204.0%2C%20Fonts%3A%20SIL%20OFL%201.1%2C%20Code%3A%20MIT%20License%29%20Copyright%202025%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M416%20427.4c58.5-44%2096-111.6%2096-187.4C512%20107.5%20397.4%200%20256%200S0%20107.5%200%20240c0%2075.8%2037.5%20143.4%2096%20187.4V464c0%2026.5%2021.5%2048%2048%2048h32v-40c0-13.3%2010.7-24%2024-24s24%2010.7%2024%2024v40h64v-40c0-13.3%2010.7-24%2024-24s24%2010.7%2024%2024v40h32c26.5%200%2048-21.5%2048-48zM96%20256a64%2064%200%201%201%20128%200%2064%2064%200%201%201-128%200m256-64a64%2064%200%201%201%200%20128%2064%2064%200%201%201%200-128%22/%3E%3C/svg%3E');--md-admonition-icon--bug:url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20576%20512%22%3E%3C%21--%21%20Font%20Awesome%20Free%207.1.0%20by%20%40fontawesome%20-%20https%3A//fontawesome.com%20License%20-%20https%3A//fontawesome.com/license/free%20%28Icons%3A%20CC%20BY%204.0%2C%20Fonts%3A%20SIL%20OFL%201.1%2C%20Code%3A%20MIT%20License%29%20Copyright%202025%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M192%2096c0-53%2043-96%2096-96s96%2043%2096%2096v3.6c0%2015.7-12.7%2028.4-28.4%2028.4H220.5c-15.7%200-28.4-12.7-28.4-28.4V96zm345.6%2012.8c10.6%2014.1%207.7%2034.2-6.4%2044.8l-97.8%2073.3c5.3%208.9%209.3%2018.7%2011.8%2029.1H544c17.7%200%2032%2014.3%2032%2032s-14.3%2032-32%2032h-96v32c0%202.6-.1%205.3-.2%207.9l83.4%2062.5c14.1%2010.6%2017%2030.7%206.4%2044.8s-30.7%2017-44.8%206.4l-63.1-47.3c-23.2%2044.2-66.5%2076.2-117.7%2083.9V280c0-13.3-10.7-24-24-24s-24%2010.7-24%2024v230.2c-51.2-7.7-94.5-39.7-117.7-83.9l-63.1%2047.3c-14.1%2010.6-34.2%207.7-44.8-6.4s-7.7-34.2%206.4-44.8l83.4-62.5c-.1-2.6-.2-5.2-.2-7.9v-32H32c-17.7%200-32-14.3-32-32s14.3-32%2032-32h98.8c2.5-10.4%206.5-20.2%2011.8-29.1l-97.8-73.3c-14.1-10.6-17-30.7-6.4-44.8s30.7-17%2044.8-6.4L192%20184c12.3-5.1%2025.8-8%2040-8h112c14.2%200%2027.7%202.8%2040%208l108.8-81.6c14.1-10.6%2034.2-7.7%2044.8%206.4%22/%3E%3C/svg%3E');--md-admonition-icon--example:url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20448%20512%22%3E%3C%21--%21%20Font%20Awesome%20Free%207.1.0%20by%20%40fontawesome%20-%20https%3A//fontawesome.com%20License%20-%20https%3A//fontawesome.com/license/free%20%28Icons%3A%20CC%20BY%204.0%2C%20Fonts%3A%20SIL%20OFL%201.1%2C%20Code%3A%20MIT%20License%29%20Copyright%202025%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M288%200H128c-17.7%200-32%2014.3-32%2032s14.3%2032%2032%2032v151.5L7.5%20426.3C2.6%20435%200%20444.7%200%20454.7%200%20486.4%2025.6%20512%2057.3%20512h333.4c31.6%200%2057.3-25.6%2057.3-57.3%200-10-2.6-19.8-7.5-28.4L320%20215.5V64c17.7%200%2032-14.3%2032-32S337.7%200%20320%200zm-96%20215.5V64h64v151.5c0%2011.1%202.9%2022.1%208.4%2031.8L306%20320H142l41.6-72.7c5.5-9.7%208.4-20.6%208.4-31.8%22/%3E%3C/svg%3E');--md-admonition-icon--quote:url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%3D%220%200%20448%20512%22%3E%3C%21--%21%20Font%20Awesome%20Free%207.1.0%20by%20%40fontawesome%20-%20https%3A//fontawesome.com%20License%20-%20https%3A//fontawesome.com/license/free%20%28Icons%3A%20CC%20BY%204.0%2C%20Fonts%3A%20SIL%20OFL%201.1%2C%20Code%3A%20MIT%20License%29%20Copyright%202025%20Fonticons%2C%20Inc.--%3E%3Cpath%20d%3D%22M0%20216C0%20149.7%2053.7%2096%20120%2096h8c17.7%200%2032%2014.3%2032%2032s-14.3%2032-32%2032h-8c-30.9%200-56%2025.1-56%2056v8h64c35.3%200%2064%2028.7%2064%2064v64c0%2035.3-28.7%2064-64%2064H64c-35.3%200-64-28.7-64-64zm256%200c0-66.3%2053.7-120%20120-120h8c17.7%200%2032%2014.3%2032%2032s-14.3%2032-32%2032h-8c-30.9%200-56%2025.1-56%2056v8h64c35.3%200%2064%2028.7%2064%2064v64c0%2035.3-28.7%2064-64%2064h-64c-35.3%200-64-28.7-64-64z%22/%3E%3C/svg%3E');}</style><link rel=preconnect href=https://fonts.gstatic.com crossorigin><link rel=stylesheet href="https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback"><style>:root{--md-text-font:"Inter";--md-code-font:"JetBrains Mono"}</style><link rel=stylesheet href=../../../css/timeago.css><link rel=stylesheet href=../../../stylesheets/custom.css><script>__md_scope=new URL("../../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script></head> <body dir=ltr data-md-color-scheme=slate data-md-color-primary=teal data-md-color-accent=deep-orange> <input class=md-toggle data-md-toggle=drawer type=checkbox id=__drawer autocomplete=off> <input class=md-toggle data-md-toggle=search type=checkbox id=__search autocomplete=off> <label class=md-overlay for=__drawer></label> <div data-md-component=skip> <a href=#serialization-types class=md-skip> Skip to content </a> </div> <div data-md-component=announce> </div> <header class="md-header md-header--shadow md-header--lifted" data-md-component=header> <nav class="md-header__inner md-grid" aria-label=Header> <a href=../../.. title="Unity Helpers" class="md-header__button md-logo" aria-label="Unity Helpers" data-md-component=logo> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg> </a> <label class="md-header__button md-icon" for=__drawer> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg> </label> <div class=md-header__title data-md-component=header-title> <div class=md-header__ellipsis> <div class=md-header__topic> <span class=md-ellipsis> Unity Helpers </span> </div> <div class=md-header__topic data-md-component=header-topic> <span class=md-ellipsis> Serializable Types </span> </div> </div> </div> <form class=md-header__option data-md-component=palette> <input class=md-option data-md-color-media data-md-color-scheme=slate data-md-color-primary=teal data-md-color-accent=deep-orange aria-label="Switch to light mode" type=radio name=__palette id=__palette_0> <label class="md-header__button md-icon" title="Switch to light mode" for=__palette_1 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3zm3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95zm-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31"/></svg> </label> <input class=md-option data-md-color-media data-md-color-scheme=default data-md-color-primary=teal data-md-color-accent=deep-orange aria-label="Switch to dark mode" type=radio name=__palette id=__palette_1> <label class="md-header__button md-icon" title="Switch to dark mode" for=__palette_0 hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5s-1.65.15-2.39.42zM3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29zm.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14zM20.65 7l-1.77 3.79a7.02 7.02 0 0 0-2.38-4.15zm-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29zM12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44z"/></svg> </label> </form> <script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script> <label class="md-header__button md-icon" for=__search> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg> </label> <div class=md-search data-md-component=search role=dialog> <label class=md-search__overlay for=__search></label> <div class=md-search__inner role=search> <form class=md-search__form name=search> <input type=text class=md-search__input name=query aria-label=Search placeholder=Search autocapitalize=off autocorrect=off autocomplete=off spellcheck=false data-md-component=search-query required> <label class="md-search__icon md-icon" for=__search> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg> </label> <nav class=md-search__options aria-label=Search> <a href=javascript:void(0) class="md-search__icon md-icon" title=Share aria-label=Share data-clipboard data-clipboard-text data-md-component=search-share tabindex=-1> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg> </a> <button type=reset class="md-search__icon md-icon" title=Clear aria-label=Clear tabindex=-1> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg> </button> </nav> <div class=md-search__suggest data-md-component=search-suggest></div> </form> <div class=md-search__output> <div class=md-search__scrollwrap tabindex=0 data-md-scrollfix> <div class=md-search-result data-md-component=search-result> <div class=md-search-result__meta> Initializing search </div> <ol class=md-search-result__list role=presentation></ol> </div> </div> </div> </div> </div> <div class=md-header__source> <a href=https://github.com/wallstop/unity-helpers title="Go to repository" class=md-source data-md-component=source> <div class="md-source__icon md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 512 512"><!-- Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg> </div> <div class=md-source__repository> wallstop/unity-helpers </div> </a> </div> </nav> <nav class=md-tabs aria-label=Tabs data-md-component=tabs> <div class=md-grid> <ul class=md-tabs__list> <li class=md-tabs__item> <a href=../../.. class=md-tabs__link> Home </a> </li> <li class=md-tabs__item> <a href=../../../overview/getting-started/ class=md-tabs__link> Getting Started </a> </li> <li class="md-tabs__item md-tabs__item--active"> <a href=../../inspector/inspector-overview/ class=md-tabs__link> Features </a> </li> <li class=md-tabs__item> <a href=../../../performance/random-performance/ class=md-tabs__link> Performance </a> </li> <li class=md-tabs__item> <a href=../../../guides/odin-migration-guide/ class=md-tabs__link> Guides </a> </li> <li class=md-tabs__item> <a href=../../../project/contributing/ class=md-tabs__link> Contributing </a> </li> <li class=md-tabs__item> <a href=../../../project/license/ class=md-tabs__link> Project </a> </li> </ul> </div> </nav> </header> <div class=md-container data-md-component=container> <main class=md-main data-md-component=main> <div class="md-main__inner md-grid"> <div class="md-sidebar md-sidebar--primary" data-md-component=sidebar data-md-type=navigation> <div class=md-sidebar__scrollwrap> <div class=md-sidebar__inner> <nav class="md-nav md-nav--primary md-nav--lifted md-nav--integrated" aria-label=Navigation data-md-level=0> <label class=md-nav__title for=__drawer> <a href=../../.. title="Unity Helpers" class="md-nav__button md-logo" aria-label="Unity Helpers" data-md-component=logo> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg> </a> Unity Helpers </label> <div class=md-nav__source> <a href=https://github.com/wallstop/unity-helpers title="Go to repository" class=md-source data-md-component=source> <div class="md-source__icon md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 512 512"><!-- Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg> </div> <div class=md-source__repository> wallstop/unity-helpers </div> </a> </div> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../.. class=md-nav__link> <span class=md-ellipsis> Home </span> </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_2> <div class="md-nav__link md-nav__container"> <a href=../../../overview/ class="md-nav__link "> <span class=md-ellipsis> Getting Started </span> </a> <label class="md-nav__link " for=__nav_2 id=__nav_2_label tabindex=0> <span class="md-nav__icon md-icon"></span> </label> </div> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_2_label aria-expanded=false> <label class=md-nav__title for=__nav_2> <span class="md-nav__icon md-icon"></span> Getting Started </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../../overview/getting-started/ class=md-nav__link> <span class=md-ellipsis> Quick Start </span> </a> </li> <li class=md-nav__item> <a href=../../../overview/glossary/ class=md-nav__link> <span class=md-ellipsis> Glossary </span> </a> </li> <li class=md-nav__item> <a href=../../../overview/roadmap/ class=md-nav__link> <span class=md-ellipsis> Roadmap </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type=checkbox id=__nav_3 checked> <label class=md-nav__link for=__nav_3 id=__nav_3_label tabindex> <span class=md-ellipsis> Features </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_3_label aria-expanded=true> <label class=md-nav__title for=__nav_3> <span class="md-nav__icon md-icon"></span> Features </label> <ul class=md-nav__list data-md-scrollfix> <li class="md-nav__item md-nav__item--section md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_3_1> <label class=md-nav__link for=__nav_3_1 id=__nav_3_1_label tabindex> <span class=md-ellipsis> Inspector </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=2 aria-labelledby=__nav_3_1_label aria-expanded=false> <label class=md-nav__title for=__nav_3_1> <span class="md-nav__icon md-icon"></span> Inspector </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../inspector/inspector-overview/ class=md-nav__link> <span class=md-ellipsis> Overview </span> </a> </li> <li class=md-nav__item> <a href=../../inspector/inspector-button/ class=md-nav__link> <span class=md-ellipsis> Buttons </span> </a> </li> <li class=md-nav__item> <a href=../../inspector/inspector-grouping-attributes/ class=md-nav__link> <span class=md-ellipsis> Grouping Attributes </span> </a> </li> <li class=md-nav__item> <a href=../../inspector/inspector-selection-attributes/ class=md-nav__link> <span class=md-ellipsis> Selection Attributes </span> </a> </li> <li class=md-nav__item> <a href=../../inspector/inspector-conditional-display/ class=md-nav__link> <span class=md-ellipsis> Conditional Display </span> </a> </li> <li class=md-nav__item> <a href=../../inspector/inspector-validation-attributes/ class=md-nav__link> <span class=md-ellipsis> Validation Attributes </span> </a> </li> <li class=md-nav__item> <a href=../../inspector/inspector-inline-editor/ class=md-nav__link> <span class=md-ellipsis> Inline Editor </span> </a> </li> <li class=md-nav__item> <a href=../../inspector/inspector-settings/ class=md-nav__link> <span class=md-ellipsis> Inspector Settings </span> </a> </li> <li class=md-nav__item> <a href=../../inspector/utility-components/ class=md-nav__link> <span class=md-ellipsis> Utility Components </span> </a> </li> <li class=md-nav__item> <a href=../../inspector/visual-components/ class=md-nav__link> <span class=md-ellipsis> Visual Components </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--section md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_3_2> <label class=md-nav__link for=__nav_3_2 id=__nav_3_2_label tabindex> <span class=md-ellipsis> Relational Components </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=2 aria-labelledby=__nav_3_2_label aria-expanded=false> <label class=md-nav__title for=__nav_3_2> <span class="md-nav__icon md-icon"></span> Relational Components </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../relational-components/relational-components/ class=md-nav__link> <span class=md-ellipsis> Overview </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--section md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_3_3> <label class=md-nav__link for=__nav_3_3 id=__nav_3_3_label tabindex> <span class=md-ellipsis> Spatial Data Structures </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=2 aria-labelledby=__nav_3_3_label aria-expanded=false> <label class=md-nav__title for=__nav_3_3> <span class="md-nav__icon md-icon"></span> Spatial Data Structures </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../spatial/spatial-trees-2d-guide/ class=md-nav__link> <span class=md-ellipsis> 2D Spatial Trees </span> </a> </li> <li class=md-nav__item> <a href=../../spatial/spatial-trees-3d-guide/ class=md-nav__link> <span class=md-ellipsis> 3D Spatial Trees </span> </a> </li> <li class=md-nav__item> <a href=../../spatial/hulls/ class=md-nav__link> <span class=md-ellipsis> Hull Algorithms </span> </a> </li> <li class=md-nav__item> <a href=../../spatial/spatial-tree-semantics/ class=md-nav__link> <span class=md-ellipsis> Spatial Tree Semantics </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--section md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_3_4> <label class=md-nav__link for=__nav_3_4 id=__nav_3_4_label tabindex> <span class=md-ellipsis> Effects System </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=2 aria-labelledby=__nav_3_4_label aria-expanded=false> <label class=md-nav__title for=__nav_3_4> <span class="md-nav__icon md-icon"></span> Effects System </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../effects/effects-system/ class=md-nav__link> <span class=md-ellipsis> Overview </span> </a> </li> <li class=md-nav__item> <a href=../../effects/effects-system-tutorial/ class=md-nav__link> <span class=md-ellipsis> Tutorial </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested"> <input class="md-nav__toggle md-toggle " type=checkbox id=__nav_3_5 checked> <label class=md-nav__link for=__nav_3_5 id=__nav_3_5_label tabindex> <span class=md-ellipsis> Serialization </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=2 aria-labelledby=__nav_3_5_label aria-expanded=true> <label class=md-nav__title for=__nav_3_5> <span class="md-nav__icon md-icon"></span> Serialization </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../serialization/ class=md-nav__link> <span class=md-ellipsis> Overview </span> </a> </li> <li class="md-nav__item md-nav__item--active"> <input class="md-nav__toggle md-toggle" type=checkbox id=__toc> <label class="md-nav__link md-nav__link--active" for=__toc> <span class=md-ellipsis> Serializable Types </span> <span class="md-nav__icon md-icon"></span> </label> <a href=./ class="md-nav__link md-nav__link--active"> <span class=md-ellipsis> Serializable Types </span> </a> <nav class="md-nav md-nav--secondary" aria-label="Table of contents"> <label class=md-nav__title for=__toc> <span class="md-nav__icon md-icon"></span> Table of contents </label> <ul class=md-nav__list data-md-component=toc data-md-scrollfix> <li class=md-nav__item> <a href=#table-of-contents class=md-nav__link> <span class=md-ellipsis> Table of Contents </span> </a> </li> <li class=md-nav__item> <a href=#wguid class=md-nav__link> <span class=md-ellipsis> WGuid </span> </a> <nav class=md-nav aria-label=WGuid> <ul class=md-nav__list> <li class=md-nav__item> <a href=#why-wguid class=md-nav__link> <span class=md-ellipsis> Why WGuid? </span> </a> </li> <li class=md-nav__item> <a href=#basic-usage class=md-nav__link> <span class=md-ellipsis> Basic Usage </span> </a> </li> <li class=md-nav__item> <a href=#creating-guids class=md-nav__link> <span class=md-ellipsis> Creating GUIDs </span> </a> </li> <li class=md-nav__item> <a href=#inspector-features class=md-nav__link> <span class=md-ellipsis> Inspector Features </span> </a> </li> <li class=md-nav__item> <a href=#conversions class=md-nav__link> <span class=md-ellipsis> Conversions </span> </a> </li> <li class=md-nav__item> <a href=#equality-comparison class=md-nav__link> <span class=md-ellipsis> Equality &amp; Comparison </span> </a> </li> <li class=md-nav__item> <a href=#serialization-support class=md-nav__link> <span class=md-ellipsis> Serialization Support </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=#serializabledictionary class=md-nav__link> <span class=md-ellipsis> SerializableDictionary </span> </a> <nav class=md-nav aria-label=SerializableDictionary> <ul class=md-nav__list> <li class=md-nav__item> <a href=#why-serializabledictionary class=md-nav__link> <span class=md-ellipsis> Why SerializableDictionary? </span> </a> </li> <li class=md-nav__item> <a href=#basic-usage_1 class=md-nav__link> <span class=md-ellipsis> Basic Usage </span> </a> </li> <li class=md-nav__item> <a href=#inspector-features_1 class=md-nav__link> <span class=md-ellipsis> Inspector Features </span> </a> </li> <li class=md-nav__item> <a href=#dictionary-operations class=md-nav__link> <span class=md-ellipsis> Dictionary Operations </span> </a> </li> <li class=md-nav__item> <a href=#specialized-dictionaries class=md-nav__link> <span class=md-ellipsis> Specialized Dictionaries </span> </a> </li> <li class=md-nav__item> <a href=#serialization-support_1 class=md-nav__link> <span class=md-ellipsis> Serialization Support </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=#serializablehashset-serializablesortedset class=md-nav__link> <span class=md-ellipsis> SerializableHashSet &amp; SerializableSortedSet </span> </a> <nav class=md-nav aria-label="SerializableHashSet & SerializableSortedSet"> <ul class=md-nav__list> <li class=md-nav__item> <a href=#why-serializable-sets class=md-nav__link> <span class=md-ellipsis> Why Serializable Sets? </span> </a> </li> <li class=md-nav__item> <a href=#basic-usage_2 class=md-nav__link> <span class=md-ellipsis> Basic Usage </span> </a> </li> <li class=md-nav__item> <a href=#inspector-features_2 class=md-nav__link> <span class=md-ellipsis> Inspector Features </span> </a> </li> <li class=md-nav__item> <a href=#set-operations class=md-nav__link> <span class=md-ellipsis> Set Operations </span> </a> </li> <li class=md-nav__item> <a href=#new-entry-foldout class=md-nav__link> <span class=md-ellipsis> New Entry Foldout </span> </a> </li> <li class=md-nav__item> <a href=#foldout-defaults-overrides class=md-nav__link> <span class=md-ellipsis> Foldout Defaults &amp; Overrides </span> </a> </li> <li class=md-nav__item> <a href=#sorted-sets class=md-nav__link> <span class=md-ellipsis> Sorted Sets </span> </a> </li> <li class=md-nav__item> <a href=#serialization-support_2 class=md-nav__link> <span class=md-ellipsis> Serialization Support </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=#serializabletype class=md-nav__link> <span class=md-ellipsis> SerializableType </span> </a> <nav class=md-nav aria-label=SerializableType> <ul class=md-nav__list> <li class=md-nav__item> <a href=#why-serializabletype class=md-nav__link> <span class=md-ellipsis> Why SerializableType? </span> </a> </li> <li class=md-nav__item> <a href=#basic-usage_3 class=md-nav__link> <span class=md-ellipsis> Basic Usage </span> </a> </li> <li class=md-nav__item> <a href=#inspector-features_3 class=md-nav__link> <span class=md-ellipsis> Inspector Features </span> </a> </li> <li class=md-nav__item> <a href=#type-operations class=md-nav__link> <span class=md-ellipsis> Type Operations </span> </a> </li> <li class=md-nav__item> <a href=#refactoring-resilience class=md-nav__link> <span class=md-ellipsis> Refactoring Resilience </span> </a> </li> <li class=md-nav__item> <a href=#serialization-support_3 class=md-nav__link> <span class=md-ellipsis> Serialization Support </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=#serializablenullable class=md-nav__link> <span class=md-ellipsis> SerializableNullable </span> </a> <nav class=md-nav aria-label=SerializableNullable> <ul class=md-nav__list> <li class=md-nav__item> <a href=#why-serializablenullable class=md-nav__link> <span class=md-ellipsis> Why SerializableNullable? </span> </a> </li> <li class=md-nav__item> <a href=#basic-usage_4 class=md-nav__link> <span class=md-ellipsis> Basic Usage </span> </a> </li> <li class=md-nav__item> <a href=#inspector-features_4 class=md-nav__link> <span class=md-ellipsis> Inspector Features </span> </a> </li> <li class=md-nav__item> <a href=#nullable-operations class=md-nav__link> <span class=md-ellipsis> Nullable Operations </span> </a> </li> <li class=md-nav__item> <a href=#use-cases class=md-nav__link> <span class=md-ellipsis> Use Cases </span> </a> </li> <li class=md-nav__item> <a href=#serialization-support_4 class=md-nav__link> <span class=md-ellipsis> Serialization Support </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=#best-practices class=md-nav__link> <span class=md-ellipsis> Best Practices </span> </a> <nav class=md-nav aria-label="Best Practices"> <ul class=md-nav__list> <li class=md-nav__item> <a href=#1-choose-the-right-type class=md-nav__link> <span class=md-ellipsis> 1. Choose the Right Type </span> </a> </li> <li class=md-nav__item> <a href=#2-initialize-collections class=md-nav__link> <span class=md-ellipsis> 2. Initialize Collections </span> </a> </li> <li class=md-nav__item> <a href=#3-use-sorted-variants-for-ordered-data class=md-nav__link> <span class=md-ellipsis> 3. Use Sorted Variants for Ordered Data </span> </a> </li> <li class=md-nav__item> <a href=#4-handle-wguid-generation-carefully class=md-nav__link> <span class=md-ellipsis> 4. Handle WGuid Generation Carefully </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=#examples class=md-nav__link> <span class=md-ellipsis> Examples </span> </a> <nav class=md-nav aria-label=Examples> <ul class=md-nav__list> <li class=md-nav__item> <a href=#example-1-item-database-with-dictionary class=md-nav__link> <span class=md-ellipsis> Example 1: Item Database with Dictionary </span> </a> </li> <li class=md-nav__item> <a href=#example-2-player-achievement-tracking class=md-nav__link> <span class=md-ellipsis> Example 2: Player Achievement Tracking </span> </a> </li> <li class=md-nav__item> <a href=#example-3-dynamic-behavior-spawning class=md-nav__link> <span class=md-ellipsis> Example 3: Dynamic Behavior Spawning </span> </a> </li> <li class=md-nav__item> <a href=#example-4-optional-configuration-with-nullable class=md-nav__link> <span class=md-ellipsis> Example 4: Optional Configuration with Nullable </span> </a> </li> </ul> </nav> </li> <li class=md-nav__item> <a href=#see-also class=md-nav__link> <span class=md-ellipsis> See Also </span> </a> </li> </ul> </nav> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--section md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_3_6> <label class=md-nav__link for=__nav_3_6 id=__nav_3_6_label tabindex> <span class=md-ellipsis> Utilities </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=2 aria-labelledby=__nav_3_6_label aria-expanded=false> <label class=md-nav__title for=__nav_3_6> <span class="md-nav__icon md-icon"></span> Utilities </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../utilities/math-and-extensions/ class=md-nav__link> <span class=md-ellipsis> Math & Extensions </span> </a> </li> <li class=md-nav__item> <a href=../../utilities/data-structures/ class=md-nav__link> <span class=md-ellipsis> Data Structures </span> </a> </li> <li class=md-nav__item> <a href=../../utilities/random-generators/ class=md-nav__link> <span class=md-ellipsis> Random Generators </span> </a> </li> <li class=md-nav__item> <a href=../../utilities/singletons/ class=md-nav__link> <span class=md-ellipsis> Singletons </span> </a> </li> <li class=md-nav__item> <a href=../../utilities/reflection-helpers/ class=md-nav__link> <span class=md-ellipsis> Reflection Helpers </span> </a> </li> <li class=md-nav__item> <a href=../../utilities/helper-utilities/ class=md-nav__link> <span class=md-ellipsis> Helper Utilities </span> </a> </li> <li class=md-nav__item> <a href=../../utilities/pooling-guide/ class=md-nav__link> <span class=md-ellipsis> Pooling Guide </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--section md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_3_7> <label class=md-nav__link for=__nav_3_7 id=__nav_3_7_label tabindex> <span class=md-ellipsis> Logging </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=2 aria-labelledby=__nav_3_7_label aria-expanded=false> <label class=md-nav__title for=__nav_3_7> <span class="md-nav__icon md-icon"></span> Logging </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../logging/logging-extensions/ class=md-nav__link> <span class=md-ellipsis> Logging Extensions </span> </a> </li> <li class=md-nav__item> <a href=../../logging/unity-main-thread-dispatcher/ class=md-nav__link> <span class=md-ellipsis> Main Thread Dispatcher </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--section md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_3_8> <label class=md-nav__link for=__nav_3_8 id=__nav_3_8_label tabindex> <span class=md-ellipsis> Editor Tools </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=2 aria-labelledby=__nav_3_8_label aria-expanded=false> <label class=md-nav__title for=__nav_3_8> <span class="md-nav__icon md-icon"></span> Editor Tools </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../editor-tools/editor-tools-guide/ class=md-nav__link> <span class=md-ellipsis> Tools Guide </span> </a> </li> <li class=md-nav__item> <a href=../../editor-tools/unity-method-analyzer/ class=md-nav__link> <span class=md-ellipsis> Unity Method Analyzer </span> </a> </li> <li class=md-nav__item> <a href=../../editor-tools/asset-change-detection/ class=md-nav__link> <span class=md-ellipsis> Asset Change Detection </span> </a> </li> <li class=md-nav__item> <a href=../../editor-tools/failed-tests-exporter/ class=md-nav__link> <span class=md-ellipsis> Failed Tests Exporter </span> </a> </li> </ul> </nav> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_4> <label class=md-nav__link for=__nav_4 id=__nav_4_label tabindex=0> <span class=md-ellipsis> Performance </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_4_label aria-expanded=false> <label class=md-nav__title for=__nav_4> <span class="md-nav__icon md-icon"></span> Performance </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../../performance/random-performance/ class=md-nav__link> <span class=md-ellipsis> Random Generators </span> </a> </li> <li class=md-nav__item> <a href=../../../performance/spatial-tree-2d-performance/ class=md-nav__link> <span class=md-ellipsis> Spatial Trees 2D </span> </a> </li> <li class=md-nav__item> <a href=../../../performance/spatial-tree-3d-performance/ class=md-nav__link> <span class=md-ellipsis> Spatial Trees 3D </span> </a> </li> <li class=md-nav__item> <a href=../../../performance/relational-components-performance/ class=md-nav__link> <span class=md-ellipsis> Relational Components </span> </a> </li> <li class=md-nav__item> <a href=../../../performance/reflection-performance/ class=md-nav__link> <span class=md-ellipsis> Reflection Helpers </span> </a> </li> <li class=md-nav__item> <a href=../../../performance/ilist-sorting-performance/ class=md-nav__link> <span class=md-ellipsis> IList Sorting </span> </a> </li> <li class=md-nav__item> <a href=../../../performance/baseline-tests-performance/ class=md-nav__link> <span class=md-ellipsis> Baseline Tests </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_5> <label class=md-nav__link for=__nav_5 id=__nav_5_label tabindex=0> <span class=md-ellipsis> Guides </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_5_label aria-expanded=false> <label class=md-nav__title for=__nav_5> <span class="md-nav__icon md-icon"></span> Guides </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../../guides/odin-migration-guide/ class=md-nav__link> <span class=md-ellipsis> Odin Migration </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_6> <label class=md-nav__link for=__nav_6 id=__nav_6_label tabindex=0> <span class=md-ellipsis> Contributing </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_6_label aria-expanded=false> <label class=md-nav__title for=__nav_6> <span class="md-nav__icon md-icon"></span> Contributing </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../../project/contributing/ class=md-nav__link> <span class=md-ellipsis> Overview </span> </a> </li> <li class=md-nav__item> <a href=../../../contributing/testing-patterns/ class=md-nav__link> <span class=md-ellipsis> Testing Patterns </span> </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle md-toggle--indeterminate" type=checkbox id=__nav_7> <label class=md-nav__link for=__nav_7 id=__nav_7_label tabindex=0> <span class=md-ellipsis> Project </span> <span class="md-nav__icon md-icon"></span> </label> <nav class=md-nav data-md-level=1 aria-labelledby=__nav_7_label aria-expanded=false> <label class=md-nav__title for=__nav_7> <span class="md-nav__icon md-icon"></span> Project </label> <ul class=md-nav__list data-md-scrollfix> <li class=md-nav__item> <a href=../../../project/license/ class=md-nav__link> <span class=md-ellipsis> License </span> </a> </li> <li class=md-nav__item> <a href=../../../project/third-party-notices/ class=md-nav__link> <span class=md-ellipsis> Third-Party Notices </span> </a> </li> <li class=md-nav__item> <a href=../../../project/llms-txt/ class=md-nav__link> <span class=md-ellipsis> LLMs.txt </span> </a> </li> </ul> </nav> </li> </ul> </nav> </div> </div> </div> <div class=md-content data-md-component=content> <nav class=md-path aria-label=Navigation> <ol class=md-path__list> <li class=md-path__item> <a href=../../.. class=md-path__link> <span class=md-ellipsis> Home </span> </a> </li> <li class=md-path__item> <a href=../../inspector/inspector-overview/ class=md-path__link> <span class=md-ellipsis> Features </span> </a> </li> <li class=md-path__item> <a href=../serialization/ class=md-path__link> <span class=md-ellipsis> Serialization </span> </a> </li> </ol> </nav> <article class="md-content__inner md-typeset"> <a href=https://github.com/wallstop/unity-helpers/edit/main/docs/features/serialization/serialization-types.md title="Edit this page" class="md-content__button md-icon" rel=edit> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75z"/></svg> </a> <a href=https://github.com/wallstop/unity-helpers/raw/main/docs/features/serialization/serialization-types.md title="View source of this page" class="md-content__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M12 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0 8a5 5 0 0 1-5-5 5 5 0 0 1 5-5 5 5 0 0 1 5 5 5 5 0 0 1-5 5m0-12.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5"/></svg> </a> <h1 id=serialization-types>Serialization Types<a class=headerlink href=#serialization-types title="Permanent link">&para;</a></h1> <p><strong>Unity-friendly wrappers for complex data.</strong></p> <p>Unity Helpers provides serializable wrappers for types that Unity can't serialize natively: GUIDs, dictionaries, sets, type references, and nullable values. All types include custom property drawers for a seamless inspector experience and support JSON/Protobuf serialization.</p> <hr> <h2 id=table-of-contents>Table of Contents<a class=headerlink href=#table-of-contents title="Permanent link">&para;</a></h2> <ul> <li><a href=#wguid>WGuid</a></li> <li><a href=#serializabledictionary>SerializableDictionary</a></li> <li><a href=#serializablehashset--serializablesortedset>SerializableHashSet &amp; SerializableSortedSet</a></li> <li><a href=#serializabletype>SerializableType</a></li> <li><a href=#serializablenullable>SerializableNullable</a></li> <li><a href=#best-practices>Best Practices</a></li> <li><a href=#examples>Examples</a></li> </ul> <hr> <h2 id=wguid>WGuid<a class=headerlink href=#wguid title="Permanent link">&para;</a></h2> <p>Immutable version-4 GUID wrapper using two longs for efficient Unity serialization.</p> <h3 id=why-wguid>Why WGuid?<a class=headerlink href=#why-wguid title="Permanent link">&para;</a></h3> <ul> <li><strong>Problem:</strong> Unity doesn't serialize <code>System.Guid</code> directly</li> <li><strong>Solution:</strong> <code>WGuid</code> stores as two <code>long</code> fields (<code>_low</code> and <code>_high</code>) for fast Unity serialization</li> </ul> <p><strong>Performance:</strong></p> <ul> <li>2x faster serialization than string-based GUID storage</li> <li>Smaller memory footprint (16 bytes vs. 36 bytes for string)</li> <li>Immutable design prevents accidental modification</li> </ul> <hr> <h3 id=basic-usage>Basic Usage<a class=headerlink href=#basic-usage title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-0-1>1</a></span>
<span class=normal><a href=#__codelineno-0-2>2</a></span>
<span class=normal><a href=#__codelineno-0-3>3</a></span>
<span class=normal><a href=#__codelineno-0-4>4</a></span>
<span class=normal><a href=#__codelineno-0-5>5</a></span>
<span class=normal><a href=#__codelineno-0-6>6</a></span>
<span class=normal><a href=#__codelineno-0-7>7</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-0-1><a id=__codelineno-0-1 name=__codelineno-0-1></a><span class=k>using</span><span class=w> </span><span class=nn>UnityEngine</span><span class=p>;</span>
</span><span id=__span-0-2><a id=__codelineno-0-2 name=__codelineno-0-2></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.DataStructure.Adapters</span><span class=p>;</span>
</span><span id=__span-0-3><a id=__codelineno-0-3 name=__codelineno-0-3></a>
</span><span id=__span-0-4><a id=__codelineno-0-4 name=__codelineno-0-4></a><span class=k>public</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>Entity</span><span class=w> </span><span class=p>:</span><span class=w> </span><span class=n>MonoBehaviour</span>
</span><span id=__span-0-5><a id=__codelineno-0-5 name=__codelineno-0-5></a><span class=p>{</span>
</span><span id=__span-0-6><a id=__codelineno-0-6 name=__codelineno-0-6></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>WGuid</span><span class=w> </span><span class=n>entityId</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>WGuid</span><span class=p>.</span><span class=n>NewGuid</span><span class=p>();</span>
</span><span id=__span-0-7><a id=__codelineno-0-7 name=__codelineno-0-7></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <blockquote> <p><strong>Visual Reference</strong></p> <p><img alt="WGuid property drawer showing GUID field with Generate button" src=../../../images/serialization/wguid-inspector.png></p> </blockquote> <hr> <h3 id=creating-guids>Creating GUIDs<a class=headerlink href=#creating-guids title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-1-1> 1</a></span>
<span class=normal><a href=#__codelineno-1-2> 2</a></span>
<span class=normal><a href=#__codelineno-1-3> 3</a></span>
<span class=normal><a href=#__codelineno-1-4> 4</a></span>
<span class=normal><a href=#__codelineno-1-5> 5</a></span>
<span class=normal><a href=#__codelineno-1-6> 6</a></span>
<span class=normal><a href=#__codelineno-1-7> 7</a></span>
<span class=normal><a href=#__codelineno-1-8> 8</a></span>
<span class=normal><a href=#__codelineno-1-9> 9</a></span>
<span class=normal><a href=#__codelineno-1-10>10</a></span>
<span class=normal><a href=#__codelineno-1-11>11</a></span>
<span class=normal><a href=#__codelineno-1-12>12</a></span>
<span class=normal><a href=#__codelineno-1-13>13</a></span>
<span class=normal><a href=#__codelineno-1-14>14</a></span>
<span class=normal><a href=#__codelineno-1-15>15</a></span>
<span class=normal><a href=#__codelineno-1-16>16</a></span>
<span class=normal><a href=#__codelineno-1-17>17</a></span>
<span class=normal><a href=#__codelineno-1-18>18</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-1-1><a id=__codelineno-1-1 name=__codelineno-1-1></a><span class=c1>// Generate new GUID</span>
</span><span id=__span-1-2><a id=__codelineno-1-2 name=__codelineno-1-2></a><span class=n>WGuid</span><span class=w> </span><span class=n>id1</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>WGuid</span><span class=p>.</span><span class=n>NewGuid</span><span class=p>();</span>
</span><span id=__span-1-3><a id=__codelineno-1-3 name=__codelineno-1-3></a>
</span><span id=__span-1-4><a id=__codelineno-1-4 name=__codelineno-1-4></a><span class=c1>// From System.Guid</span>
</span><span id=__span-1-5><a id=__codelineno-1-5 name=__codelineno-1-5></a><span class=n>System</span><span class=p>.</span><span class=n>Guid</span><span class=w> </span><span class=n>sysGuid</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>System</span><span class=p>.</span><span class=n>Guid</span><span class=p>.</span><span class=n>NewGuid</span><span class=p>();</span>
</span><span id=__span-1-6><a id=__codelineno-1-6 name=__codelineno-1-6></a><span class=n>WGuid</span><span class=w> </span><span class=n>id2</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=p>(</span><span class=n>WGuid</span><span class=p>)</span><span class=n>sysGuid</span><span class=p>;</span>
</span><span id=__span-1-7><a id=__codelineno-1-7 name=__codelineno-1-7></a>
</span><span id=__span-1-8><a id=__codelineno-1-8 name=__codelineno-1-8></a><span class=c1>// Parse from string</span>
</span><span id=__span-1-9><a id=__codelineno-1-9 name=__codelineno-1-9></a><span class=n>WGuid</span><span class=w> </span><span class=n>id3</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>WGuid</span><span class=p>.</span><span class=n>Parse</span><span class=p>(</span><span class=s>&quot;12345678-1234-1234-1234-123456789abc&quot;</span><span class=p>);</span>
</span><span id=__span-1-10><a id=__codelineno-1-10 name=__codelineno-1-10></a>
</span><span id=__span-1-11><a id=__codelineno-1-11 name=__codelineno-1-11></a><span class=c1>// Try parse (safe)</span>
</span><span id=__span-1-12><a id=__codelineno-1-12 name=__codelineno-1-12></a><span class=k>if</span><span class=w> </span><span class=p>(</span><span class=n>WGuid</span><span class=p>.</span><span class=n>TryParse</span><span class=p>(</span><span class=s>&quot;...&quot;</span><span class=p>,</span><span class=w> </span><span class=k>out</span><span class=w> </span><span class=n>WGuid</span><span class=w> </span><span class=n>id4</span><span class=p>))</span>
</span><span id=__span-1-13><a id=__codelineno-1-13 name=__codelineno-1-13></a><span class=p>{</span>
</span><span id=__span-1-14><a id=__codelineno-1-14 name=__codelineno-1-14></a><span class=w>    </span><span class=n>Debug</span><span class=p>.</span><span class=n>Log</span><span class=p>(</span><span class=s>$&quot;Parsed: {id4}&quot;</span><span class=p>);</span>
</span><span id=__span-1-15><a id=__codelineno-1-15 name=__codelineno-1-15></a><span class=p>}</span>
</span><span id=__span-1-16><a id=__codelineno-1-16 name=__codelineno-1-16></a>
</span><span id=__span-1-17><a id=__codelineno-1-17 name=__codelineno-1-17></a><span class=c1>// Empty GUID</span>
</span><span id=__span-1-18><a id=__codelineno-1-18 name=__codelineno-1-18></a><span class=n>WGuid</span><span class=w> </span><span class=n>empty</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>WGuid</span><span class=p>.</span><span class=n>EmptyGuid</span><span class=p>;</span>
</span></code></pre></div></td></tr></table></div> <hr> <h3 id=inspector-features>Inspector Features<a class=headerlink href=#inspector-features title="Permanent link">&para;</a></h3> <p><strong>Custom Drawer:</strong></p> <ul> <li>Text field displays GUID in standard format</li> <li>"Generate" button creates new GUID</li> <li>Validation warns if GUID is not version-4</li> <li>Undo/redo support</li> </ul> <p><img alt="WGuid drawer with validation warning for GUID input" src=../../../images/serialization/wguid-inspector-obviously-invalid.png></p> <p><img alt="WGuid drawer with validation warning for non-v4 GUID" src=../../../images/serialization/wguid-inspector-not-v4.png></p> <p><img alt="WGuid generate button showing that it generates new v4 GUIDs" src=../../../images/serialization/wguid-inspector-generate.gif></p> <hr> <h3 id=conversions>Conversions<a class=headerlink href=#conversions title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-2-1>1</a></span>
<span class=normal><a href=#__codelineno-2-2>2</a></span>
<span class=normal><a href=#__codelineno-2-3>3</a></span>
<span class=normal><a href=#__codelineno-2-4>4</a></span>
<span class=normal><a href=#__codelineno-2-5>5</a></span>
<span class=normal><a href=#__codelineno-2-6>6</a></span>
<span class=normal><a href=#__codelineno-2-7>7</a></span>
<span class=normal><a href=#__codelineno-2-8>8</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-2-1><a id=__codelineno-2-1 name=__codelineno-2-1></a><span class=c1>// WGuid &lt;-&gt; System.Guid</span>
</span><span id=__span-2-2><a id=__codelineno-2-2 name=__codelineno-2-2></a><span class=n>WGuid</span><span class=w> </span><span class=n>wguid</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>WGuid</span><span class=p>.</span><span class=n>NewGuid</span><span class=p>();</span>
</span><span id=__span-2-3><a id=__codelineno-2-3 name=__codelineno-2-3></a><span class=n>System</span><span class=p>.</span><span class=n>Guid</span><span class=w> </span><span class=n>sysGuid</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>wguid</span><span class=p>.</span><span class=n>ToGuid</span><span class=p>();</span>
</span><span id=__span-2-4><a id=__codelineno-2-4 name=__codelineno-2-4></a><span class=n>WGuid</span><span class=w> </span><span class=n>back</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=p>(</span><span class=n>WGuid</span><span class=p>)</span><span class=n>sysGuid</span><span class=p>;</span>
</span><span id=__span-2-5><a id=__codelineno-2-5 name=__codelineno-2-5></a>
</span><span id=__span-2-6><a id=__codelineno-2-6 name=__codelineno-2-6></a><span class=c1>// ToString() formats</span>
</span><span id=__span-2-7><a id=__codelineno-2-7 name=__codelineno-2-7></a><span class=kt>string</span><span class=w> </span><span class=n>standard</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>wguid</span><span class=p>.</span><span class=n>ToString</span><span class=p>();</span><span class=w>  </span><span class=c1>// &quot;xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&quot;</span>
</span><span id=__span-2-8><a id=__codelineno-2-8 name=__codelineno-2-8></a><span class=kt>string</span><span class=w> </span><span class=n>formatted</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>wguid</span><span class=p>.</span><span class=n>ToString</span><span class=p>(</span><span class=s>&quot;N&quot;</span><span class=p>);</span><span class=w>  </span><span class=c1>// Without hyphens</span>
</span></code></pre></div></td></tr></table></div> <hr> <h3 id=equality-comparison>Equality &amp; Comparison<a class=headerlink href=#equality-comparison title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-3-1>1</a></span>
<span class=normal><a href=#__codelineno-3-2>2</a></span>
<span class=normal><a href=#__codelineno-3-3>3</a></span>
<span class=normal><a href=#__codelineno-3-4>4</a></span>
<span class=normal><a href=#__codelineno-3-5>5</a></span>
<span class=normal><a href=#__codelineno-3-6>6</a></span>
<span class=normal><a href=#__codelineno-3-7>7</a></span>
<span class=normal><a href=#__codelineno-3-8>8</a></span>
<span class=normal><a href=#__codelineno-3-9>9</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-3-1><a id=__codelineno-3-1 name=__codelineno-3-1></a><span class=n>WGuid</span><span class=w> </span><span class=n>id1</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>WGuid</span><span class=p>.</span><span class=n>NewGuid</span><span class=p>();</span>
</span><span id=__span-3-2><a id=__codelineno-3-2 name=__codelineno-3-2></a><span class=n>WGuid</span><span class=w> </span><span class=n>id2</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>id1</span><span class=p>;</span>
</span><span id=__span-3-3><a id=__codelineno-3-3 name=__codelineno-3-3></a>
</span><span id=__span-3-4><a id=__codelineno-3-4 name=__codelineno-3-4></a><span class=c1>// Implements IEquatable&lt;WGuid&gt;</span>
</span><span id=__span-3-5><a id=__codelineno-3-5 name=__codelineno-3-5></a><span class=kt>bool</span><span class=w> </span><span class=n>equal</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>id1</span><span class=p>.</span><span class=n>Equals</span><span class=p>(</span><span class=n>id2</span><span class=p>);</span><span class=w>  </span><span class=c1>// true</span>
</span><span id=__span-3-6><a id=__codelineno-3-6 name=__codelineno-3-6></a><span class=kt>bool</span><span class=w> </span><span class=n>opEqual</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>id1</span><span class=w> </span><span class=o>==</span><span class=w> </span><span class=n>id2</span><span class=p>;</span><span class=w>     </span><span class=c1>// true</span>
</span><span id=__span-3-7><a id=__codelineno-3-7 name=__codelineno-3-7></a>
</span><span id=__span-3-8><a id=__codelineno-3-8 name=__codelineno-3-8></a><span class=c1>// Implements IComparable&lt;WGuid&gt;</span>
</span><span id=__span-3-9><a id=__codelineno-3-9 name=__codelineno-3-9></a><span class=kt>int</span><span class=w> </span><span class=n>comparison</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>id1</span><span class=p>.</span><span class=n>CompareTo</span><span class=p>(</span><span class=n>id2</span><span class=p>);</span><span class=w>  </span><span class=c1>// 0</span>
</span></code></pre></div></td></tr></table></div> <hr> <h3 id=serialization-support>Serialization Support<a class=headerlink href=#serialization-support title="Permanent link">&para;</a></h3> <ul> <li><strong>Unity:</strong> Serialized as two <code>long</code> fields</li> <li><strong>JSON:</strong> Serialized as GUID string</li> <li><strong>Protobuf:</strong> Serialized as two <code>long</code> fields</li> </ul> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-4-1>1</a></span>
<span class=normal><a href=#__codelineno-4-2>2</a></span>
<span class=normal><a href=#__codelineno-4-3>3</a></span>
<span class=normal><a href=#__codelineno-4-4>4</a></span>
<span class=normal><a href=#__codelineno-4-5>5</a></span>
<span class=normal><a href=#__codelineno-4-6>6</a></span>
<span class=normal><a href=#__codelineno-4-7>7</a></span>
<span class=normal><a href=#__codelineno-4-8>8</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-4-1><a id=__codelineno-4-1 name=__codelineno-4-1></a><span class=k>using</span><span class=w> </span><span class=nn>ProtoBuf</span><span class=p>;</span>
</span><span id=__span-4-2><a id=__codelineno-4-2 name=__codelineno-4-2></a>
</span><span id=__span-4-3><a id=__codelineno-4-3 name=__codelineno-4-3></a><span class=na>[ProtoContract]</span>
</span><span id=__span-4-4><a id=__codelineno-4-4 name=__codelineno-4-4></a><span class=k>public</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>SaveData</span>
</span><span id=__span-4-5><a id=__codelineno-4-5 name=__codelineno-4-5></a><span class=p>{</span>
</span><span id=__span-4-6><a id=__codelineno-4-6 name=__codelineno-4-6></a><span class=w>    </span><span class=na>[ProtoMember(1)]</span><span class=w> </span><span class=k>public</span><span class=w> </span><span class=n>WGuid</span><span class=w> </span><span class=n>playerId</span><span class=p>;</span>
</span><span id=__span-4-7><a id=__codelineno-4-7 name=__codelineno-4-7></a><span class=w>    </span><span class=na>[ProtoMember(2)]</span><span class=w> </span><span class=k>public</span><span class=w> </span><span class=n>WGuid</span><span class=w> </span><span class=n>sessionId</span><span class=p>;</span>
</span><span id=__span-4-8><a id=__codelineno-4-8 name=__codelineno-4-8></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <hr> <h2 id=serializabledictionary>SerializableDictionary<a class=headerlink href=#serializabledictionary title="Permanent link">&para;</a></h2> <p>Unity-friendly dictionary with synchronized key/value arrays and custom drawer.</p> <h3 id=why-serializabledictionary>Why SerializableDictionary?<a class=headerlink href=#why-serializabledictionary title="Permanent link">&para;</a></h3> <ul> <li><strong>Problem:</strong> Unity doesn't serialize <code>Dictionary&lt;TKey, TValue&gt;</code></li> <li><strong>Solution:</strong> <code>SerializableDictionary&lt;TKey, TValue&gt;</code> maintains synchronized arrays for Unity serialization and a runtime dictionary for fast lookups</li> </ul> <hr> <h3 id=basic-usage_1>Basic Usage<a class=headerlink href=#basic-usage_1 title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-5-1> 1</a></span>
<span class=normal><a href=#__codelineno-5-2> 2</a></span>
<span class=normal><a href=#__codelineno-5-3> 3</a></span>
<span class=normal><a href=#__codelineno-5-4> 4</a></span>
<span class=normal><a href=#__codelineno-5-5> 5</a></span>
<span class=normal><a href=#__codelineno-5-6> 6</a></span>
<span class=normal><a href=#__codelineno-5-7> 7</a></span>
<span class=normal><a href=#__codelineno-5-8> 8</a></span>
<span class=normal><a href=#__codelineno-5-9> 9</a></span>
<span class=normal><a href=#__codelineno-5-10>10</a></span>
<span class=normal><a href=#__codelineno-5-11>11</a></span>
<span class=normal><a href=#__codelineno-5-12>12</a></span>
<span class=normal><a href=#__codelineno-5-13>13</a></span>
<span class=normal><a href=#__codelineno-5-14>14</a></span>
<span class=normal><a href=#__codelineno-5-15>15</a></span>
<span class=normal><a href=#__codelineno-5-16>16</a></span>
<span class=normal><a href=#__codelineno-5-17>17</a></span>
<span class=normal><a href=#__codelineno-5-18>18</a></span>
<span class=normal><a href=#__codelineno-5-19>19</a></span>
<span class=normal><a href=#__codelineno-5-20>20</a></span>
<span class=normal><a href=#__codelineno-5-21>21</a></span>
<span class=normal><a href=#__codelineno-5-22>22</a></span>
<span class=normal><a href=#__codelineno-5-23>23</a></span>
<span class=normal><a href=#__codelineno-5-24>24</a></span>
<span class=normal><a href=#__codelineno-5-25>25</a></span>
<span class=normal><a href=#__codelineno-5-26>26</a></span>
<span class=normal><a href=#__codelineno-5-27>27</a></span>
<span class=normal><a href=#__codelineno-5-28>28</a></span>
<span class=normal><a href=#__codelineno-5-29>29</a></span>
<span class=normal><a href=#__codelineno-5-30>30</a></span>
<span class=normal><a href=#__codelineno-5-31>31</a></span>
<span class=normal><a href=#__codelineno-5-32>32</a></span>
<span class=normal><a href=#__codelineno-5-33>33</a></span>
<span class=normal><a href=#__codelineno-5-34>34</a></span>
<span class=normal><a href=#__codelineno-5-35>35</a></span>
<span class=normal><a href=#__codelineno-5-36>36</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-5-1><a id=__codelineno-5-1 name=__codelineno-5-1></a><span class=k>using</span><span class=w> </span><span class=nn>UnityEngine</span><span class=p>;</span>
</span><span id=__span-5-2><a id=__codelineno-5-2 name=__codelineno-5-2></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.DataStructure.Adapters</span><span class=p>;</span>
</span><span id=__span-5-3><a id=__codelineno-5-3 name=__codelineno-5-3></a>
</span><span id=__span-5-4><a id=__codelineno-5-4 name=__codelineno-5-4></a><span class=k>public</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>PrefabRegistry</span><span class=w> </span><span class=p>:</span><span class=w> </span><span class=n>MonoBehaviour</span>
</span><span id=__span-5-5><a id=__codelineno-5-5 name=__codelineno-5-5></a><span class=p>{</span>
</span><span id=__span-5-6><a id=__codelineno-5-6 name=__codelineno-5-6></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>GameObject</span><span class=w> </span><span class=n>enemyPrefab</span><span class=p>;</span>
</span><span id=__span-5-7><a id=__codelineno-5-7 name=__codelineno-5-7></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>GameObject</span><span class=w> </span><span class=n>playerPrefab</span><span class=p>;</span>
</span><span id=__span-5-8><a id=__codelineno-5-8 name=__codelineno-5-8></a>
</span><span id=__span-5-9><a id=__codelineno-5-9 name=__codelineno-5-9></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>SerializableDictionary</span><span class=o>&lt;</span><span class=kt>string</span><span class=p>,</span><span class=w> </span><span class=n>GameObject</span><span class=o>&gt;</span><span class=w> </span><span class=n>prefabs</span><span class=p>;</span>
</span><span id=__span-5-10><a id=__codelineno-5-10 name=__codelineno-5-10></a>
</span><span id=__span-5-11><a id=__codelineno-5-11 name=__codelineno-5-11></a><span class=w>    </span><span class=k>private</span><span class=w> </span><span class=k>void</span><span class=w> </span><span class=nf>Start</span><span class=p>()</span>
</span><span id=__span-5-12><a id=__codelineno-5-12 name=__codelineno-5-12></a><span class=w>    </span><span class=p>{</span>
</span><span id=__span-5-13><a id=__codelineno-5-13 name=__codelineno-5-13></a><span class=w>        </span><span class=c1>// Access entries</span>
</span><span id=__span-5-14><a id=__codelineno-5-14 name=__codelineno-5-14></a><span class=w>        </span><span class=k>if</span><span class=w> </span><span class=p>(</span><span class=n>prefabs</span><span class=p>.</span><span class=n>TryGetValue</span><span class=p>(</span><span class=s>&quot;Enemy&quot;</span><span class=p>,</span><span class=w> </span><span class=k>out</span><span class=w> </span><span class=n>GameObject</span><span class=w> </span><span class=n>prefab</span><span class=p>))</span>
</span><span id=__span-5-15><a id=__codelineno-5-15 name=__codelineno-5-15></a><span class=w>        </span><span class=p>{</span>
</span><span id=__span-5-16><a id=__codelineno-5-16 name=__codelineno-5-16></a><span class=w>            </span><span class=n>Instantiate</span><span class=p>(</span><span class=n>prefab</span><span class=p>);</span>
</span><span id=__span-5-17><a id=__codelineno-5-17 name=__codelineno-5-17></a><span class=w>        </span><span class=p>}</span>
</span><span id=__span-5-18><a id=__codelineno-5-18 name=__codelineno-5-18></a>
</span><span id=__span-5-19><a id=__codelineno-5-19 name=__codelineno-5-19></a><span class=w>        </span><span class=c1>// Count</span>
</span><span id=__span-5-20><a id=__codelineno-5-20 name=__codelineno-5-20></a><span class=w>        </span><span class=n>Debug</span><span class=p>.</span><span class=n>Log</span><span class=p>(</span><span class=s>$&quot;Prefab count: {prefabs.Count}&quot;</span><span class=p>);</span>
</span><span id=__span-5-21><a id=__codelineno-5-21 name=__codelineno-5-21></a>
</span><span id=__span-5-22><a id=__codelineno-5-22 name=__codelineno-5-22></a><span class=w>        </span><span class=c1>// Iteration</span>
</span><span id=__span-5-23><a id=__codelineno-5-23 name=__codelineno-5-23></a><span class=w>        </span><span class=k>foreach</span><span class=w> </span><span class=p>(</span><span class=kt>var</span><span class=w> </span><span class=n>kvp</span><span class=w> </span><span class=k>in</span><span class=w> </span><span class=n>prefabs</span><span class=p>)</span>
</span><span id=__span-5-24><a id=__codelineno-5-24 name=__codelineno-5-24></a><span class=w>        </span><span class=p>{</span>
</span><span id=__span-5-25><a id=__codelineno-5-25 name=__codelineno-5-25></a><span class=w>            </span><span class=n>Debug</span><span class=p>.</span><span class=n>Log</span><span class=p>(</span><span class=s>$&quot;{kvp.Key}: {kvp.Value}&quot;</span><span class=p>);</span>
</span><span id=__span-5-26><a id=__codelineno-5-26 name=__codelineno-5-26></a><span class=w>        </span><span class=p>}</span>
</span><span id=__span-5-27><a id=__codelineno-5-27 name=__codelineno-5-27></a>
</span><span id=__span-5-28><a id=__codelineno-5-28 name=__codelineno-5-28></a><span class=w>        </span><span class=cm>/*</span>
</span><span id=__span-5-29><a id=__codelineno-5-29 name=__codelineno-5-29></a><span class=cm>            Add entries (or overwrite)</span>
</span><span id=__span-5-30><a id=__codelineno-5-30 name=__codelineno-5-30></a><span class=cm>            WARNING: This is just for demo purposes! SerializableDictionary is meant for editor-mode persistence.</span>
</span><span id=__span-5-31><a id=__codelineno-5-31 name=__codelineno-5-31></a><span class=cm>            Nothing stops you from changing this at runtime, but it will be lost on next playthrough.</span>
</span><span id=__span-5-32><a id=__codelineno-5-32 name=__codelineno-5-32></a><span class=cm>        */</span>
</span><span id=__span-5-33><a id=__codelineno-5-33 name=__codelineno-5-33></a><span class=w>        </span><span class=n>prefabs</span><span class=p>[</span><span class=s>&quot;Player&quot;</span><span class=p>]</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>playerPrefab</span><span class=p>;</span>
</span><span id=__span-5-34><a id=__codelineno-5-34 name=__codelineno-5-34></a><span class=w>        </span><span class=n>prefabs</span><span class=p>[</span><span class=s>&quot;Enemy&quot;</span><span class=p>]</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>enemyPrefab</span><span class=p>;</span>
</span><span id=__span-5-35><a id=__codelineno-5-35 name=__codelineno-5-35></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-5-36><a id=__codelineno-5-36 name=__codelineno-5-36></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <hr> <h3 id=inspector-features_1>Inspector Features<a class=headerlink href=#inspector-features_1 title="Permanent link">&para;</a></h3> <blockquote> <p><strong>Visual Reference</strong></p> <p><img alt="SerializableDictionary property drawer with add/remove controls" src=../../../images/serialization/serializable-dictionary-inspector.png></p> <p><em>Dictionary inspector showing key-value pairs with pagination and inline editing</em></p> </blockquote> <p><strong>Custom Drawer:</strong></p> <ul> <li>Key/value pair editing</li> <li>Add/Remove buttons</li> <li>Reorderable list</li> <li>Duplicate key detection (visual warning)</li> <li>Null value highlighting</li> <li>Pagination for large dictionaries</li> </ul> <p><img alt="Dictionary pagination controls" src=../../../images/serialization/serialized-dictionary-pagination.gif></p> <hr> <h3 id=dictionary-operations>Dictionary Operations<a class=headerlink href=#dictionary-operations title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-6-1> 1</a></span>
<span class=normal><a href=#__codelineno-6-2> 2</a></span>
<span class=normal><a href=#__codelineno-6-3> 3</a></span>
<span class=normal><a href=#__codelineno-6-4> 4</a></span>
<span class=normal><a href=#__codelineno-6-5> 5</a></span>
<span class=normal><a href=#__codelineno-6-6> 6</a></span>
<span class=normal><a href=#__codelineno-6-7> 7</a></span>
<span class=normal><a href=#__codelineno-6-8> 8</a></span>
<span class=normal><a href=#__codelineno-6-9> 9</a></span>
<span class=normal><a href=#__codelineno-6-10>10</a></span>
<span class=normal><a href=#__codelineno-6-11>11</a></span>
<span class=normal><a href=#__codelineno-6-12>12</a></span>
<span class=normal><a href=#__codelineno-6-13>13</a></span>
<span class=normal><a href=#__codelineno-6-14>14</a></span>
<span class=normal><a href=#__codelineno-6-15>15</a></span>
<span class=normal><a href=#__codelineno-6-16>16</a></span>
<span class=normal><a href=#__codelineno-6-17>17</a></span>
<span class=normal><a href=#__codelineno-6-18>18</a></span>
<span class=normal><a href=#__codelineno-6-19>19</a></span>
<span class=normal><a href=#__codelineno-6-20>20</a></span>
<span class=normal><a href=#__codelineno-6-21>21</a></span>
<span class=normal><a href=#__codelineno-6-22>22</a></span>
<span class=normal><a href=#__codelineno-6-23>23</a></span>
<span class=normal><a href=#__codelineno-6-24>24</a></span>
<span class=normal><a href=#__codelineno-6-25>25</a></span>
<span class=normal><a href=#__codelineno-6-26>26</a></span>
<span class=normal><a href=#__codelineno-6-27>27</a></span>
<span class=normal><a href=#__codelineno-6-28>28</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-6-1><a id=__codelineno-6-1 name=__codelineno-6-1></a><span class=c1>// Implements IDictionary&lt;TKey, TValue&gt; and IReadOnlyDictionary&lt;TKey, TValue&gt;</span>
</span><span id=__span-6-2><a id=__codelineno-6-2 name=__codelineno-6-2></a><span class=n>SerializableDictionary</span><span class=o>&lt;</span><span class=kt>int</span><span class=p>,</span><span class=w> </span><span class=kt>string</span><span class=o>&gt;</span><span class=w> </span><span class=n>dict</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>new</span><span class=p>();</span>
</span><span id=__span-6-3><a id=__codelineno-6-3 name=__codelineno-6-3></a>
</span><span id=__span-6-4><a id=__codelineno-6-4 name=__codelineno-6-4></a><span class=c1>// Add</span>
</span><span id=__span-6-5><a id=__codelineno-6-5 name=__codelineno-6-5></a><span class=n>dict</span><span class=p>.</span><span class=n>Add</span><span class=p>(</span><span class=mi>1</span><span class=p>,</span><span class=w> </span><span class=s>&quot;One&quot;</span><span class=p>);</span>
</span><span id=__span-6-6><a id=__codelineno-6-6 name=__codelineno-6-6></a><span class=n>dict</span><span class=p>[</span><span class=mi>2</span><span class=p>]</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=s>&quot;Two&quot;</span><span class=p>;</span>
</span><span id=__span-6-7><a id=__codelineno-6-7 name=__codelineno-6-7></a>
</span><span id=__span-6-8><a id=__codelineno-6-8 name=__codelineno-6-8></a><span class=c1>// Read</span>
</span><span id=__span-6-9><a id=__codelineno-6-9 name=__codelineno-6-9></a><span class=kt>string</span><span class=w> </span><span class=k>value</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>dict</span><span class=p>[</span><span class=mi>1</span><span class=p>];</span>
</span><span id=__span-6-10><a id=__codelineno-6-10 name=__codelineno-6-10></a><span class=kt>bool</span><span class=w> </span><span class=n>exists</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>dict</span><span class=p>.</span><span class=n>TryGetValue</span><span class=p>(</span><span class=mi>2</span><span class=p>,</span><span class=w> </span><span class=k>out</span><span class=w> </span><span class=kt>string</span><span class=w> </span><span class=n>val</span><span class=p>);</span>
</span><span id=__span-6-11><a id=__codelineno-6-11 name=__codelineno-6-11></a><span class=kt>bool</span><span class=w> </span><span class=n>contains</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>dict</span><span class=p>.</span><span class=n>ContainsKey</span><span class=p>(</span><span class=mi>1</span><span class=p>);</span>
</span><span id=__span-6-12><a id=__codelineno-6-12 name=__codelineno-6-12></a>
</span><span id=__span-6-13><a id=__codelineno-6-13 name=__codelineno-6-13></a><span class=c1>// Update</span>
</span><span id=__span-6-14><a id=__codelineno-6-14 name=__codelineno-6-14></a><span class=n>dict</span><span class=p>[</span><span class=mi>1</span><span class=p>]</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=s>&quot;First&quot;</span><span class=p>;</span>
</span><span id=__span-6-15><a id=__codelineno-6-15 name=__codelineno-6-15></a>
</span><span id=__span-6-16><a id=__codelineno-6-16 name=__codelineno-6-16></a><span class=c1>// Remove</span>
</span><span id=__span-6-17><a id=__codelineno-6-17 name=__codelineno-6-17></a><span class=n>dict</span><span class=p>.</span><span class=n>Remove</span><span class=p>(</span><span class=mi>1</span><span class=p>);</span>
</span><span id=__span-6-18><a id=__codelineno-6-18 name=__codelineno-6-18></a><span class=n>dict</span><span class=p>.</span><span class=n>Clear</span><span class=p>();</span>
</span><span id=__span-6-19><a id=__codelineno-6-19 name=__codelineno-6-19></a>
</span><span id=__span-6-20><a id=__codelineno-6-20 name=__codelineno-6-20></a><span class=c1>// Iteration</span>
</span><span id=__span-6-21><a id=__codelineno-6-21 name=__codelineno-6-21></a><span class=k>foreach</span><span class=w> </span><span class=p>(</span><span class=n>KeyValuePair</span><span class=o>&lt;</span><span class=kt>int</span><span class=p>,</span><span class=w> </span><span class=kt>string</span><span class=o>&gt;</span><span class=w> </span><span class=n>kvp</span><span class=w> </span><span class=k>in</span><span class=w> </span><span class=n>dict</span><span class=p>)</span>
</span><span id=__span-6-22><a id=__codelineno-6-22 name=__codelineno-6-22></a><span class=p>{</span>
</span><span id=__span-6-23><a id=__codelineno-6-23 name=__codelineno-6-23></a><span class=w>    </span><span class=n>Debug</span><span class=p>.</span><span class=n>Log</span><span class=p>(</span><span class=s>$&quot;{kvp.Key} = {kvp.Value}&quot;</span><span class=p>);</span>
</span><span id=__span-6-24><a id=__codelineno-6-24 name=__codelineno-6-24></a><span class=p>}</span>
</span><span id=__span-6-25><a id=__codelineno-6-25 name=__codelineno-6-25></a>
</span><span id=__span-6-26><a id=__codelineno-6-26 name=__codelineno-6-26></a><span class=c1>// Keys/Values collections</span>
</span><span id=__span-6-27><a id=__codelineno-6-27 name=__codelineno-6-27></a><span class=n>ICollection</span><span class=o>&lt;</span><span class=kt>int</span><span class=o>&gt;</span><span class=w> </span><span class=n>keys</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>dict</span><span class=p>.</span><span class=n>Keys</span><span class=p>;</span>
</span><span id=__span-6-28><a id=__codelineno-6-28 name=__codelineno-6-28></a><span class=n>ICollection</span><span class=o>&lt;</span><span class=kt>string</span><span class=o>&gt;</span><span class=w> </span><span class=n>values</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>dict</span><span class=p>.</span><span class=n>Values</span><span class=p>;</span>
</span></code></pre></div></td></tr></table></div> <hr> <h3 id=specialized-dictionaries>Specialized Dictionaries<a class=headerlink href=#specialized-dictionaries title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-7-1>1</a></span>
<span class=normal><a href=#__codelineno-7-2>2</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-7-1><a id=__codelineno-7-1 name=__codelineno-7-1></a><span class=c1>// Sorted dictionary (maintains key order)</span>
</span><span id=__span-7-2><a id=__codelineno-7-2 name=__codelineno-7-2></a><span class=k>public</span><span class=w> </span><span class=n>SerializableSortedDictionary</span><span class=o>&lt;</span><span class=kt>int</span><span class=p>,</span><span class=w> </span><span class=kt>string</span><span class=o>&gt;</span><span class=w> </span><span class=n>sortedDict</span><span class=p>;</span>
</span></code></pre></div></td></tr></table></div> <p><strong>Note:</strong> <code>SerializableSortedDictionary</code> uses <code>SortedDictionary&lt;TKey, TValue&gt;</code> internally for ordered keys.</p> <hr> <h3 id=serialization-support_1>Serialization Support<a class=headerlink href=#serialization-support_1 title="Permanent link">&para;</a></h3> <ul> <li><strong>Unity:</strong> Synchronized <code>_keys</code> and <code>_values</code> arrays</li> <li><strong>JSON:</strong> Standard dictionary format</li> <li><strong>Protobuf:</strong> Supported via surrogates</li> </ul> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-8-1>1</a></span>
<span class=normal><a href=#__codelineno-8-2>2</a></span>
<span class=normal><a href=#__codelineno-8-3>3</a></span>
<span class=normal><a href=#__codelineno-8-4>4</a></span>
<span class=normal><a href=#__codelineno-8-5>5</a></span>
<span class=normal><a href=#__codelineno-8-6>6</a></span>
<span class=normal><a href=#__codelineno-8-7>7</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-8-1><a id=__codelineno-8-1 name=__codelineno-8-1></a><span class=c1>// JSON example</span>
</span><span id=__span-8-2><a id=__codelineno-8-2 name=__codelineno-8-2></a><span class=p>{</span>
</span><span id=__span-8-3><a id=__codelineno-8-3 name=__codelineno-8-3></a><span class=w>    </span><span class=s>&quot;prefabs&quot;</span><span class=p>:</span><span class=w> </span><span class=p>{</span>
</span><span id=__span-8-4><a id=__codelineno-8-4 name=__codelineno-8-4></a><span class=w>        </span><span class=s>&quot;Enemy&quot;</span><span class=p>:</span><span class=w> </span><span class=p>{</span><span class=w> </span><span class=s>&quot;instanceId&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>12345</span><span class=w> </span><span class=p>},</span>
</span><span id=__span-8-5><a id=__codelineno-8-5 name=__codelineno-8-5></a><span class=w>        </span><span class=s>&quot;Player&quot;</span><span class=p>:</span><span class=w> </span><span class=p>{</span><span class=w> </span><span class=s>&quot;instanceId&quot;</span><span class=p>:</span><span class=w> </span><span class=mi>67890</span><span class=w> </span><span class=p>}</span>
</span><span id=__span-8-6><a id=__codelineno-8-6 name=__codelineno-8-6></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-8-7><a id=__codelineno-8-7 name=__codelineno-8-7></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <hr> <p><a id=serializablehashset--serializablesortedset></a> <a id=serializablehashset-serializablesortedset></a></p> <h2 id=serializablehashset-serializablesortedset>SerializableHashSet &amp; SerializableSortedSet<a class=headerlink href=#serializablehashset-serializablesortedset title="Permanent link">&para;</a></h2> <p>Unity-friendly set collections with duplicate detection and custom drawers.</p> <h3 id=why-serializable-sets>Why Serializable Sets?<a class=headerlink href=#why-serializable-sets title="Permanent link">&para;</a></h3> <ul> <li><strong>Problem:</strong> Unity doesn't serialize <code>HashSet&lt;T&gt;</code> or <code>SortedSet&lt;T&gt;</code></li> <li><strong>Solution:</strong> <code>SerializableHashSet&lt;T&gt;</code> and <code>SerializableSortedSet&lt;T&gt;</code> maintain a serialized array and runtime set for fast lookups</li> </ul> <hr> <h3 id=basic-usage_2>Basic Usage<a class=headerlink href=#basic-usage_2 title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-9-1> 1</a></span>
<span class=normal><a href=#__codelineno-9-2> 2</a></span>
<span class=normal><a href=#__codelineno-9-3> 3</a></span>
<span class=normal><a href=#__codelineno-9-4> 4</a></span>
<span class=normal><a href=#__codelineno-9-5> 5</a></span>
<span class=normal><a href=#__codelineno-9-6> 6</a></span>
<span class=normal><a href=#__codelineno-9-7> 7</a></span>
<span class=normal><a href=#__codelineno-9-8> 8</a></span>
<span class=normal><a href=#__codelineno-9-9> 9</a></span>
<span class=normal><a href=#__codelineno-9-10>10</a></span>
<span class=normal><a href=#__codelineno-9-11>11</a></span>
<span class=normal><a href=#__codelineno-9-12>12</a></span>
<span class=normal><a href=#__codelineno-9-13>13</a></span>
<span class=normal><a href=#__codelineno-9-14>14</a></span>
<span class=normal><a href=#__codelineno-9-15>15</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-9-1><a id=__codelineno-9-1 name=__codelineno-9-1></a><span class=k>using</span><span class=w> </span><span class=nn>UnityEngine</span><span class=p>;</span>
</span><span id=__span-9-2><a id=__codelineno-9-2 name=__codelineno-9-2></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.DataStructure.Adapters</span><span class=p>;</span>
</span><span id=__span-9-3><a id=__codelineno-9-3 name=__codelineno-9-3></a>
</span><span id=__span-9-4><a id=__codelineno-9-4 name=__codelineno-9-4></a><span class=k>public</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>UniqueItemTracker</span><span class=w> </span><span class=p>:</span><span class=w> </span><span class=n>MonoBehaviour</span>
</span><span id=__span-9-5><a id=__codelineno-9-5 name=__codelineno-9-5></a><span class=p>{</span>
</span><span id=__span-9-6><a id=__codelineno-9-6 name=__codelineno-9-6></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>SerializableHashSet</span><span class=o>&lt;</span><span class=kt>string</span><span class=o>&gt;</span><span class=w> </span><span class=n>collectedItems</span><span class=p>;</span>
</span><span id=__span-9-7><a id=__codelineno-9-7 name=__codelineno-9-7></a>
</span><span id=__span-9-8><a id=__codelineno-9-8 name=__codelineno-9-8></a><span class=w>    </span><span class=k>private</span><span class=w> </span><span class=k>void</span><span class=w> </span><span class=nf>Start</span><span class=p>()</span>
</span><span id=__span-9-9><a id=__codelineno-9-9 name=__codelineno-9-9></a><span class=w>    </span><span class=p>{</span>
</span><span id=__span-9-10><a id=__codelineno-9-10 name=__codelineno-9-10></a><span class=w>        </span><span class=k>foreach</span><span class=w> </span><span class=p>(</span><span class=kt>var</span><span class=w> </span><span class=n>item</span><span class=w> </span><span class=k>in</span><span class=w> </span><span class=n>collectedItems</span><span class=p>)</span>
</span><span id=__span-9-11><a id=__codelineno-9-11 name=__codelineno-9-11></a><span class=w>        </span><span class=p>{</span>
</span><span id=__span-9-12><a id=__codelineno-9-12 name=__codelineno-9-12></a><span class=w>            </span><span class=n>Debug</span><span class=p>.</span><span class=n>Log</span><span class=p>(</span><span class=s>$&quot;Found item: {item}&quot;</span><span class=p>);</span>
</span><span id=__span-9-13><a id=__codelineno-9-13 name=__codelineno-9-13></a><span class=w>        </span><span class=p>}</span>
</span><span id=__span-9-14><a id=__codelineno-9-14 name=__codelineno-9-14></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-9-15><a id=__codelineno-9-15 name=__codelineno-9-15></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <blockquote> <p><strong>Visual Reference</strong></p> <p><img alt="SerializableHashSet property drawer with duplicate detection" src=../../../images/serialization/serializable-hashset-inspector.png></p> <p><em>Set inspector with add/remove controls, duplicate highlighting, and pagination</em></p> </blockquote> <hr> <h3 id=inspector-features_2>Inspector Features<a class=headerlink href=#inspector-features_2 title="Permanent link">&para;</a></h3> <p><strong>Custom Drawer:</strong></p> <ul> <li>Reorderable list</li> <li>Add/Remove/Clear/Sort buttons</li> <li><strong>Duplicate detection</strong> with visual highlighting (shake animation + color)</li> <li><strong>Null entry highlighting</strong> (red background)</li> <li>Pagination for large sets</li> <li>Move Up/Down buttons</li> <li>Current selection badge for items on other pages</li> <li><strong>New Entry foldout</strong> to stage values before adding them to the runtime set (tune its animation via <strong>Project Settings ▸ Wallstop Studios ▸ Unity Helpers ▸ Set Foldouts</strong>)</li> </ul> <blockquote> <p><strong>Visual Reference</strong></p> <p><img alt="SerializableHashSet duplicate and null highlighting" src=../../../images/serialization/serializable-hashset-validation.png></p> <p><em>Visual feedback for duplicate entries (yellow shake) and null values (red background)</em> <img alt="Adding duplicate and seeing shake animation" src=../../../images/serialization/set-duplicates.gif></p> </blockquote> <hr> <h3 id=set-operations>Set Operations<a class=headerlink href=#set-operations title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-10-1> 1</a></span>
<span class=normal><a href=#__codelineno-10-2> 2</a></span>
<span class=normal><a href=#__codelineno-10-3> 3</a></span>
<span class=normal><a href=#__codelineno-10-4> 4</a></span>
<span class=normal><a href=#__codelineno-10-5> 5</a></span>
<span class=normal><a href=#__codelineno-10-6> 6</a></span>
<span class=normal><a href=#__codelineno-10-7> 7</a></span>
<span class=normal><a href=#__codelineno-10-8> 8</a></span>
<span class=normal><a href=#__codelineno-10-9> 9</a></span>
<span class=normal><a href=#__codelineno-10-10>10</a></span>
<span class=normal><a href=#__codelineno-10-11>11</a></span>
<span class=normal><a href=#__codelineno-10-12>12</a></span>
<span class=normal><a href=#__codelineno-10-13>13</a></span>
<span class=normal><a href=#__codelineno-10-14>14</a></span>
<span class=normal><a href=#__codelineno-10-15>15</a></span>
<span class=normal><a href=#__codelineno-10-16>16</a></span>
<span class=normal><a href=#__codelineno-10-17>17</a></span>
<span class=normal><a href=#__codelineno-10-18>18</a></span>
<span class=normal><a href=#__codelineno-10-19>19</a></span>
<span class=normal><a href=#__codelineno-10-20>20</a></span>
<span class=normal><a href=#__codelineno-10-21>21</a></span>
<span class=normal><a href=#__codelineno-10-22>22</a></span>
<span class=normal><a href=#__codelineno-10-23>23</a></span>
<span class=normal><a href=#__codelineno-10-24>24</a></span>
<span class=normal><a href=#__codelineno-10-25>25</a></span>
<span class=normal><a href=#__codelineno-10-26>26</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-10-1><a id=__codelineno-10-1 name=__codelineno-10-1></a><span class=c1>// Implements ISet&lt;T&gt; and IReadOnlyCollection&lt;T&gt;</span>
</span><span id=__span-10-2><a id=__codelineno-10-2 name=__codelineno-10-2></a><span class=n>SerializableHashSet</span><span class=o>&lt;</span><span class=kt>int</span><span class=o>&gt;</span><span class=w> </span><span class=k>set</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>new</span><span class=p>();</span>
</span><span id=__span-10-3><a id=__codelineno-10-3 name=__codelineno-10-3></a>
</span><span id=__span-10-4><a id=__codelineno-10-4 name=__codelineno-10-4></a><span class=c1>// Add (returns true if new)</span>
</span><span id=__span-10-5><a id=__codelineno-10-5 name=__codelineno-10-5></a><span class=kt>bool</span><span class=w> </span><span class=n>added</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>set</span><span class=p>.</span><span class=n>Add</span><span class=p>(</span><span class=mi>42</span><span class=p>);</span>
</span><span id=__span-10-6><a id=__codelineno-10-6 name=__codelineno-10-6></a>
</span><span id=__span-10-7><a id=__codelineno-10-7 name=__codelineno-10-7></a><span class=c1>// Read</span>
</span><span id=__span-10-8><a id=__codelineno-10-8 name=__codelineno-10-8></a><span class=kt>bool</span><span class=w> </span><span class=n>contains</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>set</span><span class=p>.</span><span class=n>Contains</span><span class=p>(</span><span class=mi>42</span><span class=p>);</span>
</span><span id=__span-10-9><a id=__codelineno-10-9 name=__codelineno-10-9></a><span class=kt>int</span><span class=w> </span><span class=n>count</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>set</span><span class=p>.</span><span class=n>Count</span><span class=p>;</span>
</span><span id=__span-10-10><a id=__codelineno-10-10 name=__codelineno-10-10></a>
</span><span id=__span-10-11><a id=__codelineno-10-11 name=__codelineno-10-11></a><span class=c1>// Remove</span>
</span><span id=__span-10-12><a id=__codelineno-10-12 name=__codelineno-10-12></a><span class=kt>bool</span><span class=w> </span><span class=n>removed</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>set</span><span class=p>.</span><span class=n>Remove</span><span class=p>(</span><span class=mi>42</span><span class=p>);</span>
</span><span id=__span-10-13><a id=__codelineno-10-13 name=__codelineno-10-13></a><span class=k>set</span><span class=p>.</span><span class=n>Clear</span><span class=p>();</span>
</span><span id=__span-10-14><a id=__codelineno-10-14 name=__codelineno-10-14></a>
</span><span id=__span-10-15><a id=__codelineno-10-15 name=__codelineno-10-15></a><span class=c1>// Set operations</span>
</span><span id=__span-10-16><a id=__codelineno-10-16 name=__codelineno-10-16></a><span class=n>HashSet</span><span class=o>&lt;</span><span class=kt>int</span><span class=o>&gt;</span><span class=w> </span><span class=n>other</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>new</span><span class=w> </span><span class=n>HashSet</span><span class=o>&lt;</span><span class=kt>int</span><span class=o>&gt;</span><span class=w> </span><span class=p>{</span><span class=w> </span><span class=mi>1</span><span class=p>,</span><span class=w> </span><span class=mi>2</span><span class=p>,</span><span class=w> </span><span class=mi>3</span><span class=w> </span><span class=p>};</span>
</span><span id=__span-10-17><a id=__codelineno-10-17 name=__codelineno-10-17></a><span class=k>set</span><span class=p>.</span><span class=n>UnionWith</span><span class=p>(</span><span class=n>other</span><span class=p>);</span><span class=w>        </span><span class=c1>// Add all from other</span>
</span><span id=__span-10-18><a id=__codelineno-10-18 name=__codelineno-10-18></a><span class=k>set</span><span class=p>.</span><span class=n>IntersectWith</span><span class=p>(</span><span class=n>other</span><span class=p>);</span><span class=w>    </span><span class=c1>// Keep only common elements</span>
</span><span id=__span-10-19><a id=__codelineno-10-19 name=__codelineno-10-19></a><span class=k>set</span><span class=p>.</span><span class=n>ExceptWith</span><span class=p>(</span><span class=n>other</span><span class=p>);</span><span class=w>       </span><span class=c1>// Remove elements in other</span>
</span><span id=__span-10-20><a id=__codelineno-10-20 name=__codelineno-10-20></a><span class=kt>bool</span><span class=w> </span><span class=n>overlaps</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>set</span><span class=p>.</span><span class=n>Overlaps</span><span class=p>(</span><span class=n>other</span><span class=p>);</span>
</span><span id=__span-10-21><a id=__codelineno-10-21 name=__codelineno-10-21></a>
</span><span id=__span-10-22><a id=__codelineno-10-22 name=__codelineno-10-22></a><span class=c1>// Iteration</span>
</span><span id=__span-10-23><a id=__codelineno-10-23 name=__codelineno-10-23></a><span class=k>foreach</span><span class=w> </span><span class=p>(</span><span class=kt>int</span><span class=w> </span><span class=n>item</span><span class=w> </span><span class=k>in</span><span class=w> </span><span class=k>set</span><span class=p>)</span>
</span><span id=__span-10-24><a id=__codelineno-10-24 name=__codelineno-10-24></a><span class=p>{</span>
</span><span id=__span-10-25><a id=__codelineno-10-25 name=__codelineno-10-25></a><span class=w>    </span><span class=n>Debug</span><span class=p>.</span><span class=n>Log</span><span class=p>(</span><span class=n>item</span><span class=p>);</span>
</span><span id=__span-10-26><a id=__codelineno-10-26 name=__codelineno-10-26></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <h3 id=new-entry-foldout>New Entry Foldout<a class=headerlink href=#new-entry-foldout title="Permanent link">&para;</a></h3> <p>Expandable "New Entry" controls let you configure the exact value that will be inserted, which is especially helpful for complex structs, managed references, or ScriptableObjects. The foldout supports the same field variety as the inline list and respects your duplicate/null validation. Animation for the New Entry foldout is governed by the <strong>Serializable Set Foldouts</strong> settings; adjust tweening and speed independently for <code>SerializableHashSet&lt;T&gt;</code> and <code>SerializableSortedSet&lt;T&gt;</code>.</p> <hr> <h3 id=foldout-defaults-overrides>Foldout Defaults &amp; Overrides<a class=headerlink href=#foldout-defaults-overrides title="Permanent link">&para;</a></h3> <p>By default, SerializableSet inspectors start collapsed until you open them. This baseline comes from <strong>Project Settings ▸ Wallstop Studios ▸ Unity Helpers</strong> via the <strong>Serializable Set Start Collapsed</strong> toggle (and the equivalent <strong>Serializable Dictionary Start Collapsed</strong> toggle for dictionaries). You can override the default per-field with <code>[WSerializableCollectionFoldout]</code>:</p> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-11-1>1</a></span>
<span class=normal><a href=#__codelineno-11-2>2</a></span>
<span class=normal><a href=#__codelineno-11-3>3</a></span>
<span class=normal><a href=#__codelineno-11-4>4</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-11-1><a id=__codelineno-11-1 name=__codelineno-11-1></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.Attributes</span><span class=p>;</span>
</span><span id=__span-11-2><a id=__codelineno-11-2 name=__codelineno-11-2></a>
</span><span id=__span-11-3><a id=__codelineno-11-3 name=__codelineno-11-3></a><span class=na>[WSerializableCollectionFoldout(WSerializableCollectionFoldoutBehavior.StartExpanded)]</span>
</span><span id=__span-11-4><a id=__codelineno-11-4 name=__codelineno-11-4></a><span class=k>public</span><span class=w> </span><span class=n>SerializableHashSet</span><span class=o>&lt;</span><span class=kt>string</span><span class=o>&gt;</span><span class=w> </span><span class=n>unlockedBadges</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>new</span><span class=p>();</span>
</span></code></pre></div></td></tr></table></div> <ul> <li><strong>Project setting</strong> establishes the initial state only.</li> <li><strong><code>[WSerializableCollectionFoldout]</code></strong> can request expanded or collapsed behavior for specific collections.</li> <li><strong>Explicit changes</strong> to <code>SerializedProperty.isExpanded</code> (scripts, custom inspectors, or tests) take ultimate precedence. The drawer now respects those manual decisions, so opting-in via code no longer gets undone by the attribute or the global default.</li> </ul> <p>The attribute applies to both <code>SerializableHashSet&lt;T&gt;</code>/<code>SerializableSortedSet&lt;T&gt;</code> and the dictionary equivalents, making it straightforward to mix project-wide defaults with per-field intentions.</p> <hr> <h3 id=sorted-sets>Sorted Sets<a class=headerlink href=#sorted-sets title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-12-1> 1</a></span>
<span class=normal><a href=#__codelineno-12-2> 2</a></span>
<span class=normal><a href=#__codelineno-12-3> 3</a></span>
<span class=normal><a href=#__codelineno-12-4> 4</a></span>
<span class=normal><a href=#__codelineno-12-5> 5</a></span>
<span class=normal><a href=#__codelineno-12-6> 6</a></span>
<span class=normal><a href=#__codelineno-12-7> 7</a></span>
<span class=normal><a href=#__codelineno-12-8> 8</a></span>
<span class=normal><a href=#__codelineno-12-9> 9</a></span>
<span class=normal><a href=#__codelineno-12-10>10</a></span>
<span class=normal><a href=#__codelineno-12-11>11</a></span>
<span class=normal><a href=#__codelineno-12-12>12</a></span>
<span class=normal><a href=#__codelineno-12-13>13</a></span>
<span class=normal><a href=#__codelineno-12-14>14</a></span>
<span class=normal><a href=#__codelineno-12-15>15</a></span>
<span class=normal><a href=#__codelineno-12-16>16</a></span>
<span class=normal><a href=#__codelineno-12-17>17</a></span>
<span class=normal><a href=#__codelineno-12-18>18</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-12-1><a id=__codelineno-12-1 name=__codelineno-12-1></a><span class=k>using</span><span class=w> </span><span class=nn>UnityEngine</span><span class=p>;</span>
</span><span id=__span-12-2><a id=__codelineno-12-2 name=__codelineno-12-2></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.Attributes</span><span class=p>;</span>
</span><span id=__span-12-3><a id=__codelineno-12-3 name=__codelineno-12-3></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.DataStructure.Adapters</span><span class=p>;</span>
</span><span id=__span-12-4><a id=__codelineno-12-4 name=__codelineno-12-4></a>
</span><span id=__span-12-5><a id=__codelineno-12-5 name=__codelineno-12-5></a><span class=k>public</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>ThresholdLogger</span><span class=w> </span><span class=p>:</span><span class=w> </span><span class=n>MonoBehaviour</span>
</span><span id=__span-12-6><a id=__codelineno-12-6 name=__codelineno-12-6></a><span class=p>{</span>
</span><span id=__span-12-7><a id=__codelineno-12-7 name=__codelineno-12-7></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>SerializableSortedSet</span><span class=o>&lt;</span><span class=kt>int</span><span class=o>&gt;</span><span class=w> </span><span class=n>scoreThresholds</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>new</span><span class=p>();</span>
</span><span id=__span-12-8><a id=__codelineno-12-8 name=__codelineno-12-8></a>
</span><span id=__span-12-9><a id=__codelineno-12-9 name=__codelineno-12-9></a><span class=w>    </span><span class=na>[WButton]</span>
</span><span id=__span-12-10><a id=__codelineno-12-10 name=__codelineno-12-10></a><span class=w>    </span><span class=k>private</span><span class=w> </span><span class=kt>string</span><span class=w> </span><span class=nf>LogThresholds</span><span class=p>()</span>
</span><span id=__span-12-11><a id=__codelineno-12-11 name=__codelineno-12-11></a><span class=w>    </span><span class=p>{</span>
</span><span id=__span-12-12><a id=__codelineno-12-12 name=__codelineno-12-12></a><span class=w>        </span><span class=k>foreach</span><span class=w> </span><span class=p>(</span><span class=kt>int</span><span class=w> </span><span class=n>threshold</span><span class=w> </span><span class=k>in</span><span class=w> </span><span class=n>scoreThresholds</span><span class=p>)</span>
</span><span id=__span-12-13><a id=__codelineno-12-13 name=__codelineno-12-13></a><span class=w>        </span><span class=p>{</span>
</span><span id=__span-12-14><a id=__codelineno-12-14 name=__codelineno-12-14></a><span class=w>            </span><span class=n>Debug</span><span class=p>.</span><span class=n>Log</span><span class=p>(</span><span class=n>threshold</span><span class=p>);</span>
</span><span id=__span-12-15><a id=__codelineno-12-15 name=__codelineno-12-15></a><span class=w>        </span><span class=p>}</span>
</span><span id=__span-12-16><a id=__codelineno-12-16 name=__codelineno-12-16></a><span class=w>        </span><span class=k>return</span><span class=w> </span><span class=s>$&quot;Logged {scoreThresholds.Count} thresholds&quot;</span><span class=p>;</span>
</span><span id=__span-12-17><a id=__codelineno-12-17 name=__codelineno-12-17></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-12-18><a id=__codelineno-12-18 name=__codelineno-12-18></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <p><img alt="SerializableSortedSet showing sorted numeric values" src=../../../images/serialization/serialized-sorted-set-inspector.gif></p> <hr> <h3 id=serialization-support_2>Serialization Support<a class=headerlink href=#serialization-support_2 title="Permanent link">&para;</a></h3> <ul> <li><strong>Unity:</strong> Serialized <code>_items</code> array</li> <li><strong>JSON:</strong> Array format</li> <li><strong>Protobuf:</strong> Supported via collection surrogates</li> </ul> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-13-1>1</a></span>
<span class=normal><a href=#__codelineno-13-2>2</a></span>
<span class=normal><a href=#__codelineno-13-3>3</a></span>
<span class=normal><a href=#__codelineno-13-4>4</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-13-1><a id=__codelineno-13-1 name=__codelineno-13-1></a><span class=c1>// JSON example</span>
</span><span id=__span-13-2><a id=__codelineno-13-2 name=__codelineno-13-2></a><span class=p>{</span>
</span><span id=__span-13-3><a id=__codelineno-13-3 name=__codelineno-13-3></a><span class=w>    </span><span class=s>&quot;collectedItems&quot;</span><span class=p>:</span><span class=w> </span><span class=p>[</span><span class=s>&quot;item_001&quot;</span><span class=p>,</span><span class=w> </span><span class=s>&quot;item_042&quot;</span><span class=p>,</span><span class=w> </span><span class=s>&quot;item_137&quot;</span><span class=p>]</span>
</span><span id=__span-13-4><a id=__codelineno-13-4 name=__codelineno-13-4></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <hr> <h2 id=serializabletype>SerializableType<a class=headerlink href=#serializabletype title="Permanent link">&para;</a></h2> <p>Unity-friendly type reference that survives refactoring and namespace changes.</p> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-14-1>1</a></span>
<span class=normal><a href=#__codelineno-14-2>2</a></span>
<span class=normal><a href=#__codelineno-14-3>3</a></span>
<span class=normal><a href=#__codelineno-14-4>4</a></span>
<span class=normal><a href=#__codelineno-14-5>5</a></span>
<span class=normal><a href=#__codelineno-14-6>6</a></span>
<span class=normal><a href=#__codelineno-14-7>7</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-14-1><a id=__codelineno-14-1 name=__codelineno-14-1></a><span class=k>using</span><span class=w> </span><span class=nn>UnityEngine</span><span class=p>;</span>
</span><span id=__span-14-2><a id=__codelineno-14-2 name=__codelineno-14-2></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.DataStructure.Adapters</span><span class=p>;</span>
</span><span id=__span-14-3><a id=__codelineno-14-3 name=__codelineno-14-3></a>
</span><span id=__span-14-4><a id=__codelineno-14-4 name=__codelineno-14-4></a><span class=k>public</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>SerializableTypeExample</span><span class=w> </span><span class=p>:</span><span class=w> </span><span class=n>MonoBehaviour</span>
</span><span id=__span-14-5><a id=__codelineno-14-5 name=__codelineno-14-5></a><span class=p>{</span>
</span><span id=__span-14-6><a id=__codelineno-14-6 name=__codelineno-14-6></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>SerializableType</span><span class=w> </span><span class=n>type</span><span class=p>;</span>
</span><span id=__span-14-7><a id=__codelineno-14-7 name=__codelineno-14-7></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <blockquote> <p><strong>Visual Reference</strong></p> <p><img alt="SerializableType property drawer with searchable type dropdown" src=../../../images/serialization/serializable-type-inspector.gif></p> <p><em>Type selection with searchable dropdown, namespace filtering, and validation</em></p> </blockquote> <h3 id=why-serializabletype>Why SerializableType?<a class=headerlink href=#why-serializabletype title="Permanent link">&para;</a></h3> <ul> <li><strong>Problem:</strong> Unity doesn't serialize <code>System.Type</code>, and type names break when refactoring</li> <li><strong>Solution:</strong> <code>SerializableType</code> stores assembly-qualified names with fallback resolution on rename/namespace changes</li> </ul> <hr> <h3 id=basic-usage_3>Basic Usage<a class=headerlink href=#basic-usage_3 title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-15-1> 1</a></span>
<span class=normal><a href=#__codelineno-15-2> 2</a></span>
<span class=normal><a href=#__codelineno-15-3> 3</a></span>
<span class=normal><a href=#__codelineno-15-4> 4</a></span>
<span class=normal><a href=#__codelineno-15-5> 5</a></span>
<span class=normal><a href=#__codelineno-15-6> 6</a></span>
<span class=normal><a href=#__codelineno-15-7> 7</a></span>
<span class=normal><a href=#__codelineno-15-8> 8</a></span>
<span class=normal><a href=#__codelineno-15-9> 9</a></span>
<span class=normal><a href=#__codelineno-15-10>10</a></span>
<span class=normal><a href=#__codelineno-15-11>11</a></span>
<span class=normal><a href=#__codelineno-15-12>12</a></span>
<span class=normal><a href=#__codelineno-15-13>13</a></span>
<span class=normal><a href=#__codelineno-15-14>14</a></span>
<span class=normal><a href=#__codelineno-15-15>15</a></span>
<span class=normal><a href=#__codelineno-15-16>16</a></span>
<span class=normal><a href=#__codelineno-15-17>17</a></span>
<span class=normal><a href=#__codelineno-15-18>18</a></span>
<span class=normal><a href=#__codelineno-15-19>19</a></span>
<span class=normal><a href=#__codelineno-15-20>20</a></span>
<span class=normal><a href=#__codelineno-15-21>21</a></span>
<span class=normal><a href=#__codelineno-15-22>22</a></span>
<span class=normal><a href=#__codelineno-15-23>23</a></span>
<span class=normal><a href=#__codelineno-15-24>24</a></span>
<span class=normal><a href=#__codelineno-15-25>25</a></span>
<span class=normal><a href=#__codelineno-15-26>26</a></span>
<span class=normal><a href=#__codelineno-15-27>27</a></span>
<span class=normal><a href=#__codelineno-15-28>28</a></span>
<span class=normal><a href=#__codelineno-15-29>29</a></span>
<span class=normal><a href=#__codelineno-15-30>30</a></span>
<span class=normal><a href=#__codelineno-15-31>31</a></span>
<span class=normal><a href=#__codelineno-15-32>32</a></span>
<span class=normal><a href=#__codelineno-15-33>33</a></span>
<span class=normal><a href=#__codelineno-15-34>34</a></span>
<span class=normal><a href=#__codelineno-15-35>35</a></span>
<span class=normal><a href=#__codelineno-15-36>36</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-15-1><a id=__codelineno-15-1 name=__codelineno-15-1></a><span class=k>using</span><span class=w> </span><span class=nn>System</span><span class=p>;</span>
</span><span id=__span-15-2><a id=__codelineno-15-2 name=__codelineno-15-2></a><span class=k>using</span><span class=w> </span><span class=nn>System.Collections.Generic</span><span class=p>;</span>
</span><span id=__span-15-3><a id=__codelineno-15-3 name=__codelineno-15-3></a><span class=k>using</span><span class=w> </span><span class=nn>System.Linq</span><span class=p>;</span>
</span><span id=__span-15-4><a id=__codelineno-15-4 name=__codelineno-15-4></a><span class=k>using</span><span class=w> </span><span class=nn>UnityEngine</span><span class=p>;</span>
</span><span id=__span-15-5><a id=__codelineno-15-5 name=__codelineno-15-5></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.Attributes</span><span class=p>;</span>
</span><span id=__span-15-6><a id=__codelineno-15-6 name=__codelineno-15-6></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.DataStructure.Adapters</span><span class=p>;</span>
</span><span id=__span-15-7><a id=__codelineno-15-7 name=__codelineno-15-7></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.Helper</span><span class=p>;</span>
</span><span id=__span-15-8><a id=__codelineno-15-8 name=__codelineno-15-8></a>
</span><span id=__span-15-9><a id=__codelineno-15-9 name=__codelineno-15-9></a><span class=k>public</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>BehaviorSpawner</span><span class=w> </span><span class=p>:</span><span class=w> </span><span class=n>MonoBehaviour</span>
</span><span id=__span-15-10><a id=__codelineno-15-10 name=__codelineno-15-10></a><span class=p>{</span>
</span><span id=__span-15-11><a id=__codelineno-15-11 name=__codelineno-15-11></a><span class=w>    </span><span class=na>[WValueDropDown(typeof(BehaviorSpawner), nameof(GetAllMonoBehaviourNames))]</span>
</span><span id=__span-15-12><a id=__codelineno-15-12 name=__codelineno-15-12></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>SerializableType</span><span class=w> </span><span class=n>behaviorType</span><span class=p>;</span>
</span><span id=__span-15-13><a id=__codelineno-15-13 name=__codelineno-15-13></a>
</span><span id=__span-15-14><a id=__codelineno-15-14 name=__codelineno-15-14></a><span class=w>    </span><span class=k>private</span><span class=w> </span><span class=k>void</span><span class=w> </span><span class=nf>SpawnBehavior</span><span class=p>()</span>
</span><span id=__span-15-15><a id=__codelineno-15-15 name=__codelineno-15-15></a><span class=w>    </span><span class=p>{</span>
</span><span id=__span-15-16><a id=__codelineno-15-16 name=__codelineno-15-16></a><span class=w>        </span><span class=k>if</span><span class=w> </span><span class=p>(</span><span class=n>behaviorType</span><span class=p>.</span><span class=n>IsEmpty</span><span class=p>)</span>
</span><span id=__span-15-17><a id=__codelineno-15-17 name=__codelineno-15-17></a><span class=w>        </span><span class=p>{</span>
</span><span id=__span-15-18><a id=__codelineno-15-18 name=__codelineno-15-18></a><span class=w>            </span><span class=n>Debug</span><span class=p>.</span><span class=n>LogWarning</span><span class=p>(</span><span class=s>&quot;No behavior type assigned!&quot;</span><span class=p>);</span>
</span><span id=__span-15-19><a id=__codelineno-15-19 name=__codelineno-15-19></a><span class=w>            </span><span class=k>return</span><span class=p>;</span>
</span><span id=__span-15-20><a id=__codelineno-15-20 name=__codelineno-15-20></a><span class=w>        </span><span class=p>}</span>
</span><span id=__span-15-21><a id=__codelineno-15-21 name=__codelineno-15-21></a>
</span><span id=__span-15-22><a id=__codelineno-15-22 name=__codelineno-15-22></a><span class=w>        </span><span class=n>Type</span><span class=w> </span><span class=n>type</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>behaviorType</span><span class=p>.</span><span class=n>Value</span><span class=p>;</span>
</span><span id=__span-15-23><a id=__codelineno-15-23 name=__codelineno-15-23></a><span class=w>        </span><span class=k>if</span><span class=w> </span><span class=p>(</span><span class=n>type</span><span class=w> </span><span class=o>!=</span><span class=w> </span><span class=k>null</span><span class=p>)</span>
</span><span id=__span-15-24><a id=__codelineno-15-24 name=__codelineno-15-24></a><span class=w>        </span><span class=p>{</span>
</span><span id=__span-15-25><a id=__codelineno-15-25 name=__codelineno-15-25></a><span class=w>            </span><span class=n>GameObject</span><span class=w> </span><span class=n>go</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>new</span><span class=w> </span><span class=n>GameObject</span><span class=p>(</span><span class=n>type</span><span class=p>.</span><span class=n>Name</span><span class=p>);</span>
</span><span id=__span-15-26><a id=__codelineno-15-26 name=__codelineno-15-26></a><span class=w>            </span><span class=n>go</span><span class=p>.</span><span class=n>AddComponent</span><span class=p>(</span><span class=n>type</span><span class=p>);</span>
</span><span id=__span-15-27><a id=__codelineno-15-27 name=__codelineno-15-27></a><span class=w>        </span><span class=p>}</span>
</span><span id=__span-15-28><a id=__codelineno-15-28 name=__codelineno-15-28></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-15-29><a id=__codelineno-15-29 name=__codelineno-15-29></a>
</span><span id=__span-15-30><a id=__codelineno-15-30 name=__codelineno-15-30></a><span class=w>    </span><span class=k>private</span><span class=w> </span><span class=k>static</span><span class=w> </span><span class=n>IEnumerable</span><span class=o>&lt;</span><span class=n>Type</span><span class=o>&gt;</span><span class=w> </span><span class=n>GetAllMonoBehaviourNames</span><span class=p>()</span>
</span><span id=__span-15-31><a id=__codelineno-15-31 name=__codelineno-15-31></a><span class=w>    </span><span class=p>{</span>
</span><span id=__span-15-32><a id=__codelineno-15-32 name=__codelineno-15-32></a><span class=w>        </span><span class=k>return</span><span class=w> </span><span class=n>ReflectionHelpers</span>
</span><span id=__span-15-33><a id=__codelineno-15-33 name=__codelineno-15-33></a><span class=w>            </span><span class=p>.</span><span class=n>GetAllLoadedTypes</span><span class=p>()</span>
</span><span id=__span-15-34><a id=__codelineno-15-34 name=__codelineno-15-34></a><span class=w>            </span><span class=p>.</span><span class=n>Where</span><span class=p>(</span><span class=n>type</span><span class=w> </span><span class=o>=&gt;</span><span class=w> </span><span class=k>typeof</span><span class=p>(</span><span class=n>MonoBehaviour</span><span class=p>).</span><span class=n>IsAssignableFrom</span><span class=p>(</span><span class=n>type</span><span class=p>)</span><span class=w> </span><span class=o>&amp;&amp;</span><span class=w> </span><span class=o>!</span><span class=n>type</span><span class=p>.</span><span class=n>IsAbstract</span><span class=p>);</span>
</span><span id=__span-15-35><a id=__codelineno-15-35 name=__codelineno-15-35></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-15-36><a id=__codelineno-15-36 name=__codelineno-15-36></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <p><img alt="SerializableType inspector with type browser and search" src=../../../images/serialization/custom-type-filtering.gif></p> <hr> <h3 id=inspector-features_3>Inspector Features<a class=headerlink href=#inspector-features_3 title="Permanent link">&para;</a></h3> <p><strong>Custom Drawer (Two-Line):</strong></p> <ul> <li><strong>Search row:</strong> Text field for filtering types</li> <li><strong>Popup row:</strong> Dropdown showing matched types</li> <li>Clear button to unset the type</li> <li>Pagination for large type catalogs</li> <li>Auto-complete suggestions</li> </ul> <hr> <h3 id=type-operations>Type Operations<a class=headerlink href=#type-operations title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-16-1> 1</a></span>
<span class=normal><a href=#__codelineno-16-2> 2</a></span>
<span class=normal><a href=#__codelineno-16-3> 3</a></span>
<span class=normal><a href=#__codelineno-16-4> 4</a></span>
<span class=normal><a href=#__codelineno-16-5> 5</a></span>
<span class=normal><a href=#__codelineno-16-6> 6</a></span>
<span class=normal><a href=#__codelineno-16-7> 7</a></span>
<span class=normal><a href=#__codelineno-16-8> 8</a></span>
<span class=normal><a href=#__codelineno-16-9> 9</a></span>
<span class=normal><a href=#__codelineno-16-10>10</a></span>
<span class=normal><a href=#__codelineno-16-11>11</a></span>
<span class=normal><a href=#__codelineno-16-12>12</a></span>
<span class=normal><a href=#__codelineno-16-13>13</a></span>
<span class=normal><a href=#__codelineno-16-14>14</a></span>
<span class=normal><a href=#__codelineno-16-15>15</a></span>
<span class=normal><a href=#__codelineno-16-16>16</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-16-1><a id=__codelineno-16-1 name=__codelineno-16-1></a><span class=c1>// Create</span>
</span><span id=__span-16-2><a id=__codelineno-16-2 name=__codelineno-16-2></a><span class=n>SerializableType</span><span class=w> </span><span class=n>typeRef</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>new</span><span class=w> </span><span class=n>SerializableType</span><span class=p>(</span><span class=k>typeof</span><span class=p>(</span><span class=n>PlayerController</span><span class=p>));</span>
</span><span id=__span-16-3><a id=__codelineno-16-3 name=__codelineno-16-3></a>
</span><span id=__span-16-4><a id=__codelineno-16-4 name=__codelineno-16-4></a><span class=c1>// Resolve</span>
</span><span id=__span-16-5><a id=__codelineno-16-5 name=__codelineno-16-5></a><span class=n>Type</span><span class=w> </span><span class=n>resolvedType</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>typeRef</span><span class=p>.</span><span class=n>Value</span><span class=p>;</span>
</span><span id=__span-16-6><a id=__codelineno-16-6 name=__codelineno-16-6></a><span class=k>if</span><span class=w> </span><span class=p>(</span><span class=n>resolvedType</span><span class=w> </span><span class=o>!=</span><span class=w> </span><span class=k>null</span><span class=p>)</span>
</span><span id=__span-16-7><a id=__codelineno-16-7 name=__codelineno-16-7></a><span class=p>{</span>
</span><span id=__span-16-8><a id=__codelineno-16-8 name=__codelineno-16-8></a><span class=w>    </span><span class=kt>object</span><span class=w> </span><span class=n>instance</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>Activator</span><span class=p>.</span><span class=n>CreateInstance</span><span class=p>(</span><span class=n>resolvedType</span><span class=p>);</span>
</span><span id=__span-16-9><a id=__codelineno-16-9 name=__codelineno-16-9></a><span class=p>}</span>
</span><span id=__span-16-10><a id=__codelineno-16-10 name=__codelineno-16-10></a>
</span><span id=__span-16-11><a id=__codelineno-16-11 name=__codelineno-16-11></a><span class=c1>// Check</span>
</span><span id=__span-16-12><a id=__codelineno-16-12 name=__codelineno-16-12></a><span class=kt>bool</span><span class=w> </span><span class=n>isEmpty</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>typeRef</span><span class=p>.</span><span class=n>IsEmpty</span><span class=p>;</span>
</span><span id=__span-16-13><a id=__codelineno-16-13 name=__codelineno-16-13></a><span class=kt>string</span><span class=w> </span><span class=n>displayName</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>typeRef</span><span class=p>.</span><span class=n>DisplayName</span><span class=p>;</span><span class=w>  </span><span class=c1>// User-friendly name</span>
</span><span id=__span-16-14><a id=__codelineno-16-14 name=__codelineno-16-14></a>
</span><span id=__span-16-15><a id=__codelineno-16-15 name=__codelineno-16-15></a><span class=c1>// Equality</span>
</span><span id=__span-16-16><a id=__codelineno-16-16 name=__codelineno-16-16></a><span class=kt>bool</span><span class=w> </span><span class=n>equal</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>typeRef</span><span class=p>.</span><span class=n>Equals</span><span class=p>(</span><span class=k>new</span><span class=w> </span><span class=n>SerializableType</span><span class=p>(</span><span class=k>typeof</span><span class=p>(</span><span class=n>PlayerController</span><span class=p>)));</span>
</span></code></pre></div></td></tr></table></div> <hr> <h3 id=refactoring-resilience>Refactoring Resilience<a class=headerlink href=#refactoring-resilience title="Permanent link">&para;</a></h3> <p><strong>Scenario:</strong> You rename <code>PlayerController</code> to <code>PlayerBehavior</code> or move it to a new namespace.</p> <ul> <li><strong>Standard Approach:</strong> Type reference breaks, data loss</li> <li><strong>SerializableType:</strong> Automatically resolves via assembly scanning and fallback matching</li> </ul> <p><strong>How it works:</strong></p> <ol> <li>Stores assembly-qualified name (e.g., <code>Namespace.PlayerController, Assembly-CSharp</code>)</li> <li>On deserialization, tries exact match first</li> <li>If the exact match fails, it scans assemblies for the best partial match</li> <li>Updates internal name if resolved to the new type</li> </ol> <hr> <h3 id=serialization-support_3>Serialization Support<a class=headerlink href=#serialization-support_3 title="Permanent link">&para;</a></h3> <ul> <li><strong>Unity:</strong> Stores assembly-qualified name string</li> <li><strong>JSON:</strong> Type name string with custom converter</li> <li><strong>Protobuf:</strong> Supported via string surrogates</li> </ul> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-17-1>1</a></span>
<span class=normal><a href=#__codelineno-17-2>2</a></span>
<span class=normal><a href=#__codelineno-17-3>3</a></span>
<span class=normal><a href=#__codelineno-17-4>4</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-17-1><a id=__codelineno-17-1 name=__codelineno-17-1></a><span class=c1>// JSON example</span>
</span><span id=__span-17-2><a id=__codelineno-17-2 name=__codelineno-17-2></a><span class=p>{</span>
</span><span id=__span-17-3><a id=__codelineno-17-3 name=__codelineno-17-3></a><span class=w>    </span><span class=s>&quot;behaviorType&quot;</span><span class=p>:</span><span class=w> </span><span class=s>&quot;MyNamespace.PlayerController, Assembly-CSharp&quot;</span>
</span><span id=__span-17-4><a id=__codelineno-17-4 name=__codelineno-17-4></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <hr> <h2 id=serializablenullable>SerializableNullable<a class=headerlink href=#serializablenullable title="Permanent link">&para;</a></h2> <p>Unity-friendly nullable value type wrapper.</p> <h3 id=why-serializablenullable>Why SerializableNullable?<a class=headerlink href=#why-serializablenullable title="Permanent link">&para;</a></h3> <ul> <li><strong>Problem:</strong> Unity doesn't serialize <code>Nullable&lt;T&gt;</code> (e.g., <code>int?</code>, <code>float?</code>)</li> <li><strong>Solution:</strong> <code>SerializableNullable&lt;T&gt;</code> wraps any value type with <code>HasValue</code> and <code>Value</code> properties</li> </ul> <hr> <h3 id=basic-usage_4>Basic Usage<a class=headerlink href=#basic-usage_4 title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-18-1> 1</a></span>
<span class=normal><a href=#__codelineno-18-2> 2</a></span>
<span class=normal><a href=#__codelineno-18-3> 3</a></span>
<span class=normal><a href=#__codelineno-18-4> 4</a></span>
<span class=normal><a href=#__codelineno-18-5> 5</a></span>
<span class=normal><a href=#__codelineno-18-6> 6</a></span>
<span class=normal><a href=#__codelineno-18-7> 7</a></span>
<span class=normal><a href=#__codelineno-18-8> 8</a></span>
<span class=normal><a href=#__codelineno-18-9> 9</a></span>
<span class=normal><a href=#__codelineno-18-10>10</a></span>
<span class=normal><a href=#__codelineno-18-11>11</a></span>
<span class=normal><a href=#__codelineno-18-12>12</a></span>
<span class=normal><a href=#__codelineno-18-13>13</a></span>
<span class=normal><a href=#__codelineno-18-14>14</a></span>
<span class=normal><a href=#__codelineno-18-15>15</a></span>
<span class=normal><a href=#__codelineno-18-16>16</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-18-1><a id=__codelineno-18-1 name=__codelineno-18-1></a><span class=k>using</span><span class=w> </span><span class=nn>UnityEngine</span><span class=p>;</span>
</span><span id=__span-18-2><a id=__codelineno-18-2 name=__codelineno-18-2></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.DataStructure.Adapters</span><span class=p>;</span>
</span><span id=__span-18-3><a id=__codelineno-18-3 name=__codelineno-18-3></a>
</span><span id=__span-18-4><a id=__codelineno-18-4 name=__codelineno-18-4></a><span class=k>public</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>BonusConfig</span><span class=w> </span><span class=p>:</span><span class=w> </span><span class=n>MonoBehaviour</span>
</span><span id=__span-18-5><a id=__codelineno-18-5 name=__codelineno-18-5></a><span class=p>{</span>
</span><span id=__span-18-6><a id=__codelineno-18-6 name=__codelineno-18-6></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>SerializableNullable</span><span class=o>&lt;</span><span class=kt>float</span><span class=o>&gt;</span><span class=w> </span><span class=n>criticalHitMultiplier</span><span class=p>;</span>
</span><span id=__span-18-7><a id=__codelineno-18-7 name=__codelineno-18-7></a>
</span><span id=__span-18-8><a id=__codelineno-18-8 name=__codelineno-18-8></a><span class=w>    </span><span class=k>private</span><span class=w> </span><span class=kt>float</span><span class=w> </span><span class=nf>GetDamage</span><span class=p>(</span><span class=kt>float</span><span class=w> </span><span class=n>baseDamage</span><span class=p>,</span><span class=w> </span><span class=kt>bool</span><span class=w> </span><span class=n>isCritical</span><span class=p>)</span>
</span><span id=__span-18-9><a id=__codelineno-18-9 name=__codelineno-18-9></a><span class=w>    </span><span class=p>{</span>
</span><span id=__span-18-10><a id=__codelineno-18-10 name=__codelineno-18-10></a><span class=w>        </span><span class=k>if</span><span class=w> </span><span class=p>(</span><span class=n>isCritical</span><span class=w> </span><span class=o>&amp;&amp;</span><span class=w> </span><span class=n>criticalHitMultiplier</span><span class=p>.</span><span class=n>HasValue</span><span class=p>)</span>
</span><span id=__span-18-11><a id=__codelineno-18-11 name=__codelineno-18-11></a><span class=w>        </span><span class=p>{</span>
</span><span id=__span-18-12><a id=__codelineno-18-12 name=__codelineno-18-12></a><span class=w>            </span><span class=k>return</span><span class=w> </span><span class=n>baseDamage</span><span class=w> </span><span class=o>*</span><span class=w> </span><span class=n>criticalHitMultiplier</span><span class=p>.</span><span class=n>Value</span><span class=p>;</span>
</span><span id=__span-18-13><a id=__codelineno-18-13 name=__codelineno-18-13></a><span class=w>        </span><span class=p>}</span>
</span><span id=__span-18-14><a id=__codelineno-18-14 name=__codelineno-18-14></a><span class=w>        </span><span class=k>return</span><span class=w> </span><span class=n>baseDamage</span><span class=p>;</span>
</span><span id=__span-18-15><a id=__codelineno-18-15 name=__codelineno-18-15></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-18-16><a id=__codelineno-18-16 name=__codelineno-18-16></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <p><img alt="SerializableNullable inspector with toggle and value field" src=../../../images/serialization/serializable-nullable-type-and-clear.gif></p> <hr> <h3 id=inspector-features_4>Inspector Features<a class=headerlink href=#inspector-features_4 title="Permanent link">&para;</a></h3> <p><strong>Custom Drawer:</strong></p> <ul> <li>Checkbox for <code>HasValue</code> state</li> <li>Inline value field (enabled when <code>HasValue == true</code>)</li> <li>Height adapts based on the nullable state</li> </ul> <hr> <h3 id=nullable-operations>Nullable Operations<a class=headerlink href=#nullable-operations title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-19-1> 1</a></span>
<span class=normal><a href=#__codelineno-19-2> 2</a></span>
<span class=normal><a href=#__codelineno-19-3> 3</a></span>
<span class=normal><a href=#__codelineno-19-4> 4</a></span>
<span class=normal><a href=#__codelineno-19-5> 5</a></span>
<span class=normal><a href=#__codelineno-19-6> 6</a></span>
<span class=normal><a href=#__codelineno-19-7> 7</a></span>
<span class=normal><a href=#__codelineno-19-8> 8</a></span>
<span class=normal><a href=#__codelineno-19-9> 9</a></span>
<span class=normal><a href=#__codelineno-19-10>10</a></span>
<span class=normal><a href=#__codelineno-19-11>11</a></span>
<span class=normal><a href=#__codelineno-19-12>12</a></span>
<span class=normal><a href=#__codelineno-19-13>13</a></span>
<span class=normal><a href=#__codelineno-19-14>14</a></span>
<span class=normal><a href=#__codelineno-19-15>15</a></span>
<span class=normal><a href=#__codelineno-19-16>16</a></span>
<span class=normal><a href=#__codelineno-19-17>17</a></span>
<span class=normal><a href=#__codelineno-19-18>18</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-19-1><a id=__codelineno-19-1 name=__codelineno-19-1></a><span class=c1>// Create with value</span>
</span><span id=__span-19-2><a id=__codelineno-19-2 name=__codelineno-19-2></a><span class=n>SerializableNullable</span><span class=o>&lt;</span><span class=kt>int</span><span class=o>&gt;</span><span class=w> </span><span class=n>nullableInt</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>new</span><span class=w> </span><span class=n>SerializableNullable</span><span class=o>&lt;</span><span class=kt>int</span><span class=o>&gt;</span><span class=p>(</span><span class=mi>42</span><span class=p>);</span>
</span><span id=__span-19-3><a id=__codelineno-19-3 name=__codelineno-19-3></a>
</span><span id=__span-19-4><a id=__codelineno-19-4 name=__codelineno-19-4></a><span class=c1>// Create without value (null)</span>
</span><span id=__span-19-5><a id=__codelineno-19-5 name=__codelineno-19-5></a><span class=n>SerializableNullable</span><span class=o>&lt;</span><span class=kt>int</span><span class=o>&gt;</span><span class=w> </span><span class=n>nullInt</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>new</span><span class=w> </span><span class=n>SerializableNullable</span><span class=o>&lt;</span><span class=kt>int</span><span class=o>&gt;</span><span class=p>();</span>
</span><span id=__span-19-6><a id=__codelineno-19-6 name=__codelineno-19-6></a>
</span><span id=__span-19-7><a id=__codelineno-19-7 name=__codelineno-19-7></a><span class=c1>// Check</span>
</span><span id=__span-19-8><a id=__codelineno-19-8 name=__codelineno-19-8></a><span class=k>if</span><span class=w> </span><span class=p>(</span><span class=n>nullableInt</span><span class=p>.</span><span class=n>HasValue</span><span class=p>)</span>
</span><span id=__span-19-9><a id=__codelineno-19-9 name=__codelineno-19-9></a><span class=p>{</span>
</span><span id=__span-19-10><a id=__codelineno-19-10 name=__codelineno-19-10></a><span class=w>    </span><span class=kt>int</span><span class=w> </span><span class=k>value</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>nullableInt</span><span class=p>.</span><span class=n>Value</span><span class=p>;</span>
</span><span id=__span-19-11><a id=__codelineno-19-11 name=__codelineno-19-11></a><span class=w>    </span><span class=n>Debug</span><span class=p>.</span><span class=n>Log</span><span class=p>(</span><span class=s>$&quot;Value: {value}&quot;</span><span class=p>);</span>
</span><span id=__span-19-12><a id=__codelineno-19-12 name=__codelineno-19-12></a><span class=p>}</span>
</span><span id=__span-19-13><a id=__codelineno-19-13 name=__codelineno-19-13></a>
</span><span id=__span-19-14><a id=__codelineno-19-14 name=__codelineno-19-14></a><span class=c1>// Implicit conversion from T</span>
</span><span id=__span-19-15><a id=__codelineno-19-15 name=__codelineno-19-15></a><span class=n>SerializableNullable</span><span class=o>&lt;</span><span class=kt>float</span><span class=o>&gt;</span><span class=w> </span><span class=n>nullableFloat</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=mf>3.14f</span><span class=p>;</span>
</span><span id=__span-19-16><a id=__codelineno-19-16 name=__codelineno-19-16></a>
</span><span id=__span-19-17><a id=__codelineno-19-17 name=__codelineno-19-17></a><span class=c1>// Conversion to Nullable&lt;T&gt;</span>
</span><span id=__span-19-18><a id=__codelineno-19-18 name=__codelineno-19-18></a><span class=kt>int?</span><span class=w> </span><span class=n>systemNullable</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>nullableInt</span><span class=p>.</span><span class=n>HasValue</span><span class=w> </span><span class=o>?</span><span class=w> </span><span class=n>nullableInt</span><span class=p>.</span><span class=n>Value</span><span class=w> </span><span class=p>:</span><span class=w> </span><span class=k>null</span><span class=p>;</span>
</span></code></pre></div></td></tr></table></div> <hr> <h3 id=use-cases>Use Cases<a class=headerlink href=#use-cases title="Permanent link">&para;</a></h3> <p><strong>Optional Configuration:</strong></p> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-20-1>1</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-20-1><a id=__codelineno-20-1 name=__codelineno-20-1></a><span class=k>public</span><span class=w> </span><span class=n>SerializableNullable</span><span class=o>&lt;</span><span class=kt>float</span><span class=o>&gt;</span><span class=w> </span><span class=n>overrideSpeed</span><span class=p>;</span><span class=w>  </span><span class=c1>// null = use default</span>
</span></code></pre></div></td></tr></table></div> <p><strong>Conditional Bonuses:</strong></p> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-21-1>1</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-21-1><a id=__codelineno-21-1 name=__codelineno-21-1></a><span class=k>public</span><span class=w> </span><span class=n>SerializableNullable</span><span class=o>&lt;</span><span class=kt>int</span><span class=o>&gt;</span><span class=w> </span><span class=n>bonusGold</span><span class=p>;</span><span class=w>  </span><span class=c1>// null = no bonus</span>
</span></code></pre></div></td></tr></table></div> <p><strong>Dynamic Properties:</strong></p> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-22-1>1</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-22-1><a id=__codelineno-22-1 name=__codelineno-22-1></a><span class=k>public</span><span class=w> </span><span class=n>SerializableNullable</span><span class=o>&lt;</span><span class=n>Color</span><span class=o>&gt;</span><span class=w> </span><span class=n>customColor</span><span class=p>;</span><span class=w>  </span><span class=c1>// null = use preset</span>
</span></code></pre></div></td></tr></table></div> <hr> <h3 id=serialization-support_4>Serialization Support<a class=headerlink href=#serialization-support_4 title="Permanent link">&para;</a></h3> <ul> <li><strong>Unity:</strong> Stores <code>_hasValue</code> bool and <code>_value</code> T fields</li> <li><strong>JSON:</strong> Standard nullable format</li> <li><strong>Protobuf:</strong> Supported via nullable surrogates</li> </ul> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-23-1>1</a></span>
<span class=normal><a href=#__codelineno-23-2>2</a></span>
<span class=normal><a href=#__codelineno-23-3>3</a></span>
<span class=normal><a href=#__codelineno-23-4>4</a></span>
<span class=normal><a href=#__codelineno-23-5>5</a></span>
<span class=normal><a href=#__codelineno-23-6>6</a></span>
<span class=normal><a href=#__codelineno-23-7>7</a></span>
<span class=normal><a href=#__codelineno-23-8>8</a></span>
<span class=normal><a href=#__codelineno-23-9>9</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-23-1><a id=__codelineno-23-1 name=__codelineno-23-1></a><span class=c1>// JSON example (has value)</span>
</span><span id=__span-23-2><a id=__codelineno-23-2 name=__codelineno-23-2></a><span class=p>{</span>
</span><span id=__span-23-3><a id=__codelineno-23-3 name=__codelineno-23-3></a><span class=w>    </span><span class=s>&quot;criticalHitMultiplier&quot;</span><span class=p>:</span><span class=w> </span><span class=mf>2.5</span>
</span><span id=__span-23-4><a id=__codelineno-23-4 name=__codelineno-23-4></a><span class=p>}</span>
</span><span id=__span-23-5><a id=__codelineno-23-5 name=__codelineno-23-5></a>
</span><span id=__span-23-6><a id=__codelineno-23-6 name=__codelineno-23-6></a><span class=c1>// JSON example (null)</span>
</span><span id=__span-23-7><a id=__codelineno-23-7 name=__codelineno-23-7></a><span class=p>{</span>
</span><span id=__span-23-8><a id=__codelineno-23-8 name=__codelineno-23-8></a><span class=w>    </span><span class=s>&quot;criticalHitMultiplier&quot;</span><span class=p>:</span><span class=w> </span><span class=k>null</span>
</span><span id=__span-23-9><a id=__codelineno-23-9 name=__codelineno-23-9></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <hr> <h2 id=best-practices>Best Practices<a class=headerlink href=#best-practices title="Permanent link">&para;</a></h2> <h3 id=1-choose-the-right-type>1. Choose the Right Type<a class=headerlink href=#1-choose-the-right-type title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-24-1> 1</a></span>
<span class=normal><a href=#__codelineno-24-2> 2</a></span>
<span class=normal><a href=#__codelineno-24-3> 3</a></span>
<span class=normal><a href=#__codelineno-24-4> 4</a></span>
<span class=normal><a href=#__codelineno-24-5> 5</a></span>
<span class=normal><a href=#__codelineno-24-6> 6</a></span>
<span class=normal><a href=#__codelineno-24-7> 7</a></span>
<span class=normal><a href=#__codelineno-24-8> 8</a></span>
<span class=normal><a href=#__codelineno-24-9> 9</a></span>
<span class=normal><a href=#__codelineno-24-10>10</a></span>
<span class=normal><a href=#__codelineno-24-11>11</a></span>
<span class=normal><a href=#__codelineno-24-12>12</a></span>
<span class=normal><a href=#__codelineno-24-13>13</a></span>
<span class=normal><a href=#__codelineno-24-14>14</a></span>
<span class=normal><a href=#__codelineno-24-15>15</a></span>
<span class=normal><a href=#__codelineno-24-16>16</a></span>
<span class=normal><a href=#__codelineno-24-17>17</a></span>
<span class=normal><a href=#__codelineno-24-18>18</a></span>
<span class=normal><a href=#__codelineno-24-19>19</a></span>
<span class=normal><a href=#__codelineno-24-20>20</a></span>
<span class=normal><a href=#__codelineno-24-21>21</a></span>
<span class=normal><a href=#__codelineno-24-22>22</a></span>
<span class=normal><a href=#__codelineno-24-23>23</a></span>
<span class=normal><a href=#__codelineno-24-24>24</a></span>
<span class=normal><a href=#__codelineno-24-25>25</a></span>
<span class=normal><a href=#__codelineno-24-26>26</a></span>
<span class=normal><a href=#__codelineno-24-27>27</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-24-1><a id=__codelineno-24-1 name=__codelineno-24-1></a><span class=c1>// ✅ GOOD: WGuid for entity IDs</span>
</span><span id=__span-24-2><a id=__codelineno-24-2 name=__codelineno-24-2></a><span class=k>public</span><span class=w> </span><span class=n>WGuid</span><span class=w> </span><span class=n>entityId</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>WGuid</span><span class=p>.</span><span class=n>NewGuid</span><span class=p>();</span>
</span><span id=__span-24-3><a id=__codelineno-24-3 name=__codelineno-24-3></a>
</span><span id=__span-24-4><a id=__codelineno-24-4 name=__codelineno-24-4></a><span class=c1>// ✅ GOOD: SerializableDictionary for key/value mappings</span>
</span><span id=__span-24-5><a id=__codelineno-24-5 name=__codelineno-24-5></a><span class=k>public</span><span class=w> </span><span class=n>SerializableDictionary</span><span class=o>&lt;</span><span class=kt>string</span><span class=p>,</span><span class=w> </span><span class=n>GameObject</span><span class=o>&gt;</span><span class=w> </span><span class=n>prefabRegistry</span><span class=p>;</span>
</span><span id=__span-24-6><a id=__codelineno-24-6 name=__codelineno-24-6></a>
</span><span id=__span-24-7><a id=__codelineno-24-7 name=__codelineno-24-7></a><span class=c1>// ✅ GOOD: SerializableHashSet for unique collections</span>
</span><span id=__span-24-8><a id=__codelineno-24-8 name=__codelineno-24-8></a><span class=k>public</span><span class=w> </span><span class=n>SerializableHashSet</span><span class=o>&lt;</span><span class=kt>string</span><span class=o>&gt;</span><span class=w> </span><span class=n>uniqueItemIds</span><span class=p>;</span>
</span><span id=__span-24-9><a id=__codelineno-24-9 name=__codelineno-24-9></a>
</span><span id=__span-24-10><a id=__codelineno-24-10 name=__codelineno-24-10></a><span class=c1>// ✅ GOOD: SerializableSortedSet for ordered unique values</span>
</span><span id=__span-24-11><a id=__codelineno-24-11 name=__codelineno-24-11></a><span class=k>public</span><span class=w> </span><span class=n>SerializableSortedSet</span><span class=o>&lt;</span><span class=kt>int</span><span class=o>&gt;</span><span class=w> </span><span class=n>scoreThresholds</span><span class=p>;</span>
</span><span id=__span-24-12><a id=__codelineno-24-12 name=__codelineno-24-12></a>
</span><span id=__span-24-13><a id=__codelineno-24-13 name=__codelineno-24-13></a><span class=c1>// ✅ GOOD: SerializableType for type references</span>
</span><span id=__span-24-14><a id=__codelineno-24-14 name=__codelineno-24-14></a><span class=k>public</span><span class=w> </span><span class=n>SerializableType</span><span class=w> </span><span class=n>behaviorType</span><span class=p>;</span>
</span><span id=__span-24-15><a id=__codelineno-24-15 name=__codelineno-24-15></a>
</span><span id=__span-24-16><a id=__codelineno-24-16 name=__codelineno-24-16></a><span class=c1>// ✅ GOOD: SerializableNullable for optional values</span>
</span><span id=__span-24-17><a id=__codelineno-24-17 name=__codelineno-24-17></a><span class=k>public</span><span class=w> </span><span class=n>SerializableNullable</span><span class=o>&lt;</span><span class=kt>float</span><span class=o>&gt;</span><span class=w> </span><span class=n>overrideSpeed</span><span class=p>;</span>
</span><span id=__span-24-18><a id=__codelineno-24-18 name=__codelineno-24-18></a>
</span><span id=__span-24-19><a id=__codelineno-24-19 name=__codelineno-24-19></a><span class=c1>// ❌ BAD: String-based GUID</span>
</span><span id=__span-24-20><a id=__codelineno-24-20 name=__codelineno-24-20></a><span class=k>public</span><span class=w> </span><span class=kt>string</span><span class=w> </span><span class=n>entityId</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>System</span><span class=p>.</span><span class=n>Guid</span><span class=p>.</span><span class=n>NewGuid</span><span class=p>().</span><span class=n>ToString</span><span class=p>();</span><span class=w>  </span><span class=c1>// Use WGuid!</span>
</span><span id=__span-24-21><a id=__codelineno-24-21 name=__codelineno-24-21></a>
</span><span id=__span-24-22><a id=__codelineno-24-22 name=__codelineno-24-22></a><span class=c1>// ❌ BAD: Parallel arrays instead of dictionary</span>
</span><span id=__span-24-23><a id=__codelineno-24-23 name=__codelineno-24-23></a><span class=k>public</span><span class=w> </span><span class=kt>string</span><span class=p>[]</span><span class=w> </span><span class=n>keys</span><span class=p>;</span>
</span><span id=__span-24-24><a id=__codelineno-24-24 name=__codelineno-24-24></a><span class=k>public</span><span class=w> </span><span class=n>GameObject</span><span class=p>[]</span><span class=w> </span><span class=n>values</span><span class=p>;</span><span class=w>  </span><span class=c1>// Use SerializableDictionary!</span>
</span><span id=__span-24-25><a id=__codelineno-24-25 name=__codelineno-24-25></a>
</span><span id=__span-24-26><a id=__codelineno-24-26 name=__codelineno-24-26></a><span class=c1>// ❌ BAD: List with manual duplicate checking</span>
</span><span id=__span-24-27><a id=__codelineno-24-27 name=__codelineno-24-27></a><span class=k>public</span><span class=w> </span><span class=n>List</span><span class=o>&lt;</span><span class=kt>string</span><span class=o>&gt;</span><span class=w> </span><span class=n>uniqueItems</span><span class=p>;</span><span class=w>  </span><span class=c1>// Use SerializableHashSet!</span>
</span></code></pre></div></td></tr></table></div> <hr> <h3 id=2-initialize-collections>2. Initialize Collections<a class=headerlink href=#2-initialize-collections title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-25-1> 1</a></span>
<span class=normal><a href=#__codelineno-25-2> 2</a></span>
<span class=normal><a href=#__codelineno-25-3> 3</a></span>
<span class=normal><a href=#__codelineno-25-4> 4</a></span>
<span class=normal><a href=#__codelineno-25-5> 5</a></span>
<span class=normal><a href=#__codelineno-25-6> 6</a></span>
<span class=normal><a href=#__codelineno-25-7> 7</a></span>
<span class=normal><a href=#__codelineno-25-8> 8</a></span>
<span class=normal><a href=#__codelineno-25-9> 9</a></span>
<span class=normal><a href=#__codelineno-25-10>10</a></span>
<span class=normal><a href=#__codelineno-25-11>11</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-25-1><a id=__codelineno-25-1 name=__codelineno-25-1></a><span class=c1>// ✅ GOOD: Initialize in field declaration</span>
</span><span id=__span-25-2><a id=__codelineno-25-2 name=__codelineno-25-2></a><span class=k>public</span><span class=w> </span><span class=n>SerializableDictionary</span><span class=o>&lt;</span><span class=kt>string</span><span class=p>,</span><span class=w> </span><span class=kt>int</span><span class=o>&gt;</span><span class=w> </span><span class=n>scores</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>new</span><span class=p>();</span>
</span><span id=__span-25-3><a id=__codelineno-25-3 name=__codelineno-25-3></a><span class=k>public</span><span class=w> </span><span class=n>SerializableHashSet</span><span class=o>&lt;</span><span class=kt>string</span><span class=o>&gt;</span><span class=w> </span><span class=n>tags</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>new</span><span class=p>();</span>
</span><span id=__span-25-4><a id=__codelineno-25-4 name=__codelineno-25-4></a>
</span><span id=__span-25-5><a id=__codelineno-25-5 name=__codelineno-25-5></a><span class=c1>// ❌ BAD: Null collections (NullReferenceException!)</span>
</span><span id=__span-25-6><a id=__codelineno-25-6 name=__codelineno-25-6></a><span class=k>public</span><span class=w> </span><span class=n>SerializableDictionary</span><span class=o>&lt;</span><span class=kt>string</span><span class=p>,</span><span class=w> </span><span class=kt>int</span><span class=o>&gt;</span><span class=w> </span><span class=n>scores</span><span class=p>;</span><span class=w>  </span><span class=c1>// null!</span>
</span><span id=__span-25-7><a id=__codelineno-25-7 name=__codelineno-25-7></a>
</span><span id=__span-25-8><a id=__codelineno-25-8 name=__codelineno-25-8></a><span class=k>private</span><span class=w> </span><span class=k>void</span><span class=w> </span><span class=nf>Start</span><span class=p>()</span>
</span><span id=__span-25-9><a id=__codelineno-25-9 name=__codelineno-25-9></a><span class=p>{</span>
</span><span id=__span-25-10><a id=__codelineno-25-10 name=__codelineno-25-10></a><span class=w>    </span><span class=n>scores</span><span class=p>.</span><span class=n>Add</span><span class=p>(</span><span class=s>&quot;player&quot;</span><span class=p>,</span><span class=w> </span><span class=mi>100</span><span class=p>);</span><span class=w>  </span><span class=c1>// Crash!</span>
</span><span id=__span-25-11><a id=__codelineno-25-11 name=__codelineno-25-11></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <hr> <h3 id=3-use-sorted-variants-for-ordered-data>3. Use Sorted Variants for Ordered Data<a class=headerlink href=#3-use-sorted-variants-for-ordered-data title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-26-1>1</a></span>
<span class=normal><a href=#__codelineno-26-2>2</a></span>
<span class=normal><a href=#__codelineno-26-3>3</a></span>
<span class=normal><a href=#__codelineno-26-4>4</a></span>
<span class=normal><a href=#__codelineno-26-5>5</a></span>
<span class=normal><a href=#__codelineno-26-6>6</a></span>
<span class=normal><a href=#__codelineno-26-7>7</a></span>
<span class=normal><a href=#__codelineno-26-8>8</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-26-1><a id=__codelineno-26-1 name=__codelineno-26-1></a><span class=c1>// ✅ GOOD: SortedSet for ordered priorities</span>
</span><span id=__span-26-2><a id=__codelineno-26-2 name=__codelineno-26-2></a><span class=k>public</span><span class=w> </span><span class=n>SerializableSortedSet</span><span class=o>&lt;</span><span class=kt>int</span><span class=o>&gt;</span><span class=w> </span><span class=n>unlockLevels</span><span class=p>;</span>
</span><span id=__span-26-3><a id=__codelineno-26-3 name=__codelineno-26-3></a>
</span><span id=__span-26-4><a id=__codelineno-26-4 name=__codelineno-26-4></a><span class=c1>// ✅ GOOD: SortedDictionary for ordered display</span>
</span><span id=__span-26-5><a id=__codelineno-26-5 name=__codelineno-26-5></a><span class=k>public</span><span class=w> </span><span class=n>SerializableSortedDictionary</span><span class=o>&lt;</span><span class=kt>string</span><span class=p>,</span><span class=w> </span><span class=kt>string</span><span class=o>&gt;</span><span class=w> </span><span class=n>alphabeticalNames</span><span class=p>;</span>
</span><span id=__span-26-6><a id=__codelineno-26-6 name=__codelineno-26-6></a>
</span><span id=__span-26-7><a id=__codelineno-26-7 name=__codelineno-26-7></a><span class=c1>// ❌ BAD: HashSet for ordered data (no guaranteed order!)</span>
</span><span id=__span-26-8><a id=__codelineno-26-8 name=__codelineno-26-8></a><span class=k>public</span><span class=w> </span><span class=n>SerializableHashSet</span><span class=o>&lt;</span><span class=kt>int</span><span class=o>&gt;</span><span class=w> </span><span class=n>unlockLevels</span><span class=p>;</span><span class=w>  </span><span class=c1>// Order is random!</span>
</span></code></pre></div></td></tr></table></div> <hr> <h3 id=4-handle-wguid-generation-carefully>4. Handle WGuid Generation Carefully<a class=headerlink href=#4-handle-wguid-generation-carefully title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-27-1> 1</a></span>
<span class=normal><a href=#__codelineno-27-2> 2</a></span>
<span class=normal><a href=#__codelineno-27-3> 3</a></span>
<span class=normal><a href=#__codelineno-27-4> 4</a></span>
<span class=normal><a href=#__codelineno-27-5> 5</a></span>
<span class=normal><a href=#__codelineno-27-6> 6</a></span>
<span class=normal><a href=#__codelineno-27-7> 7</a></span>
<span class=normal><a href=#__codelineno-27-8> 8</a></span>
<span class=normal><a href=#__codelineno-27-9> 9</a></span>
<span class=normal><a href=#__codelineno-27-10>10</a></span>
<span class=normal><a href=#__codelineno-27-11>11</a></span>
<span class=normal><a href=#__codelineno-27-12>12</a></span>
<span class=normal><a href=#__codelineno-27-13>13</a></span>
<span class=normal><a href=#__codelineno-27-14>14</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-27-1><a id=__codelineno-27-1 name=__codelineno-27-1></a><span class=c1>// ✅ GOOD: Generate once, then immutable</span>
</span><span id=__span-27-2><a id=__codelineno-27-2 name=__codelineno-27-2></a><span class=k>public</span><span class=w> </span><span class=n>WGuid</span><span class=w> </span><span class=n>entityId</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>WGuid</span><span class=p>.</span><span class=n>NewGuid</span><span class=p>();</span>
</span><span id=__span-27-3><a id=__codelineno-27-3 name=__codelineno-27-3></a>
</span><span id=__span-27-4><a id=__codelineno-27-4 name=__codelineno-27-4></a><span class=c1>// ✅ GOOD: Generate in Awake if needed</span>
</span><span id=__span-27-5><a id=__codelineno-27-5 name=__codelineno-27-5></a><span class=k>private</span><span class=w> </span><span class=k>void</span><span class=w> </span><span class=nf>Awake</span><span class=p>()</span>
</span><span id=__span-27-6><a id=__codelineno-27-6 name=__codelineno-27-6></a><span class=p>{</span>
</span><span id=__span-27-7><a id=__codelineno-27-7 name=__codelineno-27-7></a><span class=w>    </span><span class=k>if</span><span class=w> </span><span class=p>(</span><span class=n>entityId</span><span class=w> </span><span class=o>==</span><span class=w> </span><span class=n>WGuid</span><span class=p>.</span><span class=n>EmptyGuid</span><span class=p>)</span>
</span><span id=__span-27-8><a id=__codelineno-27-8 name=__codelineno-27-8></a><span class=w>    </span><span class=p>{</span>
</span><span id=__span-27-9><a id=__codelineno-27-9 name=__codelineno-27-9></a><span class=w>        </span><span class=n>entityId</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>WGuid</span><span class=p>.</span><span class=n>NewGuid</span><span class=p>();</span>
</span><span id=__span-27-10><a id=__codelineno-27-10 name=__codelineno-27-10></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-27-11><a id=__codelineno-27-11 name=__codelineno-27-11></a><span class=p>}</span>
</span><span id=__span-27-12><a id=__codelineno-27-12 name=__codelineno-27-12></a>
</span><span id=__span-27-13><a id=__codelineno-27-13 name=__codelineno-27-13></a><span class=c1>// ❌ BAD: Regenerating on every access</span>
</span><span id=__span-27-14><a id=__codelineno-27-14 name=__codelineno-27-14></a><span class=k>public</span><span class=w> </span><span class=n>WGuid</span><span class=w> </span><span class=n>EntityId</span><span class=w> </span><span class=o>=&gt;</span><span class=w> </span><span class=n>WGuid</span><span class=p>.</span><span class=n>NewGuid</span><span class=p>();</span><span class=w>  </span><span class=c1>// New GUID every time!</span>
</span></code></pre></div></td></tr></table></div> <hr> <h2 id=examples>Examples<a class=headerlink href=#examples title="Permanent link">&para;</a></h2> <h3 id=example-1-item-database-with-dictionary>Example 1: Item Database with Dictionary<a class=headerlink href=#example-1-item-database-with-dictionary title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-28-1> 1</a></span>
<span class=normal><a href=#__codelineno-28-2> 2</a></span>
<span class=normal><a href=#__codelineno-28-3> 3</a></span>
<span class=normal><a href=#__codelineno-28-4> 4</a></span>
<span class=normal><a href=#__codelineno-28-5> 5</a></span>
<span class=normal><a href=#__codelineno-28-6> 6</a></span>
<span class=normal><a href=#__codelineno-28-7> 7</a></span>
<span class=normal><a href=#__codelineno-28-8> 8</a></span>
<span class=normal><a href=#__codelineno-28-9> 9</a></span>
<span class=normal><a href=#__codelineno-28-10>10</a></span>
<span class=normal><a href=#__codelineno-28-11>11</a></span>
<span class=normal><a href=#__codelineno-28-12>12</a></span>
<span class=normal><a href=#__codelineno-28-13>13</a></span>
<span class=normal><a href=#__codelineno-28-14>14</a></span>
<span class=normal><a href=#__codelineno-28-15>15</a></span>
<span class=normal><a href=#__codelineno-28-16>16</a></span>
<span class=normal><a href=#__codelineno-28-17>17</a></span>
<span class=normal><a href=#__codelineno-28-18>18</a></span>
<span class=normal><a href=#__codelineno-28-19>19</a></span>
<span class=normal><a href=#__codelineno-28-20>20</a></span>
<span class=normal><a href=#__codelineno-28-21>21</a></span>
<span class=normal><a href=#__codelineno-28-22>22</a></span>
<span class=normal><a href=#__codelineno-28-23>23</a></span>
<span class=normal><a href=#__codelineno-28-24>24</a></span>
<span class=normal><a href=#__codelineno-28-25>25</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-28-1><a id=__codelineno-28-1 name=__codelineno-28-1></a><span class=k>using</span><span class=w> </span><span class=nn>UnityEngine</span><span class=p>;</span>
</span><span id=__span-28-2><a id=__codelineno-28-2 name=__codelineno-28-2></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.DataStructure.Adapters</span><span class=p>;</span>
</span><span id=__span-28-3><a id=__codelineno-28-3 name=__codelineno-28-3></a>
</span><span id=__span-28-4><a id=__codelineno-28-4 name=__codelineno-28-4></a><span class=na>[System.Serializable]</span>
</span><span id=__span-28-5><a id=__codelineno-28-5 name=__codelineno-28-5></a><span class=k>public</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>ItemData</span>
</span><span id=__span-28-6><a id=__codelineno-28-6 name=__codelineno-28-6></a><span class=p>{</span>
</span><span id=__span-28-7><a id=__codelineno-28-7 name=__codelineno-28-7></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=kt>string</span><span class=w> </span><span class=n>name</span><span class=p>;</span>
</span><span id=__span-28-8><a id=__codelineno-28-8 name=__codelineno-28-8></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>Sprite</span><span class=w> </span><span class=n>icon</span><span class=p>;</span>
</span><span id=__span-28-9><a id=__codelineno-28-9 name=__codelineno-28-9></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=kt>int</span><span class=w> </span><span class=k>value</span><span class=p>;</span>
</span><span id=__span-28-10><a id=__codelineno-28-10 name=__codelineno-28-10></a><span class=p>}</span>
</span><span id=__span-28-11><a id=__codelineno-28-11 name=__codelineno-28-11></a>
</span><span id=__span-28-12><a id=__codelineno-28-12 name=__codelineno-28-12></a><span class=k>public</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>ItemDatabase</span><span class=w> </span><span class=p>:</span><span class=w> </span><span class=n>MonoBehaviour</span>
</span><span id=__span-28-13><a id=__codelineno-28-13 name=__codelineno-28-13></a><span class=p>{</span>
</span><span id=__span-28-14><a id=__codelineno-28-14 name=__codelineno-28-14></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>SerializableDictionary</span><span class=o>&lt;</span><span class=kt>string</span><span class=p>,</span><span class=w> </span><span class=n>ItemData</span><span class=o>&gt;</span><span class=w> </span><span class=n>items</span><span class=p>;</span>
</span><span id=__span-28-15><a id=__codelineno-28-15 name=__codelineno-28-15></a>
</span><span id=__span-28-16><a id=__codelineno-28-16 name=__codelineno-28-16></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=kt>bool</span><span class=w> </span><span class=nf>TryGetItem</span><span class=p>(</span><span class=kt>string</span><span class=w> </span><span class=n>itemId</span><span class=p>,</span><span class=w> </span><span class=k>out</span><span class=w> </span><span class=n>ItemData</span><span class=w> </span><span class=n>data</span><span class=p>)</span>
</span><span id=__span-28-17><a id=__codelineno-28-17 name=__codelineno-28-17></a><span class=w>    </span><span class=p>{</span>
</span><span id=__span-28-18><a id=__codelineno-28-18 name=__codelineno-28-18></a><span class=w>        </span><span class=k>return</span><span class=w> </span><span class=n>items</span><span class=p>.</span><span class=n>TryGetValue</span><span class=p>(</span><span class=n>itemId</span><span class=p>,</span><span class=w> </span><span class=k>out</span><span class=w> </span><span class=n>data</span><span class=p>);</span>
</span><span id=__span-28-19><a id=__codelineno-28-19 name=__codelineno-28-19></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-28-20><a id=__codelineno-28-20 name=__codelineno-28-20></a>
</span><span id=__span-28-21><a id=__codelineno-28-21 name=__codelineno-28-21></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=k>void</span><span class=w> </span><span class=nf>AddItem</span><span class=p>(</span><span class=kt>string</span><span class=w> </span><span class=n>itemId</span><span class=p>,</span><span class=w> </span><span class=n>ItemData</span><span class=w> </span><span class=n>data</span><span class=p>)</span>
</span><span id=__span-28-22><a id=__codelineno-28-22 name=__codelineno-28-22></a><span class=w>    </span><span class=p>{</span>
</span><span id=__span-28-23><a id=__codelineno-28-23 name=__codelineno-28-23></a><span class=w>        </span><span class=n>items</span><span class=p>[</span><span class=n>itemId</span><span class=p>]</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>data</span><span class=p>;</span>
</span><span id=__span-28-24><a id=__codelineno-28-24 name=__codelineno-28-24></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-28-25><a id=__codelineno-28-25 name=__codelineno-28-25></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <hr> <h3 id=example-2-player-achievement-tracking>Example 2: Player Achievement Tracking<a class=headerlink href=#example-2-player-achievement-tracking title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-29-1> 1</a></span>
<span class=normal><a href=#__codelineno-29-2> 2</a></span>
<span class=normal><a href=#__codelineno-29-3> 3</a></span>
<span class=normal><a href=#__codelineno-29-4> 4</a></span>
<span class=normal><a href=#__codelineno-29-5> 5</a></span>
<span class=normal><a href=#__codelineno-29-6> 6</a></span>
<span class=normal><a href=#__codelineno-29-7> 7</a></span>
<span class=normal><a href=#__codelineno-29-8> 8</a></span>
<span class=normal><a href=#__codelineno-29-9> 9</a></span>
<span class=normal><a href=#__codelineno-29-10>10</a></span>
<span class=normal><a href=#__codelineno-29-11>11</a></span>
<span class=normal><a href=#__codelineno-29-12>12</a></span>
<span class=normal><a href=#__codelineno-29-13>13</a></span>
<span class=normal><a href=#__codelineno-29-14>14</a></span>
<span class=normal><a href=#__codelineno-29-15>15</a></span>
<span class=normal><a href=#__codelineno-29-16>16</a></span>
<span class=normal><a href=#__codelineno-29-17>17</a></span>
<span class=normal><a href=#__codelineno-29-18>18</a></span>
<span class=normal><a href=#__codelineno-29-19>19</a></span>
<span class=normal><a href=#__codelineno-29-20>20</a></span>
<span class=normal><a href=#__codelineno-29-21>21</a></span>
<span class=normal><a href=#__codelineno-29-22>22</a></span>
<span class=normal><a href=#__codelineno-29-23>23</a></span>
<span class=normal><a href=#__codelineno-29-24>24</a></span>
<span class=normal><a href=#__codelineno-29-25>25</a></span>
<span class=normal><a href=#__codelineno-29-26>26</a></span>
<span class=normal><a href=#__codelineno-29-27>27</a></span>
<span class=normal><a href=#__codelineno-29-28>28</a></span>
<span class=normal><a href=#__codelineno-29-29>29</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-29-1><a id=__codelineno-29-1 name=__codelineno-29-1></a><span class=k>using</span><span class=w> </span><span class=nn>UnityEngine</span><span class=p>;</span>
</span><span id=__span-29-2><a id=__codelineno-29-2 name=__codelineno-29-2></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.DataStructure.Adapters</span><span class=p>;</span>
</span><span id=__span-29-3><a id=__codelineno-29-3 name=__codelineno-29-3></a>
</span><span id=__span-29-4><a id=__codelineno-29-4 name=__codelineno-29-4></a><span class=k>public</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>PlayerProfile</span><span class=w> </span><span class=p>:</span><span class=w> </span><span class=n>MonoBehaviour</span>
</span><span id=__span-29-5><a id=__codelineno-29-5 name=__codelineno-29-5></a><span class=p>{</span>
</span><span id=__span-29-6><a id=__codelineno-29-6 name=__codelineno-29-6></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>WGuid</span><span class=w> </span><span class=n>playerId</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>WGuid</span><span class=p>.</span><span class=n>NewGuid</span><span class=p>();</span>
</span><span id=__span-29-7><a id=__codelineno-29-7 name=__codelineno-29-7></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>SerializableHashSet</span><span class=o>&lt;</span><span class=kt>string</span><span class=o>&gt;</span><span class=w> </span><span class=n>unlockedAchievements</span><span class=p>;</span>
</span><span id=__span-29-8><a id=__codelineno-29-8 name=__codelineno-29-8></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>SerializableSortedSet</span><span class=o>&lt;</span><span class=kt>int</span><span class=o>&gt;</span><span class=w> </span><span class=n>highScores</span><span class=p>;</span>
</span><span id=__span-29-9><a id=__codelineno-29-9 name=__codelineno-29-9></a>
</span><span id=__span-29-10><a id=__codelineno-29-10 name=__codelineno-29-10></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=k>void</span><span class=w> </span><span class=nf>UnlockAchievement</span><span class=p>(</span><span class=kt>string</span><span class=w> </span><span class=n>achievementId</span><span class=p>)</span>
</span><span id=__span-29-11><a id=__codelineno-29-11 name=__codelineno-29-11></a><span class=w>    </span><span class=p>{</span>
</span><span id=__span-29-12><a id=__codelineno-29-12 name=__codelineno-29-12></a><span class=w>        </span><span class=k>if</span><span class=w> </span><span class=p>(</span><span class=n>unlockedAchievements</span><span class=p>.</span><span class=n>Add</span><span class=p>(</span><span class=n>achievementId</span><span class=p>))</span>
</span><span id=__span-29-13><a id=__codelineno-29-13 name=__codelineno-29-13></a><span class=w>        </span><span class=p>{</span>
</span><span id=__span-29-14><a id=__codelineno-29-14 name=__codelineno-29-14></a><span class=w>            </span><span class=n>Debug</span><span class=p>.</span><span class=n>Log</span><span class=p>(</span><span class=s>$&quot;Unlocked: {achievementId}&quot;</span><span class=p>);</span>
</span><span id=__span-29-15><a id=__codelineno-29-15 name=__codelineno-29-15></a><span class=w>            </span><span class=c1>// Trigger UI notification, etc.</span>
</span><span id=__span-29-16><a id=__codelineno-29-16 name=__codelineno-29-16></a><span class=w>        </span><span class=p>}</span>
</span><span id=__span-29-17><a id=__codelineno-29-17 name=__codelineno-29-17></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-29-18><a id=__codelineno-29-18 name=__codelineno-29-18></a>
</span><span id=__span-29-19><a id=__codelineno-29-19 name=__codelineno-29-19></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=k>void</span><span class=w> </span><span class=nf>RecordScore</span><span class=p>(</span><span class=kt>int</span><span class=w> </span><span class=n>score</span><span class=p>)</span>
</span><span id=__span-29-20><a id=__codelineno-29-20 name=__codelineno-29-20></a><span class=w>    </span><span class=p>{</span>
</span><span id=__span-29-21><a id=__codelineno-29-21 name=__codelineno-29-21></a><span class=w>        </span><span class=n>highScores</span><span class=p>.</span><span class=n>Add</span><span class=p>(</span><span class=n>score</span><span class=p>);</span>
</span><span id=__span-29-22><a id=__codelineno-29-22 name=__codelineno-29-22></a>
</span><span id=__span-29-23><a id=__codelineno-29-23 name=__codelineno-29-23></a><span class=w>        </span><span class=c1>// Keep only top 10</span>
</span><span id=__span-29-24><a id=__codelineno-29-24 name=__codelineno-29-24></a><span class=w>        </span><span class=k>while</span><span class=w> </span><span class=p>(</span><span class=n>highScores</span><span class=p>.</span><span class=n>Count</span><span class=w> </span><span class=o>&gt;</span><span class=w> </span><span class=mi>10</span><span class=p>)</span>
</span><span id=__span-29-25><a id=__codelineno-29-25 name=__codelineno-29-25></a><span class=w>        </span><span class=p>{</span>
</span><span id=__span-29-26><a id=__codelineno-29-26 name=__codelineno-29-26></a><span class=w>            </span><span class=n>highScores</span><span class=p>.</span><span class=n>Remove</span><span class=p>(</span><span class=n>highScores</span><span class=p>.</span><span class=n>Min</span><span class=p>);</span>
</span><span id=__span-29-27><a id=__codelineno-29-27 name=__codelineno-29-27></a><span class=w>        </span><span class=p>}</span>
</span><span id=__span-29-28><a id=__codelineno-29-28 name=__codelineno-29-28></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-29-29><a id=__codelineno-29-29 name=__codelineno-29-29></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <hr> <h3 id=example-3-dynamic-behavior-spawning>Example 3: Dynamic Behavior Spawning<a class=headerlink href=#example-3-dynamic-behavior-spawning title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-30-1> 1</a></span>
<span class=normal><a href=#__codelineno-30-2> 2</a></span>
<span class=normal><a href=#__codelineno-30-3> 3</a></span>
<span class=normal><a href=#__codelineno-30-4> 4</a></span>
<span class=normal><a href=#__codelineno-30-5> 5</a></span>
<span class=normal><a href=#__codelineno-30-6> 6</a></span>
<span class=normal><a href=#__codelineno-30-7> 7</a></span>
<span class=normal><a href=#__codelineno-30-8> 8</a></span>
<span class=normal><a href=#__codelineno-30-9> 9</a></span>
<span class=normal><a href=#__codelineno-30-10>10</a></span>
<span class=normal><a href=#__codelineno-30-11>11</a></span>
<span class=normal><a href=#__codelineno-30-12>12</a></span>
<span class=normal><a href=#__codelineno-30-13>13</a></span>
<span class=normal><a href=#__codelineno-30-14>14</a></span>
<span class=normal><a href=#__codelineno-30-15>15</a></span>
<span class=normal><a href=#__codelineno-30-16>16</a></span>
<span class=normal><a href=#__codelineno-30-17>17</a></span>
<span class=normal><a href=#__codelineno-30-18>18</a></span>
<span class=normal><a href=#__codelineno-30-19>19</a></span>
<span class=normal><a href=#__codelineno-30-20>20</a></span>
<span class=normal><a href=#__codelineno-30-21>21</a></span>
<span class=normal><a href=#__codelineno-30-22>22</a></span>
<span class=normal><a href=#__codelineno-30-23>23</a></span>
<span class=normal><a href=#__codelineno-30-24>24</a></span>
<span class=normal><a href=#__codelineno-30-25>25</a></span>
<span class=normal><a href=#__codelineno-30-26>26</a></span>
<span class=normal><a href=#__codelineno-30-27>27</a></span>
<span class=normal><a href=#__codelineno-30-28>28</a></span>
<span class=normal><a href=#__codelineno-30-29>29</a></span>
<span class=normal><a href=#__codelineno-30-30>30</a></span>
<span class=normal><a href=#__codelineno-30-31>31</a></span>
<span class=normal><a href=#__codelineno-30-32>32</a></span>
<span class=normal><a href=#__codelineno-30-33>33</a></span>
<span class=normal><a href=#__codelineno-30-34>34</a></span>
<span class=normal><a href=#__codelineno-30-35>35</a></span>
<span class=normal><a href=#__codelineno-30-36>36</a></span>
<span class=normal><a href=#__codelineno-30-37>37</a></span>
<span class=normal><a href=#__codelineno-30-38>38</a></span>
<span class=normal><a href=#__codelineno-30-39>39</a></span>
<span class=normal><a href=#__codelineno-30-40>40</a></span>
<span class=normal><a href=#__codelineno-30-41>41</a></span>
<span class=normal><a href=#__codelineno-30-42>42</a></span>
<span class=normal><a href=#__codelineno-30-43>43</a></span>
<span class=normal><a href=#__codelineno-30-44>44</a></span>
<span class=normal><a href=#__codelineno-30-45>45</a></span>
<span class=normal><a href=#__codelineno-30-46>46</a></span>
<span class=normal><a href=#__codelineno-30-47>47</a></span>
<span class=normal><a href=#__codelineno-30-48>48</a></span>
<span class=normal><a href=#__codelineno-30-49>49</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-30-1><a id=__codelineno-30-1 name=__codelineno-30-1></a><span class=k>using</span><span class=w> </span><span class=nn>UnityEngine</span><span class=p>;</span>
</span><span id=__span-30-2><a id=__codelineno-30-2 name=__codelineno-30-2></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.DataStructure.Adapters</span><span class=p>;</span>
</span><span id=__span-30-3><a id=__codelineno-30-3 name=__codelineno-30-3></a><span class=k>using</span><span class=w> </span><span class=nn>System</span><span class=p>;</span>
</span><span id=__span-30-4><a id=__codelineno-30-4 name=__codelineno-30-4></a>
</span><span id=__span-30-5><a id=__codelineno-30-5 name=__codelineno-30-5></a><span class=k>public</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>BehaviorFactory</span><span class=w> </span><span class=p>:</span><span class=w> </span><span class=n>MonoBehaviour</span>
</span><span id=__span-30-6><a id=__codelineno-30-6 name=__codelineno-30-6></a><span class=p>{</span>
</span><span id=__span-30-7><a id=__codelineno-30-7 name=__codelineno-30-7></a><span class=w>    </span><span class=na>[StringInList(typeof(TypeHelper), nameof(TypeHelper.GetAllMonoBehaviours))]</span>
</span><span id=__span-30-8><a id=__codelineno-30-8 name=__codelineno-30-8></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>SerializableType</span><span class=w> </span><span class=n>defaultBehavior</span><span class=p>;</span>
</span><span id=__span-30-9><a id=__codelineno-30-9 name=__codelineno-30-9></a>
</span><span id=__span-30-10><a id=__codelineno-30-10 name=__codelineno-30-10></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>SerializableDictionary</span><span class=o>&lt;</span><span class=kt>string</span><span class=p>,</span><span class=w> </span><span class=n>SerializableType</span><span class=o>&gt;</span><span class=w> </span><span class=n>namedBehaviors</span><span class=p>;</span>
</span><span id=__span-30-11><a id=__codelineno-30-11 name=__codelineno-30-11></a>
</span><span id=__span-30-12><a id=__codelineno-30-12 name=__codelineno-30-12></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>GameObject</span><span class=w> </span><span class=nf>SpawnWithBehavior</span><span class=p>(</span><span class=kt>string</span><span class=w> </span><span class=n>behaviorName</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>null</span><span class=p>)</span>
</span><span id=__span-30-13><a id=__codelineno-30-13 name=__codelineno-30-13></a><span class=w>    </span><span class=p>{</span>
</span><span id=__span-30-14><a id=__codelineno-30-14 name=__codelineno-30-14></a><span class=w>        </span><span class=n>SerializableType</span><span class=w> </span><span class=n>typeToSpawn</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>defaultBehavior</span><span class=p>;</span>
</span><span id=__span-30-15><a id=__codelineno-30-15 name=__codelineno-30-15></a>
</span><span id=__span-30-16><a id=__codelineno-30-16 name=__codelineno-30-16></a><span class=w>        </span><span class=k>if</span><span class=w> </span><span class=p>(</span><span class=o>!</span><span class=kt>string</span><span class=p>.</span><span class=n>IsNullOrEmpty</span><span class=p>(</span><span class=n>behaviorName</span><span class=p>)</span><span class=w> </span><span class=o>&amp;&amp;</span>
</span><span id=__span-30-17><a id=__codelineno-30-17 name=__codelineno-30-17></a><span class=w>            </span><span class=n>namedBehaviors</span><span class=p>.</span><span class=n>TryGetValue</span><span class=p>(</span><span class=n>behaviorName</span><span class=p>,</span><span class=w> </span><span class=k>out</span><span class=w> </span><span class=n>SerializableType</span><span class=w> </span><span class=n>namedType</span><span class=p>))</span>
</span><span id=__span-30-18><a id=__codelineno-30-18 name=__codelineno-30-18></a><span class=w>        </span><span class=p>{</span>
</span><span id=__span-30-19><a id=__codelineno-30-19 name=__codelineno-30-19></a><span class=w>            </span><span class=n>typeToSpawn</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>namedType</span><span class=p>;</span>
</span><span id=__span-30-20><a id=__codelineno-30-20 name=__codelineno-30-20></a><span class=w>        </span><span class=p>}</span>
</span><span id=__span-30-21><a id=__codelineno-30-21 name=__codelineno-30-21></a>
</span><span id=__span-30-22><a id=__codelineno-30-22 name=__codelineno-30-22></a><span class=w>        </span><span class=k>if</span><span class=w> </span><span class=p>(</span><span class=n>typeToSpawn</span><span class=p>.</span><span class=n>IsEmpty</span><span class=p>)</span>
</span><span id=__span-30-23><a id=__codelineno-30-23 name=__codelineno-30-23></a><span class=w>        </span><span class=p>{</span>
</span><span id=__span-30-24><a id=__codelineno-30-24 name=__codelineno-30-24></a><span class=w>            </span><span class=n>Debug</span><span class=p>.</span><span class=n>LogWarning</span><span class=p>(</span><span class=s>&quot;No behavior type specified!&quot;</span><span class=p>);</span>
</span><span id=__span-30-25><a id=__codelineno-30-25 name=__codelineno-30-25></a><span class=w>            </span><span class=k>return</span><span class=w> </span><span class=k>null</span><span class=p>;</span>
</span><span id=__span-30-26><a id=__codelineno-30-26 name=__codelineno-30-26></a><span class=w>        </span><span class=p>}</span>
</span><span id=__span-30-27><a id=__codelineno-30-27 name=__codelineno-30-27></a>
</span><span id=__span-30-28><a id=__codelineno-30-28 name=__codelineno-30-28></a><span class=w>        </span><span class=n>Type</span><span class=w> </span><span class=n>type</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>typeToSpawn</span><span class=p>.</span><span class=n>Value</span><span class=p>;</span>
</span><span id=__span-30-29><a id=__codelineno-30-29 name=__codelineno-30-29></a><span class=w>        </span><span class=k>if</span><span class=w> </span><span class=p>(</span><span class=n>type</span><span class=w> </span><span class=o>==</span><span class=w> </span><span class=k>null</span><span class=w> </span><span class=o>||</span><span class=w> </span><span class=o>!</span><span class=k>typeof</span><span class=p>(</span><span class=n>MonoBehaviour</span><span class=p>).</span><span class=n>IsAssignableFrom</span><span class=p>(</span><span class=n>type</span><span class=p>))</span>
</span><span id=__span-30-30><a id=__codelineno-30-30 name=__codelineno-30-30></a><span class=w>        </span><span class=p>{</span>
</span><span id=__span-30-31><a id=__codelineno-30-31 name=__codelineno-30-31></a><span class=w>            </span><span class=n>Debug</span><span class=p>.</span><span class=n>LogError</span><span class=p>(</span><span class=s>$&quot;Invalid behavior type: {typeToSpawn.DisplayName}&quot;</span><span class=p>);</span>
</span><span id=__span-30-32><a id=__codelineno-30-32 name=__codelineno-30-32></a><span class=w>            </span><span class=k>return</span><span class=w> </span><span class=k>null</span><span class=p>;</span>
</span><span id=__span-30-33><a id=__codelineno-30-33 name=__codelineno-30-33></a><span class=w>        </span><span class=p>}</span>
</span><span id=__span-30-34><a id=__codelineno-30-34 name=__codelineno-30-34></a>
</span><span id=__span-30-35><a id=__codelineno-30-35 name=__codelineno-30-35></a><span class=w>        </span><span class=n>GameObject</span><span class=w> </span><span class=n>go</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=k>new</span><span class=w> </span><span class=n>GameObject</span><span class=p>(</span><span class=n>type</span><span class=p>.</span><span class=n>Name</span><span class=p>);</span>
</span><span id=__span-30-36><a id=__codelineno-30-36 name=__codelineno-30-36></a><span class=w>        </span><span class=n>go</span><span class=p>.</span><span class=n>AddComponent</span><span class=p>(</span><span class=n>type</span><span class=p>);</span>
</span><span id=__span-30-37><a id=__codelineno-30-37 name=__codelineno-30-37></a><span class=w>        </span><span class=k>return</span><span class=w> </span><span class=n>go</span><span class=p>;</span>
</span><span id=__span-30-38><a id=__codelineno-30-38 name=__codelineno-30-38></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-30-39><a id=__codelineno-30-39 name=__codelineno-30-39></a><span class=p>}</span>
</span><span id=__span-30-40><a id=__codelineno-30-40 name=__codelineno-30-40></a>
</span><span id=__span-30-41><a id=__codelineno-30-41 name=__codelineno-30-41></a><span class=k>public</span><span class=w> </span><span class=k>static</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>TypeHelper</span>
</span><span id=__span-30-42><a id=__codelineno-30-42 name=__codelineno-30-42></a><span class=p>{</span>
</span><span id=__span-30-43><a id=__codelineno-30-43 name=__codelineno-30-43></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=k>static</span><span class=w> </span><span class=n>IEnumerable</span><span class=o>&lt;</span><span class=n>Type</span><span class=o>&gt;</span><span class=w> </span><span class=n>GetAllMonoBehaviours</span><span class=p>()</span>
</span><span id=__span-30-44><a id=__codelineno-30-44 name=__codelineno-30-44></a><span class=w>    </span><span class=p>{</span>
</span><span id=__span-30-45><a id=__codelineno-30-45 name=__codelineno-30-45></a><span class=w>        </span><span class=k>return</span><span class=w> </span><span class=n>AppDomain</span><span class=p>.</span><span class=n>CurrentDomain</span><span class=p>.</span><span class=n>GetAssemblies</span><span class=p>()</span>
</span><span id=__span-30-46><a id=__codelineno-30-46 name=__codelineno-30-46></a><span class=w>            </span><span class=p>.</span><span class=n>SelectMany</span><span class=p>(</span><span class=n>a</span><span class=w> </span><span class=o>=&gt;</span><span class=w> </span><span class=n>a</span><span class=p>.</span><span class=n>GetTypes</span><span class=p>())</span>
</span><span id=__span-30-47><a id=__codelineno-30-47 name=__codelineno-30-47></a><span class=w>            </span><span class=p>.</span><span class=n>Where</span><span class=p>(</span><span class=n>t</span><span class=w> </span><span class=o>=&gt;</span><span class=w> </span><span class=k>typeof</span><span class=p>(</span><span class=n>MonoBehaviour</span><span class=p>).</span><span class=n>IsAssignableFrom</span><span class=p>(</span><span class=n>t</span><span class=p>)</span><span class=w> </span><span class=o>&amp;&amp;</span><span class=w> </span><span class=o>!</span><span class=n>t</span><span class=p>.</span><span class=n>IsAbstract</span><span class=p>);</span>
</span><span id=__span-30-48><a id=__codelineno-30-48 name=__codelineno-30-48></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-30-49><a id=__codelineno-30-49 name=__codelineno-30-49></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <hr> <h3 id=example-4-optional-configuration-with-nullable>Example 4: Optional Configuration with Nullable<a class=headerlink href=#example-4-optional-configuration-with-nullable title="Permanent link">&para;</a></h3> <div class="language-csharp highlight"><table class=highlighttable><tr><th colspan=2 class=filename><span class=filename>C#</span></th></tr><tr><td class=linenos><div class=linenodiv><pre><span></span><span class=normal><a href=#__codelineno-31-1> 1</a></span>
<span class=normal><a href=#__codelineno-31-2> 2</a></span>
<span class=normal><a href=#__codelineno-31-3> 3</a></span>
<span class=normal><a href=#__codelineno-31-4> 4</a></span>
<span class=normal><a href=#__codelineno-31-5> 5</a></span>
<span class=normal><a href=#__codelineno-31-6> 6</a></span>
<span class=normal><a href=#__codelineno-31-7> 7</a></span>
<span class=normal><a href=#__codelineno-31-8> 8</a></span>
<span class=normal><a href=#__codelineno-31-9> 9</a></span>
<span class=normal><a href=#__codelineno-31-10>10</a></span>
<span class=normal><a href=#__codelineno-31-11>11</a></span>
<span class=normal><a href=#__codelineno-31-12>12</a></span>
<span class=normal><a href=#__codelineno-31-13>13</a></span>
<span class=normal><a href=#__codelineno-31-14>14</a></span>
<span class=normal><a href=#__codelineno-31-15>15</a></span>
<span class=normal><a href=#__codelineno-31-16>16</a></span>
<span class=normal><a href=#__codelineno-31-17>17</a></span>
<span class=normal><a href=#__codelineno-31-18>18</a></span>
<span class=normal><a href=#__codelineno-31-19>19</a></span></pre></div></td><td class=code><div><pre><span></span><code><span id=__span-31-1><a id=__codelineno-31-1 name=__codelineno-31-1></a><span class=k>using</span><span class=w> </span><span class=nn>UnityEngine</span><span class=p>;</span>
</span><span id=__span-31-2><a id=__codelineno-31-2 name=__codelineno-31-2></a><span class=k>using</span><span class=w> </span><span class=nn>WallstopStudios.UnityHelpers.Core.DataStructure.Adapters</span><span class=p>;</span>
</span><span id=__span-31-3><a id=__codelineno-31-3 name=__codelineno-31-3></a>
</span><span id=__span-31-4><a id=__codelineno-31-4 name=__codelineno-31-4></a><span class=k>public</span><span class=w> </span><span class=k>class</span><span class=w> </span><span class=nc>CharacterConfig</span><span class=w> </span><span class=p>:</span><span class=w> </span><span class=n>MonoBehaviour</span>
</span><span id=__span-31-5><a id=__codelineno-31-5 name=__codelineno-31-5></a><span class=p>{</span>
</span><span id=__span-31-6><a id=__codelineno-31-6 name=__codelineno-31-6></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=kt>float</span><span class=w> </span><span class=n>baseSpeed</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=mf>5f</span><span class=p>;</span>
</span><span id=__span-31-7><a id=__codelineno-31-7 name=__codelineno-31-7></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>SerializableNullable</span><span class=o>&lt;</span><span class=kt>float</span><span class=o>&gt;</span><span class=w> </span><span class=n>speedOverride</span><span class=p>;</span><span class=w>  </span><span class=c1>// null = use baseSpeed</span>
</span><span id=__span-31-8><a id=__codelineno-31-8 name=__codelineno-31-8></a>
</span><span id=__span-31-9><a id=__codelineno-31-9 name=__codelineno-31-9></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>Color</span><span class=w> </span><span class=n>defaultColor</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>Color</span><span class=p>.</span><span class=n>white</span><span class=p>;</span>
</span><span id=__span-31-10><a id=__codelineno-31-10 name=__codelineno-31-10></a><span class=w>    </span><span class=k>public</span><span class=w> </span><span class=n>SerializableNullable</span><span class=o>&lt;</span><span class=n>Color</span><span class=o>&gt;</span><span class=w> </span><span class=n>colorOverride</span><span class=p>;</span><span class=w>  </span><span class=c1>// null = use defaultColor</span>
</span><span id=__span-31-11><a id=__codelineno-31-11 name=__codelineno-31-11></a>
</span><span id=__span-31-12><a id=__codelineno-31-12 name=__codelineno-31-12></a><span class=w>    </span><span class=k>private</span><span class=w> </span><span class=k>void</span><span class=w> </span><span class=nf>Start</span><span class=p>()</span>
</span><span id=__span-31-13><a id=__codelineno-31-13 name=__codelineno-31-13></a><span class=w>    </span><span class=p>{</span>
</span><span id=__span-31-14><a id=__codelineno-31-14 name=__codelineno-31-14></a><span class=w>        </span><span class=kt>float</span><span class=w> </span><span class=n>actualSpeed</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>speedOverride</span><span class=p>.</span><span class=n>HasValue</span><span class=w> </span><span class=o>?</span><span class=w> </span><span class=n>speedOverride</span><span class=p>.</span><span class=n>Value</span><span class=w> </span><span class=p>:</span><span class=w> </span><span class=n>baseSpeed</span><span class=p>;</span>
</span><span id=__span-31-15><a id=__codelineno-31-15 name=__codelineno-31-15></a><span class=w>        </span><span class=n>Color</span><span class=w> </span><span class=n>actualColor</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>colorOverride</span><span class=p>.</span><span class=n>HasValue</span><span class=w> </span><span class=o>?</span><span class=w> </span><span class=n>colorOverride</span><span class=p>.</span><span class=n>Value</span><span class=w> </span><span class=p>:</span><span class=w> </span><span class=n>defaultColor</span><span class=p>;</span>
</span><span id=__span-31-16><a id=__codelineno-31-16 name=__codelineno-31-16></a>
</span><span id=__span-31-17><a id=__codelineno-31-17 name=__codelineno-31-17></a><span class=w>        </span><span class=n>Debug</span><span class=p>.</span><span class=n>Log</span><span class=p>(</span><span class=s>$&quot;Speed: {actualSpeed}, Color: {actualColor}&quot;</span><span class=p>);</span>
</span><span id=__span-31-18><a id=__codelineno-31-18 name=__codelineno-31-18></a><span class=w>    </span><span class=p>}</span>
</span><span id=__span-31-19><a id=__codelineno-31-19 name=__codelineno-31-19></a><span class=p>}</span>
</span></code></pre></div></td></tr></table></div> <hr> <h2 id=see-also>See Also<a class=headerlink href=#see-also title="Permanent link">&para;</a></h2> <ul> <li><strong><a href=../../inspector/inspector-overview/ >Inspector Overview</a></strong> - Complete inspector features overview</li> <li><strong><a href=../serialization/ >Serialization Guide</a></strong> - JSON/Protobuf serialization</li> <li><strong><a href=../../utilities/data-structures/ >Data Structures</a></strong> - Other data structures</li> <li><strong><a href=../../editor-tools/editor-tools-guide/ >Editor Tools Guide</a></strong> - Editor utilities</li> </ul> <hr> <p><strong>Next Steps:</strong></p> <ul> <li>Replace string/int-based IDs with <code>WGuid</code></li> <li>Use <code>SerializableDictionary</code> instead of parallel arrays</li> <li>Track unique collections with <code>SerializableHashSet</code></li> <li>Store type references with <code>SerializableType</code></li> <li>Add optional configuration with <code>SerializableNullable</code></li> </ul> <aside class=md-source-file> <span class=md-source-file__fact> <span class=md-icon title="Last update"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z"/></svg> </span> <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago" title="February 27, 2026 02:38:56 UTC"><span class=timeago datetime=2026-02-27T02:38:56+00:00 locale=en></span></span><span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date" title="February 27, 2026 02:38:56 UTC">2026-02-27</span> </span> <span class=md-source-file__fact> <span class=md-icon title=Created> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M14.47 15.08 11 13V7h1.5v5.25l3.08 1.83c-.41.28-.79.62-1.11 1m-1.39 4.84c-.36.05-.71.08-1.08.08-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8c0 .37-.03.72-.08 1.08.69.1 1.33.32 1.92.64.1-.56.16-1.13.16-1.72 0-5.5-4.5-10-10-10S2 6.5 2 12s4.47 10 10 10c.59 0 1.16-.06 1.72-.16-.32-.59-.54-1.23-.64-1.92M18 15v3h-3v2h3v3h2v-3h3v-2h-3v-3z"/></svg> </span> <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago" title="December 25, 2025 20:02:30 UTC"><span class=timeago datetime=2025-12-25T20:02:30+00:00 locale=en></span></span><span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date" title="December 25, 2025 20:02:30 UTC">2025-12-25</span> </span> </aside> </article> </div> <script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> <button type=button class="md-top md-icon" data-md-component=top hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg> Back to top </button> </main> <footer class=md-footer> <nav class="md-footer__inner md-grid" aria-label=Footer> <a href=../serialization/ class="md-footer__link md-footer__link--prev" aria-label="Previous: Overview"> <div class="md-footer__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg> </div> <div class=md-footer__title> <span class=md-footer__direction> Previous </span> <div class=md-ellipsis> Overview </div> </div> </a> <a href=../../utilities/math-and-extensions/ class="md-footer__link md-footer__link--next" aria-label="Next: Math & Extensions"> <div class=md-footer__title> <span class=md-footer__direction> Next </span> <div class=md-ellipsis> Math & Extensions </div> </div> <div class="md-footer__button md-icon"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg> </div> </a> </nav> <div class="md-footer-meta md-typeset"> <div class="md-footer-meta__inner md-grid"> <div class=md-copyright> <div class=md-copyright__highlight> Copyright &copy; 2024-2026 Wallstop Studios - MIT License </div> </div> <div class=md-social> <a href=https://github.com/wallstop/unity-helpers target=_blank rel=noopener title="Unity Helpers on GitHub" class=md-social__link> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 512 512"><!-- Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg> </a> </div> </div> </div> </footer> </div> <div class=md-dialog data-md-component=dialog> <div class="md-dialog__inner md-typeset"></div> </div> <div class=md-progress data-md-component=progress role=progressbar></div> <script id=__config type=application/json>{"annotate": null, "base": "../../..", "features": ["navigation.instant", "navigation.instant.prefetch", "navigation.instant.progress", "navigation.tracking", "navigation.tabs", "navigation.tabs.sticky", "navigation.sections", "navigation.expand", "navigation.path", "navigation.indexes", "navigation.top", "navigation.footer", "toc.follow", "toc.integrate", "search.suggest", "search.highlight", "search.share", "header.autohide", "content.code.copy", "content.code.annotate", "content.tabs.link", "content.tooltips", "content.action.edit", "content.action.view"], "search": "../../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script> <script src=../../../assets/javascripts/bundle.79ae519e.min.js></script> <script src=../../../js/timeago.min.js></script> <script src=../../../js/timeago_mkdocs_material.js></script> <script src=https://unpkg.com/mermaid@10/dist/mermaid.min.js></script> </body> </html>