{"id":18961037,"url":"https://github.com/itwin/imodel-unity-example","last_synced_at":"2025-04-19T11:33:03.061Z","repository":{"id":38454028,"uuid":"199504714","full_name":"iTwin/imodel-unity-example","owner":"iTwin","description":"Example demonstrating use of iTwin.js with a Unity application","archived":false,"fork":false,"pushed_at":"2023-07-18T20:16:14.000Z","size":19458,"stargazers_count":22,"open_issues_count":10,"forks_count":9,"subscribers_count":16,"default_branch":"main","last_synced_at":"2025-03-29T07:21:54.995Z","etag":null,"topics":["digital-twin","imodel","imodeljs","itwin","itwinjs","unity"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iTwin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null}},"created_at":"2019-07-29T18:14:51.000Z","updated_at":"2024-11-01T03:12:29.000Z","dependencies_parsed_at":"2023-02-13T19:31:48.690Z","dependency_job_id":null,"html_url":"https://github.com/iTwin/imodel-unity-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iTwin%2Fimodel-unity-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iTwin%2Fimodel-unity-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iTwin%2Fimodel-unity-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iTwin%2Fimodel-unity-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iTwin","download_url":"https://codeload.github.com/iTwin/imodel-unity-example/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249195392,"owners_count":21228190,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["digital-twin","imodel","imodeljs","itwin","itwinjs","unity"],"created_at":"2024-11-08T14:11:14.446Z","updated_at":"2025-04-19T11:33:03.028Z","avatar_url":"https://github.com/iTwin.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# imodel-unity-example\r\n\r\nCopyright © Bentley Systems, Incorporated. All rights reserved.\r\n\r\nThis is an example of using IPC to work with [iTwin.js](https://itwinjs.org/)\r\nin a [Unity](https://unity.com/) application. It includes a demonstration iModel to be used only for\r\ndevelopment purposes.\r\n\r\n## Getting Started\r\n\r\n### Prerequisites\r\n\r\n- Unity 2020.3 or later\r\n- Node 16\r\n- Windows\r\n- MacOS and Linux should work but are untested. Developers on these platforms will need to add the appropriate\r\n  version of the [protobuf-compiler](https://developers.google.com/protocol-buffers/docs/downloads)\r\n\r\n### Setup\r\n\r\nOpen the node subdirectory in a shell, and run:\r\n\r\n```sh\r\nnpm install\r\nnpm run build\r\n```\r\n\r\n### Running\r\n\r\n- From the node subdirectory, run `npm start` to start the server.\r\n- Click Play in the Unity editor to connect to the server.\r\n- Camera controls match Unity's scene view:\r\n  - WASD to fly\r\n  - Hold right-click for mouse-look\r\n  - Middle mouse to pan\r\n  - Mouse wheel to zoom\r\n- Left-clicking an element will display its tooltip by querying the iTwin.js backend\r\n- Arrow keys to cycle through 3D views\r\n\r\n## How It Works\r\n\r\n### Node.js Server With iTwin.js\r\n\r\nThe Node.js server uses the\r\n[core-backend package](https://www.itwinjs.org/reference/core-backend/)\r\nand its dependencies to open a specified\r\n[Snapshot iModel](https://www.itwinjs.org/learning/backend/accessingimodels/).\r\nOpening an iModel loads a minimal amount of data and takes a small fixed amount of time, regardless of\r\nhow large the iModel is.\r\n\r\n### Unity Application Connects to Server Over WebSocket\r\n\r\nIn this example, the Unity application is connecting to a process on the same computer but it could\r\njust as easily connect to a separate machine, either in the cloud or on a local network. This pattern\r\nis useful for streaming to standalone devices like the Microsoft HoloLens or Oculus Quest.\r\n\r\n### Processes Communicate With Protocol Buffer Messages\r\n\r\nThe communication between the Node.js server and Unity application is via messages encoded with\r\n[Google Protocol Buffers](https://developers.google.com/protocol-buffers/docs/proto3).\r\nProtocol Buffers is a widely useful and efficient format with excellent tooling and code generation\r\nfor many languages.\r\n\r\nWhen [IModelRpc.proto](./node/IModelRpc.proto) is modified, new bindings are automatically generated\r\nfor both the Node.js server and Unity application. This workflow is efficient during development and\r\nat runtime.\r\n\r\nIModelRpc.proto is broken down into Requests and Replies, with the Unity application making Requests\r\nand the Node.js server making Replies. Because Protocol Buffer messages are not self-describing, each\r\nprocess needs to know the message type when parsing. `RequestWrapper` and `ReplyWrapper` handle this\r\nproblem.\r\n\r\nThis IPC scheme is heavily inspired by [gRPC](https://grpc.io/). This example does not use gRPC due\r\nto a lack of official TypeScript bindings for generated code and Unity support still being experimental.\r\n\r\n### Element Graphics and Data Are Streamed On-Demand\r\n\r\n[Spatial Queries](https://www.itwinjs.org/learning/spatialqueries/) on the iModel are used to request\r\ngraphics based on what's visible to the Unity camera. The largest elements by volume are sent first, and\r\nas the camera moves new graphics are continually requested.\r\n\r\nElement properties (commonly referred to as \"BIM data\") are loaded on demand when an element is selected.\r\n\r\n## Frequently Asked Questions\r\n\r\n### What Is the Purpose of This Example?\r\n\r\nThis example shows one possible pattern for integrating iTwin.js with applications that\r\naren't full-stack JavaScript/TypeScript. There are no special accomodations for this pattern in\r\niTwin.js, so feel free to choose an alternative or adapt this strategy as you see fit.\r\n\r\n### How Do I Update the Protocol Buffer Schema?\r\n\r\n- Make changes to [IModelRpc.proto](./node/IModelRpc.proto).\r\n  See the [proto3 Language Guide](https://developers.google.com/protocol-buffers/docs/proto3).\r\n- From the node subdirectory, run\r\n\r\n```sh\r\nnpm run proto-build\r\n```\r\n\r\n- The protobuf-generated code in node and unity subdirectories will be updated.\r\n\r\n### How Do I Use iModels From iModelHub?\r\n\r\nEdit `IMODELHUB_REQUEST_PROPS` in [IModelHubDownload.ts](./node/src/IModelHubDownload.ts) to replace iTwinId\r\nand iModelId with the appropriate values for your iModel.\r\n\r\nYou will also need to provide a clientId, scope and redirectUri for your application. To register an application,\r\ngo to [https://developer.bentley.com/register/](https://developer.bentley.com/register/).\r\n\r\n- Add \"Digital Twin Management\" as an API Association to get the \"imodels:read\" scope\r\n- Select \"Desktop/Mobile\" as the Application Type\r\n- Enter \"http://localhost:3000/signin-callback\" for Redirect URI\r\n- No logout URI is required\r\n\r\nOnce your application is created, go to its details page and copy/paste the scope, clientId and redirectUri fields\r\ninto `AUTH_CLIENT_CONFIG_PROPS` in [IModelHubDownload.ts](./node/src/IModelHubDownload.ts).\r\n\r\nFinally:\r\n\r\n```sh\r\nnpm run build\r\nnpm run start-from-hub\r\n```\r\n\r\n### What About AR, VR, Mobile and Other Platforms?\r\n\r\nThe example is targeted at producing a desktop executable because it is the most generic and universally\r\naccessible platform for developers.\r\n\r\nHowever, the project code and its dependencies work on most of the platforms that Unity supports. Bentley\r\ndevelopers have deployed this example to the Oculus Rift, HTC Vive, Oculus Quest, Microsoft HoloLens and other\r\ndevices.\r\n\r\n### How Can I Improve Performance With This Example?\r\n\r\n#### GameObjects\r\n\r\nThis example defaults to creating one [Unity GameObject](https://docs.unity3d.com/Manual/class-GameObject.html)\r\nfor every element in the iModel. This is done for the sake of simplifying the code and making it easier to\r\nextend, but is far from ideal for performance.\r\n\r\nSee [ElementMeshCombiner.cs](./unity/Assets/Bentley/Scripts/ElementMeshCombiner.cs) for an\r\nexample of how to combine element meshes for better performance.\r\n\r\n#### Spatial Queries and Other Filters\r\n\r\nIdeally, an application built on iModel.js would leverage the developer's speciality knowledge of their problem\r\ndomain to apply the advanced filtering tools available in iTwin.js. See [ECSQL](https://www.itwinjs.org/learning/ecsql/)\r\nand especially [Spatial Queries](https://www.itwinjs.org/learning/spatialqueries/).\r\n\r\n#### Dynamic LOD\r\n\r\nBecause iModels store original geometry representations and not just meshes, it's easy and fast to request varying levels of detail.\r\nSee [chordTol in ExportGraphicsOptions](https://www.itwinjs.org/reference/core-backend/imodels/exportgraphicsoptions/).\r\n\r\n### How Can I Do XYZ With This Example?\r\n\r\nPlease ask any questions on [GitHub Discussions](https://github.com/iTwin/itwinjs-core/discussions).\r\nWe are actively supporting interested users of this technology.\r\n\r\n## Contributing\r\n\r\n[Contributing to iTwin.js](https://github.com/iTwin/itwinjs-core/blob/master/CONTRIBUTING.md)\r\n\r\n## Acknowledgements\r\n\r\nThe Unity project bundles [WebSocket4Net](https://github.com/kerryjiang/WebSocket4Net) and\r\n[Google Protocol Buffers](https://developers.google.com/protocol-buffers).\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitwin%2Fimodel-unity-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitwin%2Fimodel-unity-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitwin%2Fimodel-unity-example/lists"}