├── .gitignore ├── LICENSE ├── ManagedPlugin ├── AsyncGPUReadbackPlugin.cs ├── AsyncGPUReadbackPlugin.csproj └── bin │ └── Release │ └── netstandard2.0 │ └── AsyncGPUReadbackPlugin.dll ├── NativePlugin ├── Makefile ├── build │ ├── .gitkeep │ └── libAsyncGPUReadbackPlugin.so └── src │ ├── AsyncGPUReadbackPlugin.cpp │ ├── TypeHelpers.hpp │ └── Unity │ ├── IUnityGraphics.h │ ├── IUnityGraphicsD3D11.h │ ├── IUnityGraphicsD3D12.h │ ├── IUnityGraphicsD3D9.h │ ├── IUnityGraphicsMetal.h │ ├── IUnityGraphicsVulkan.h │ └── IUnityInterface.h ├── README.md └── UnityExampleProject ├── .gitignore ├── Assets ├── Plugins.meta ├── Plugins │ ├── libAsyncGPUReadbackPlugin.so │ └── libAsyncGPUReadbackPlugin.so.meta ├── Scenes.meta ├── Scenes │ ├── Scene.unity │ └── Scene.unity.meta ├── Scripts.meta ├── Scripts │ ├── AsyncGPUReadbackPlugin.dll │ ├── AsyncGPUReadbackPlugin.dll.meta │ ├── UsePlugin.cs │ └── UsePlugin.cs.meta ├── b.mat ├── b.mat.meta ├── g.mat ├── g.mat.meta ├── r.mat └── r.mat.meta ├── Packages └── manifest.json └── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── PresetManager.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset └── UnityConnectSettings.asset /.gitignore: -------------------------------------------------------------------------------- 1 | ManagedPlugin/obj 2 | ManagedPlugin/bin 3 | UnityExampleProject/test.png 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Aurélien Labate 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ManagedPlugin/AsyncGPUReadbackPlugin.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System; 4 | using System.Threading; 5 | using System.Runtime.InteropServices; 6 | using UnityEngine.Rendering; 7 | using Unity.Collections; 8 | using Unity.Collections.LowLevel.Unsafe; 9 | 10 | namespace AsyncGPUReadbackPluginNs { 11 | 12 | // Tries to match the official API 13 | public class AsyncGPUReadbackPlugin 14 | { 15 | public static AsyncGPUReadbackPluginRequest Request(Texture src) 16 | { 17 | return new AsyncGPUReadbackPluginRequest(src); 18 | } 19 | } 20 | 21 | public class AsyncGPUReadbackPluginRequest 22 | { 23 | 24 | /// 25 | /// Tell if we are using the plugin api or the official api 26 | /// 27 | private bool usePlugin; 28 | 29 | /// 30 | /// Official api request object used if supported 31 | /// 32 | private AsyncGPUReadbackRequest gpuRequest; 33 | 34 | /// 35 | /// Event Id used to tell what texture is targeted to the render thread 36 | /// 37 | private int eventId; 38 | 39 | /// 40 | /// Is buffer allocated 41 | /// 42 | private bool bufferCreated = false; 43 | 44 | /// 45 | /// Check if the request is done 46 | /// 47 | public bool done 48 | { 49 | get 50 | { 51 | if (usePlugin) { 52 | return isRequestDone(eventId); 53 | } 54 | else { 55 | return gpuRequest.done; 56 | } 57 | } 58 | } 59 | 60 | /// 61 | /// Check if the request has an error 62 | /// 63 | public bool hasError 64 | { 65 | get 66 | { 67 | if (usePlugin) { 68 | return isRequestError(eventId); 69 | } 70 | else { 71 | return gpuRequest.hasError; 72 | } 73 | } 74 | } 75 | 76 | /// 77 | /// Create an AsyncGPUReadbackPluginRequest. 78 | /// Use official AsyncGPUReadback.Request if possible. 79 | /// If not, it tries to use OpenGL specific implementation 80 | /// Warning! Can only be called from render thread yet (not main thread) 81 | /// 82 | /// 83 | /// 84 | public AsyncGPUReadbackPluginRequest(Texture src) 85 | { 86 | if (SystemInfo.supportsAsyncGPUReadback) { 87 | usePlugin = false; 88 | gpuRequest = AsyncGPUReadback.Request(src); 89 | } 90 | else if(isCompatible()) { 91 | usePlugin = true; 92 | int textureId = (int)(src.GetNativeTexturePtr()); 93 | this.eventId = makeRequest_mainThread(textureId, 0); 94 | GL.IssuePluginEvent(getfunction_makeRequest_renderThread(), this.eventId); 95 | } 96 | else { 97 | Debug.LogError("AsyncGPUReadback is not supported on your system."); 98 | } 99 | } 100 | 101 | public unsafe byte[] GetRawData() 102 | { 103 | if (usePlugin) { 104 | // Get data from cpp plugin 105 | void* ptr = null; 106 | int length = 0; 107 | getData_mainThread(this.eventId, ref ptr, ref length); 108 | 109 | // Copy data to a buffer that we own and that will not be deleted 110 | byte[] buffer = new byte[length]; 111 | Marshal.Copy(new IntPtr(ptr), buffer, 0, length); 112 | bufferCreated = true; 113 | 114 | return buffer; 115 | } 116 | else { 117 | return gpuRequest.GetData().ToArray(); 118 | } 119 | } 120 | 121 | /// 122 | /// Has to be called regularly to update request status. 123 | /// Call this from Update() or from a corountine 124 | /// 125 | /// Update is automatic on official api, 126 | /// so we don't call the Update() method except on force mode. 127 | public void Update(bool force = false) 128 | { 129 | if (usePlugin) { 130 | GL.IssuePluginEvent(getfunction_update_renderThread(), this.eventId); 131 | } 132 | else if(force) { 133 | gpuRequest.Update(); 134 | } 135 | } 136 | 137 | /// 138 | /// Has to be called to free the allocated buffer after it has been used 139 | /// 140 | public void Dispose() 141 | { 142 | if (usePlugin && bufferCreated) { 143 | dispose(this.eventId); 144 | } 145 | } 146 | 147 | 148 | [DllImport ("AsyncGPUReadbackPlugin")] 149 | private static extern bool isCompatible(); 150 | [DllImport ("AsyncGPUReadbackPlugin")] 151 | private static extern int makeRequest_mainThread(int texture, int miplevel); 152 | [DllImport ("AsyncGPUReadbackPlugin")] 153 | private static extern IntPtr getfunction_makeRequest_renderThread(); 154 | [DllImport ("AsyncGPUReadbackPlugin")] 155 | private static extern void makeRequest_renderThread(int event_id); 156 | [DllImport ("AsyncGPUReadbackPlugin")] 157 | private static extern IntPtr getfunction_update_renderThread(); 158 | [DllImport ("AsyncGPUReadbackPlugin")] 159 | private static extern unsafe void getData_mainThread(int event_id, ref void* buffer, ref int length); 160 | [DllImport ("AsyncGPUReadbackPlugin")] 161 | private static extern bool isRequestError(int event_id); 162 | [DllImport ("AsyncGPUReadbackPlugin")] 163 | private static extern bool isRequestDone(int event_id); 164 | [DllImport ("AsyncGPUReadbackPlugin")] 165 | private static extern void dispose(int event_id); 166 | } 167 | } -------------------------------------------------------------------------------- /ManagedPlugin/AsyncGPUReadbackPlugin.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | true 6 | 7 | 8 | 9 | /opt/Unity/Editor/Data/Managed/UnityEngine.dll 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ManagedPlugin/bin/Release/netstandard2.0/AsyncGPUReadbackPlugin.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kidapu/AsyncGPUReadbackPlugin/e8d5e52a9adba24bc0f652c39076404e4671e367/ManagedPlugin/bin/Release/netstandard2.0/AsyncGPUReadbackPlugin.dll -------------------------------------------------------------------------------- /NativePlugin/Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Linux build 4 | linux: build/libAsyncGPUReadbackPlugin.so 5 | build/libAsyncGPUReadbackPlugin.so: src/AsyncGPUReadbackPlugin.cpp 6 | g++ -fPIC -std=c++11 -shared src/AsyncGPUReadbackPlugin.cpp -o build/libAsyncGPUReadbackPlugin.so 7 | -------------------------------------------------------------------------------- /NativePlugin/build/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kidapu/AsyncGPUReadbackPlugin/e8d5e52a9adba24bc0f652c39076404e4671e367/NativePlugin/build/.gitkeep -------------------------------------------------------------------------------- /NativePlugin/build/libAsyncGPUReadbackPlugin.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kidapu/AsyncGPUReadbackPlugin/e8d5e52a9adba24bc0f652c39076404e4671e367/NativePlugin/build/libAsyncGPUReadbackPlugin.so -------------------------------------------------------------------------------- /NativePlugin/src/AsyncGPUReadbackPlugin.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "Unity/IUnityInterface.h" 7 | #include "Unity/IUnityGraphics.h" 8 | #include 9 | #include "TypeHelpers.hpp" 10 | 11 | #define DEBUG 1 12 | #ifdef DEBUG 13 | #include 14 | #include 15 | #endif 16 | 17 | struct Task { 18 | GLuint texture; 19 | GLuint fbo; 20 | GLuint pbo; 21 | GLsync fence; 22 | bool initialized = false; 23 | bool error = false; 24 | bool done = false; 25 | void* data; 26 | int miplevel; 27 | int size; 28 | int height; 29 | int width; 30 | int depth; 31 | GLint internal_format; 32 | }; 33 | 34 | static IUnityInterfaces* unity_interfaces = NULL; 35 | static IUnityGraphics* graphics = NULL; 36 | static UnityGfxRenderer renderer = kUnityGfxRendererNull; 37 | 38 | static std::map> tasks; 39 | static std::mutex tasks_mutex; 40 | int next_event_id = 1; 41 | 42 | static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType); 43 | 44 | 45 | 46 | 47 | #ifdef DEBUG 48 | std::ofstream logMain, logRender; 49 | 50 | /** 51 | * @brief Debug log function. Log to /tmp/AsyncGPUReadbackPlugin.log 52 | * 53 | * @param message 54 | */ 55 | void logToFile(std::string message) { 56 | std::ofstream outfile; 57 | outfile.open("/tmp/AsyncGPUReadbackPlugin_main.log", std::ios_base::app); 58 | outfile << "GL CALLBACK: " << message << std::endl; 59 | outfile.close(); 60 | } 61 | 62 | /** 63 | * OpenGL debug message callback 64 | */ 65 | void GLAPIENTRY DebugMessageCallback( GLenum source, 66 | GLenum type, 67 | GLuint id, 68 | GLenum severity, 69 | GLsizei length, 70 | const GLchar* message, 71 | const void* userParam) 72 | { 73 | if (type == GL_DEBUG_TYPE_ERROR) { 74 | logRender << "GL CALLBACK: " << message << std::endl; 75 | } 76 | } 77 | #endif 78 | 79 | /** 80 | * Unity plugin load event 81 | */ 82 | extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API 83 | UnityPluginLoad(IUnityInterfaces* unityInterfaces) 84 | { 85 | #ifdef DEBUG 86 | logMain.open("/tmp/AsyncGPUReadbackPlugin_main.log", std::ios_base::app); 87 | logRender.open("/tmp/AsyncGPUReadbackPlugin_render.log", std::ios_base::app); 88 | 89 | glEnable ( GL_DEBUG_OUTPUT ); 90 | glDebugMessageCallback( DebugMessageCallback, 0 ); 91 | #endif 92 | 93 | unityInterfaces = unityInterfaces; 94 | graphics = unityInterfaces->Get(); 95 | 96 | graphics->RegisterDeviceEventCallback(OnGraphicsDeviceEvent); 97 | 98 | // Run OnGraphicsDeviceEvent(initialize) manually on plugin load 99 | // to not miss the event in case the graphics device is already initialized 100 | OnGraphicsDeviceEvent(kUnityGfxDeviceEventInitialize); 101 | } 102 | 103 | /** 104 | * Unity unload plugin event 105 | */ 106 | extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload() 107 | { 108 | graphics->UnregisterDeviceEventCallback(OnGraphicsDeviceEvent); 109 | } 110 | 111 | /** 112 | * Called for every graphics device events 113 | */ 114 | static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType) 115 | { 116 | // Create graphics API implementation upon initialization 117 | if (eventType == kUnityGfxDeviceEventInitialize) 118 | { 119 | renderer = graphics->GetRenderer(); 120 | } 121 | 122 | // Cleanup graphics API implementation upon shutdown 123 | if (eventType == kUnityGfxDeviceEventShutdown) 124 | { 125 | renderer = kUnityGfxRendererNull; 126 | } 127 | } 128 | 129 | 130 | /** 131 | * Check if plugin is compatible with this system 132 | * This plugin is only compatible with opengl core 133 | */ 134 | extern "C" bool isCompatible() { 135 | return (renderer == kUnityGfxRendererOpenGLCore); 136 | } 137 | 138 | /** 139 | * @brief Init of the make request action. 140 | * You then have to call makeRequest_renderThread 141 | * via GL.IssuePluginEvent with the returned event_id 142 | * 143 | * @param texture OpenGL texture id 144 | * @return event_id to give to other functions and to IssuePluginEvent 145 | */ 146 | extern "C" int makeRequest_mainThread(GLuint texture, int miplevel) { 147 | // Create the task 148 | std::shared_ptr task = std::make_shared(); 149 | task->texture = texture; 150 | task->miplevel = miplevel; 151 | int event_id = next_event_id; 152 | next_event_id++; 153 | 154 | // Save it (lock because possible vector resize) 155 | tasks_mutex.lock(); 156 | tasks[event_id] = task; 157 | tasks_mutex.unlock(); 158 | 159 | return event_id; 160 | } 161 | 162 | /** 163 | * @brief Create a a read texture request 164 | * Has to be called by GL.IssuePluginEvent 165 | * @param event_id containing the the task index, given by makeRequest_mainThread 166 | */ 167 | extern "C" void UNITY_INTERFACE_API makeRequest_renderThread(int event_id) { 168 | // Get task back 169 | tasks_mutex.lock(); 170 | std::shared_ptr task = tasks[event_id]; 171 | tasks_mutex.unlock(); 172 | 173 | // Get texture informations 174 | glBindTexture(GL_TEXTURE_2D, task->texture); 175 | glGetTexLevelParameteriv(GL_TEXTURE_2D, task->miplevel, GL_TEXTURE_WIDTH, &(task->width)); 176 | glGetTexLevelParameteriv(GL_TEXTURE_2D, task->miplevel, GL_TEXTURE_HEIGHT, &(task->height)); 177 | glGetTexLevelParameteriv(GL_TEXTURE_2D, task->miplevel, GL_TEXTURE_DEPTH, &(task->depth)); 178 | glGetTexLevelParameteriv(GL_TEXTURE_2D, task->miplevel, GL_TEXTURE_INTERNAL_FORMAT, &(task->internal_format)); 179 | task->size = task->depth * task->width * task->height * getPixelSizeFromInternalFormat(task->internal_format); 180 | 181 | // Check for errors 182 | if (task->size == 0 183 | || getFormatFromInternalFormat(task->internal_format) == 0 184 | || getTypeFromInternalFormat(task->internal_format) == 0) { 185 | task->error = true; 186 | return; 187 | } 188 | 189 | // Allocate the final data buffer !!! WARNING: free, will have to be done on script side !!!! 190 | task->data = std::malloc(task->size); 191 | 192 | // Create the fbo (frame buffer object) from the given texture 193 | task->fbo; 194 | glGenFramebuffers(1, &(task->fbo)); 195 | 196 | // Bind the texture to the fbo 197 | glBindFramebuffer(GL_FRAMEBUFFER, task->fbo); 198 | glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, task->texture, 0); 199 | 200 | // Create and bind pbo (pixel buffer object) to fbo 201 | task->pbo; 202 | glGenBuffers(1, &(task->pbo)); 203 | glBindBuffer(GL_PIXEL_PACK_BUFFER, task->pbo); 204 | glBufferData(GL_PIXEL_PACK_BUFFER, task->size, 0, GL_DYNAMIC_READ); 205 | 206 | // Start the read request 207 | glReadBuffer(GL_COLOR_ATTACHMENT0); 208 | glReadPixels(0, 0, task->width, task->height, getFormatFromInternalFormat(task->internal_format), getTypeFromInternalFormat(task->internal_format), 0); 209 | 210 | // Unbind buffers 211 | glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); 212 | glBindFramebuffer(GL_FRAMEBUFFER, 0); 213 | 214 | // Fence to know when it's ready 215 | task->fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); 216 | 217 | // Done init 218 | task->initialized = true; 219 | } 220 | extern "C" UnityRenderingEvent UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API getfunction_makeRequest_renderThread() { 221 | return makeRequest_renderThread; 222 | } 223 | 224 | /** 225 | * @brief check if data is ready 226 | * Has to be called by GL.IssuePluginEvent 227 | * @param event_id containing the the task index, given by makeRequest_mainThread 228 | */ 229 | extern "C" void UNITY_INTERFACE_API update_renderThread(int event_id) { 230 | // Get task back 231 | tasks_mutex.lock(); 232 | std::shared_ptr task = tasks[event_id]; 233 | tasks_mutex.unlock(); 234 | 235 | // Check if task has not been already deleted by main thread 236 | if(task == nullptr) { 237 | return; 238 | } 239 | 240 | // Do something only if initialized (thread safety) 241 | if (!task->initialized || task->done) { 242 | return; 243 | } 244 | 245 | // Check fence state 246 | GLint status = 0; 247 | GLsizei length = 0; 248 | glGetSynciv(task->fence, GL_SYNC_STATUS, sizeof(GLint), &length, &status); 249 | if (length <= 0) { 250 | task->error = true; 251 | task->done = true; 252 | return; 253 | } 254 | 255 | // When it's done 256 | if (status == GL_SIGNALED) { 257 | 258 | // Bind back the pbo 259 | glBindBuffer(GL_PIXEL_PACK_BUFFER, task->pbo); 260 | 261 | // Map the buffer and copy it to data 262 | void* ptr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, task->size, GL_MAP_READ_BIT); 263 | std::memcpy(task->data, ptr, task->size); 264 | 265 | // Unmap and unbind 266 | glUnmapBuffer(GL_PIXEL_PACK_BUFFER); 267 | glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); 268 | 269 | // Clear buffers 270 | glDeleteFramebuffers(1, &(task->fbo)); 271 | glDeleteBuffers(1, &(task->pbo)); 272 | glDeleteSync(task->fence); 273 | 274 | // yeah task is done! 275 | task->done = true; 276 | } 277 | } 278 | extern "C" UnityRenderingEvent UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API getfunction_update_renderThread() { 279 | return update_renderThread; 280 | } 281 | 282 | /** 283 | * @brief Get data from the main thread 284 | * @param event_id containing the the task index, given by makeRequest_mainThread 285 | */ 286 | extern "C" void getData_mainThread(int event_id, void** buffer, size_t* length) { 287 | // Get task back 288 | tasks_mutex.lock(); 289 | std::shared_ptr task = tasks[event_id]; 290 | tasks_mutex.unlock(); 291 | 292 | // Do something only if initialized (thread safety) 293 | if (!task->done) { 294 | return; 295 | } 296 | 297 | // Copy the pointer. Warning: free will have to be done on script side 298 | *length = task->size; 299 | *buffer = task->data; 300 | } 301 | 302 | /** 303 | * @brief Check if request is done 304 | * @param event_id containing the the task index, given by makeRequest_mainThread 305 | */ 306 | extern "C" bool isRequestDone(int event_id) { 307 | // Get task back 308 | tasks_mutex.lock(); 309 | std::shared_ptr task = tasks[event_id]; 310 | tasks_mutex.unlock(); 311 | 312 | return task->done; 313 | } 314 | 315 | /** 316 | * @brief Check if request is in error 317 | * @param event_id containing the the task index, given by makeRequest_mainThread 318 | */ 319 | extern "C" bool isRequestError(int event_id) { 320 | // Get task back 321 | tasks_mutex.lock(); 322 | std::shared_ptr task = tasks[event_id]; 323 | tasks_mutex.unlock(); 324 | 325 | return task->error; 326 | } 327 | 328 | /** 329 | * @brief clear data for a frame 330 | * Warning : Buffer is never cleaned, it has to be cleaned from script side 331 | * Has to be called by GL.IssuePluginEvent 332 | * @param event_id containing the the task index, given by makeRequest_mainThread 333 | */ 334 | extern "C" void dispose(int event_id) { 335 | // Remove from tasks 336 | tasks_mutex.lock(); 337 | std::shared_ptr task = tasks[event_id]; 338 | std::free(task->data); 339 | tasks.erase(event_id); 340 | tasks_mutex.unlock(); 341 | } -------------------------------------------------------------------------------- /NativePlugin/src/TypeHelpers.hpp: -------------------------------------------------------------------------------- 1 | 2 | // Opengl includes 3 | #define GL_GLEXT_PROTOTYPES 4 | #ifdef __APPLE__ 5 | #include 6 | #include 7 | #else 8 | #ifdef _WIN32 9 | #include 10 | #endif 11 | #include 12 | #endif 13 | 14 | /** 15 | * @brief Get the size of a pixel in bytes from the given internal format 16 | * 17 | * @param internalFormat 18 | * @return int The size of the pixel in number of bytes. 0 if not found 19 | */ 20 | inline int getPixelSizeFromInternalFormat(int internalFormat) 21 | { 22 | switch(internalFormat) { 23 | case GL_R8: return 8; 24 | case GL_R8_SNORM: return 8; 25 | case GL_R16: return 16; 26 | case GL_R16_SNORM: return 16; 27 | case GL_RG8: return 8 + 8; 28 | case GL_RG8_SNORM: return 8 + 8; 29 | case GL_RG16: return 16 + 16; 30 | case GL_RG16_SNORM: return 16 + 16; 31 | case GL_R3_G3_B2: return 3 + 3 + 2; 32 | case GL_RGB4: return 4 + 4 + 4; 33 | case GL_RGB5: return 5 + 5 + 5; 34 | case GL_RGB8: return 8 + 8 + 8; 35 | case GL_RGB8_SNORM: return 8 + 8 + 8; 36 | case GL_RGB10: return 10 + 10 + 10; 37 | case GL_RGB12: return 12 + 12 + 12; 38 | case GL_RGB16: return 16 + 16 + 16; 39 | case GL_RGB16_SNORM: return 16 + 16 + 16; 40 | case GL_RGBA2: return 2 + 2 + 2 + 2; 41 | case GL_RGBA4: return 4 + 4 + 4 + 4; 42 | case GL_RGB5_A1: return 5 + 5 + 5 + 1; 43 | case GL_RGBA8: return 8 + 8 + 8 + 8; 44 | case GL_RGBA8_SNORM: return 8 + 8 + 8 + 8; 45 | case GL_RGB10_A2: return 10 + 10 + 10 + 2; 46 | case GL_RGBA12: return 12 + 12 + 12 + 12; 47 | case GL_RGBA16: return 16 + 16 + 16 + 16; 48 | case GL_RGBA16_SNORM: return 16 + 16 + 16 + 16; 49 | case GL_SRGB8: return 8 + 8 + 8; 50 | case GL_SRGB8_ALPHA8: return 8 + 8 + 8 + 8; 51 | case GL_R16F: return 16; 52 | case GL_RG16F: return 16 + 16; 53 | case GL_RGB16F: return 16 + 16 + 16; 54 | case GL_RGBA16F: return 16 + 16 + 16 + 16; 55 | case GL_R32F: return 32; 56 | case GL_RG32F: return 32 + 32; 57 | case GL_RGB32F: return 32 + 32 + 32; 58 | case GL_RGBA32F: return 32 + 32 + 32 + 32; 59 | case GL_R11F_G11F_B10F: return 11 + 11 + 10; 60 | case GL_RGB9_E5: return 9 + 9 + 9; 61 | case GL_R8I: return 8; 62 | case GL_R8UI: return 8; 63 | case GL_R16I: return 16; 64 | case GL_R16UI: return 16; 65 | case GL_R32I: return 32; 66 | case GL_R32UI: return 32; 67 | case GL_RG8I: return 8 + 8; 68 | case GL_RG8UI: return 8 + 8; 69 | case GL_RG16I: return 16 + 16; 70 | case GL_RG16UI: return 16 + 16; 71 | case GL_RG32I: return 32 + 32; 72 | case GL_RG32UI: return 32 + 32; 73 | case GL_RGB8I: return 8 + 8 + 8; 74 | case GL_RGB8UI: return 8 + 8 + 8; 75 | case GL_RGB16I: return 16 + 16 + 16; 76 | case GL_RGB16UI: return 16 + 16 + 16; 77 | case GL_RGB32I: return 32 + 32 + 32; 78 | case GL_RGB32UI: return 32 + 32 + 32; 79 | case GL_RGBA8I: return 8 + 8 + 8 + 8; 80 | case GL_RGBA8UI: return 8 + 8 + 8 + 8; 81 | case GL_RGBA16I: return 16 + 16 + 16 + 16; 82 | case GL_RGBA16UI: return 16 + 16 + 16 + 16; 83 | case GL_RGBA32I: return 32 + 32 + 32 + 32; 84 | case GL_RGBA32UI: return 32 + 32 + 32 + 32; 85 | case GL_DEPTH_COMPONENT16: return 16; 86 | case GL_DEPTH_COMPONENT24: return 24; 87 | case GL_DEPTH_COMPONENT32: return 32; 88 | case GL_DEPTH_COMPONENT32F: return 32; 89 | case GL_DEPTH24_STENCIL8: return 24 + 8; 90 | case GL_DEPTH32F_STENCIL8: return 32 + 8; 91 | } 92 | return 0; 93 | } 94 | 95 | /** 96 | * @brief Get the format from internal format 97 | * 98 | * @param internalFormat 99 | * @return int The size of the pixel in number of bytes. 0 if not found 100 | */ 101 | inline int getFormatFromInternalFormat(int internalFormat) 102 | { 103 | switch(internalFormat) { 104 | case GL_R8: 105 | case GL_R8_SNORM: 106 | case GL_R16: 107 | case GL_R16_SNORM: 108 | case GL_R16F: 109 | case GL_R32F: 110 | return GL_RED; 111 | 112 | case GL_R8UI: 113 | case GL_R8I: 114 | case GL_R16UI: 115 | case GL_R16I: 116 | case GL_R32UI: 117 | case GL_R32I: 118 | return GL_RED_INTEGER; 119 | 120 | case GL_RG8: 121 | case GL_RG8_SNORM: 122 | case GL_RG16: 123 | case GL_RG16_SNORM: 124 | case GL_RG16F: 125 | case GL_RG32F: 126 | return GL_RG; 127 | 128 | case GL_RG8UI: 129 | case GL_RG8I: 130 | case GL_RG16UI: 131 | case GL_RG16I: 132 | case GL_RG32UI: 133 | case GL_RG32I: 134 | return GL_RG_INTEGER; 135 | 136 | case GL_RGB8: 137 | case GL_RGB8_SNORM: 138 | case GL_RGB16: 139 | case GL_RGB16_SNORM: 140 | case GL_RGB16F: 141 | case GL_RGB32F: 142 | return GL_RGB; 143 | 144 | case GL_RGB8UI: 145 | case GL_RGB8I: 146 | case GL_RGB16UI: 147 | case GL_RGB16I: 148 | case GL_RGB32UI: 149 | case GL_RGB32I: 150 | return GL_RGB_INTEGER; 151 | 152 | case GL_RGBA8: 153 | case GL_RGBA8_SNORM: 154 | case GL_RGBA16: 155 | case GL_RGBA16_SNORM: 156 | case GL_RGBA16F: 157 | case GL_RGBA32F: 158 | return GL_RGBA; 159 | 160 | case GL_RGBA8UI: 161 | case GL_RGBA8I: 162 | case GL_RGBA16UI: 163 | case GL_RGBA16I: 164 | case GL_RGBA32UI: 165 | case GL_RGBA32I: 166 | return GL_RGBA_INTEGER; 167 | 168 | case GL_SRGB8: 169 | case GL_SRGB8_ALPHA8: 170 | return GL_RGB; 171 | } 172 | return 0; 173 | } 174 | 175 | /** 176 | * @brief Get the best suitable type from internal format 177 | * 178 | * @param internalFormat 179 | * @return int The size of the pixel in number of bytes. 0 if not found 180 | */ 181 | inline int getTypeFromInternalFormat(int internalFormat) 182 | { 183 | switch(internalFormat) { 184 | case GL_R8: 185 | case GL_RG8: 186 | case GL_RGB8: 187 | case GL_RGBA8: 188 | case GL_SRGB8: 189 | case GL_SRGB8_ALPHA8: 190 | case GL_R8UI: 191 | case GL_RG8UI: 192 | case GL_RGB8UI: 193 | case GL_RGBA8UI: 194 | return GL_UNSIGNED_BYTE; 195 | 196 | case GL_R8_SNORM: 197 | case GL_RG8_SNORM: 198 | case GL_RGB8_SNORM: 199 | case GL_RGBA8_SNORM: 200 | case GL_R8I: 201 | case GL_RG8I: 202 | case GL_RGB8I: 203 | case GL_RGBA8I: 204 | return GL_BYTE; 205 | 206 | case GL_R16: 207 | case GL_RG16: 208 | case GL_RGB16: 209 | case GL_RGBA16: 210 | case GL_R16UI: 211 | case GL_RG16UI: 212 | case GL_RGB16UI: 213 | case GL_RGBA16UI: 214 | return GL_UNSIGNED_SHORT; 215 | 216 | case GL_R16_SNORM: 217 | case GL_RG16_SNORM: 218 | case GL_RGB16_SNORM: 219 | case GL_RGBA16_SNORM: 220 | case GL_R16I: 221 | case GL_RG16I: 222 | case GL_RGB16I: 223 | case GL_RGBA16I: 224 | return GL_SHORT; 225 | 226 | case GL_R16F: 227 | case GL_RG16F: 228 | case GL_RGB16F: 229 | case GL_RGBA16F: 230 | return GL_HALF_FLOAT; 231 | 232 | case GL_R32F: 233 | case GL_RG32F: 234 | case GL_RGB32F: 235 | case GL_RGBA32F: 236 | return GL_FLOAT; 237 | 238 | case GL_R32UI: 239 | case GL_RG32UI: 240 | case GL_RGB32UI: 241 | case GL_RGBA32UI: 242 | return GL_UNSIGNED_INT; 243 | 244 | case GL_R32I: 245 | case GL_RG32I: 246 | case GL_RGB32I: 247 | case GL_RGBA32I: 248 | return GL_INT; 249 | } 250 | return 0; 251 | } -------------------------------------------------------------------------------- /NativePlugin/src/Unity/IUnityGraphics.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "IUnityInterface.h" 3 | 4 | typedef enum UnityGfxRenderer 5 | { 6 | //kUnityGfxRendererOpenGL = 0, // Legacy OpenGL, removed 7 | //kUnityGfxRendererD3D9 = 1, // Direct3D 9, removed 8 | kUnityGfxRendererD3D11 = 2, // Direct3D 11 9 | kUnityGfxRendererGCM = 3, // PlayStation 3 10 | kUnityGfxRendererNull = 4, // "null" device (used in batch mode) 11 | kUnityGfxRendererOpenGLES20 = 8, // OpenGL ES 2.0 12 | kUnityGfxRendererOpenGLES30 = 11, // OpenGL ES 3.0 13 | kUnityGfxRendererGXM = 12, // PlayStation Vita 14 | kUnityGfxRendererPS4 = 13, // PlayStation 4 15 | kUnityGfxRendererXboxOne = 14, // Xbox One 16 | kUnityGfxRendererMetal = 16, // iOS Metal 17 | kUnityGfxRendererOpenGLCore = 17, // OpenGL core 18 | kUnityGfxRendererD3D12 = 18, // Direct3D 12 19 | kUnityGfxRendererVulkan = 21, // Vulkan 20 | kUnityGfxRendererNvn = 22, // Nintendo Switch NVN API 21 | kUnityGfxRendererXboxOneD3D12 = 23 // MS XboxOne Direct3D 12 22 | } UnityGfxRenderer; 23 | 24 | typedef enum UnityGfxDeviceEventType 25 | { 26 | kUnityGfxDeviceEventInitialize = 0, 27 | kUnityGfxDeviceEventShutdown = 1, 28 | kUnityGfxDeviceEventBeforeReset = 2, 29 | kUnityGfxDeviceEventAfterReset = 3, 30 | } UnityGfxDeviceEventType; 31 | 32 | typedef void (UNITY_INTERFACE_API * IUnityGraphicsDeviceEventCallback)(UnityGfxDeviceEventType eventType); 33 | 34 | // Should only be used on the rendering thread unless noted otherwise. 35 | UNITY_DECLARE_INTERFACE(IUnityGraphics) 36 | { 37 | UnityGfxRenderer(UNITY_INTERFACE_API * GetRenderer)(); // Thread safe 38 | 39 | // This callback will be called when graphics device is created, destroyed, reset, etc. 40 | // It is possible to miss the kUnityGfxDeviceEventInitialize event in case plugin is loaded at a later time, 41 | // when the graphics device is already created. 42 | void(UNITY_INTERFACE_API * RegisterDeviceEventCallback)(IUnityGraphicsDeviceEventCallback callback); 43 | void(UNITY_INTERFACE_API * UnregisterDeviceEventCallback)(IUnityGraphicsDeviceEventCallback callback); 44 | int(UNITY_INTERFACE_API * ReserveEventIDRange)(int count); // reserves 'count' event IDs. Plugins should use the result as a base index when issuing events back and forth to avoid event id clashes. 45 | }; 46 | UNITY_REGISTER_INTERFACE_GUID(0x7CBA0A9CA4DDB544ULL, 0x8C5AD4926EB17B11ULL, IUnityGraphics) 47 | 48 | 49 | // Certain Unity APIs (GL.IssuePluginEvent, CommandBuffer.IssuePluginEvent) can callback into native plugins. 50 | // Provide them with an address to a function of this signature. 51 | typedef void (UNITY_INTERFACE_API * UnityRenderingEvent)(int eventId); 52 | typedef void (UNITY_INTERFACE_API * UnityRenderingEventAndData)(int eventId, void* data); 53 | -------------------------------------------------------------------------------- /NativePlugin/src/Unity/IUnityGraphicsD3D11.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "IUnityInterface.h" 3 | 4 | 5 | // Should only be used on the rendering thread unless noted otherwise. 6 | UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D11) 7 | { 8 | ID3D11Device* (UNITY_INTERFACE_API * GetDevice)(); 9 | 10 | ID3D11Resource* (UNITY_INTERFACE_API * TextureFromRenderBuffer)(UnityRenderBuffer buffer); 11 | ID3D11Resource* (UNITY_INTERFACE_API * TextureFromNativeTexture)(UnityTextureID texture); 12 | 13 | ID3D11RenderTargetView* (UNITY_INTERFACE_API * RTVFromRenderBuffer)(UnityRenderBuffer surface); 14 | ID3D11ShaderResourceView* (UNITY_INTERFACE_API * SRVFromNativeTexture)(UnityTextureID texture); 15 | }; 16 | 17 | UNITY_REGISTER_INTERFACE_GUID(0xAAB37EF87A87D748ULL, 0xBF76967F07EFB177ULL, IUnityGraphicsD3D11) 18 | -------------------------------------------------------------------------------- /NativePlugin/src/Unity/IUnityGraphicsD3D12.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "IUnityInterface.h" 3 | #ifndef __cplusplus 4 | #include 5 | #endif 6 | 7 | struct RenderSurfaceBase; 8 | typedef struct RenderSurfaceBase* UnityRenderBuffer; 9 | 10 | typedef struct UnityGraphicsD3D12ResourceState UnityGraphicsD3D12ResourceState; 11 | struct UnityGraphicsD3D12ResourceState 12 | { 13 | ID3D12Resource* resource; // Resource to barrier. 14 | D3D12_RESOURCE_STATES expected; // Expected resource state before this command list is executed. 15 | D3D12_RESOURCE_STATES current; // State this resource will be in after this command list is executed. 16 | }; 17 | 18 | typedef struct UnityGraphicsD3D12PhysicalVideoMemoryControlValues UnityGraphicsD3D12PhysicalVideoMemoryControlValues; 19 | struct UnityGraphicsD3D12PhysicalVideoMemoryControlValues // all values in bytes 20 | { 21 | UINT64 reservation; // Minimum required physical memory for an application [default = 64MB]. 22 | UINT64 systemMemoryThreshold; // If free physical video memory drops below this threshold, resources will be allocated in system memory. [default = 64MB] 23 | UINT64 residencyThreshold; // Minimum free physical video memory needed to start bringing evicted resources back after shrunken video memory budget expands again. [default = 128MB] 24 | }; 25 | 26 | // Should only be used on the rendering/submission thread. 27 | UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12v5) 28 | { 29 | ID3D12Device* (UNITY_INTERFACE_API * GetDevice)(); 30 | 31 | ID3D12Fence* (UNITY_INTERFACE_API * GetFrameFence)(); 32 | // Returns the value set on the frame fence once the current frame completes or the GPU is flushed 33 | UINT64(UNITY_INTERFACE_API * GetNextFrameFenceValue)(); 34 | 35 | // Executes a given command list on a worker thread. 36 | // [Optional] Declares expected and post-execution resource states. 37 | // Returns the fence value. 38 | UINT64(UNITY_INTERFACE_API * ExecuteCommandList)(ID3D12GraphicsCommandList * commandList, int stateCount, UnityGraphicsD3D12ResourceState * states); 39 | 40 | void(UNITY_INTERFACE_API * SetPhysicalVideoMemoryControlValues)(const UnityGraphicsD3D12PhysicalVideoMemoryControlValues * memInfo); 41 | 42 | ID3D12CommandQueue* (UNITY_INTERFACE_API * GetCommandQueue)(); 43 | 44 | ID3D12Resource* (UNITY_INTERFACE_API * TextureFromRenderBuffer)(UnityRenderBuffer * rb); 45 | }; 46 | UNITY_REGISTER_INTERFACE_GUID(0xF5C8D8A37D37BC42ULL, 0xB02DFE93B5064A27ULL, IUnityGraphicsD3D12v5) 47 | 48 | // Should only be used on the rendering/submission thread. 49 | UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12v4) 50 | { 51 | ID3D12Device* (UNITY_INTERFACE_API * GetDevice)(); 52 | 53 | ID3D12Fence* (UNITY_INTERFACE_API * GetFrameFence)(); 54 | // Returns the value set on the frame fence once the current frame completes or the GPU is flushed 55 | UINT64(UNITY_INTERFACE_API * GetNextFrameFenceValue)(); 56 | 57 | // Executes a given command list on a worker thread. 58 | // [Optional] Declares expected and post-execution resource states. 59 | // Returns the fence value. 60 | UINT64(UNITY_INTERFACE_API * ExecuteCommandList)(ID3D12GraphicsCommandList * commandList, int stateCount, UnityGraphicsD3D12ResourceState * states); 61 | 62 | void(UNITY_INTERFACE_API * SetPhysicalVideoMemoryControlValues)(const UnityGraphicsD3D12PhysicalVideoMemoryControlValues * memInfo); 63 | 64 | ID3D12CommandQueue* (UNITY_INTERFACE_API * GetCommandQueue)(); 65 | }; 66 | UNITY_REGISTER_INTERFACE_GUID(0X498FFCC13EC94006ULL, 0XB18F8B0FF67778C8ULL, IUnityGraphicsD3D12v4) 67 | 68 | // Should only be used on the rendering/submission thread. 69 | UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12v3) 70 | { 71 | ID3D12Device* (UNITY_INTERFACE_API * GetDevice)(); 72 | 73 | ID3D12Fence* (UNITY_INTERFACE_API * GetFrameFence)(); 74 | // Returns the value set on the frame fence once the current frame completes or the GPU is flushed 75 | UINT64(UNITY_INTERFACE_API * GetNextFrameFenceValue)(); 76 | 77 | // Executes a given command list on a worker thread. 78 | // [Optional] Declares expected and post-execution resource states. 79 | // Returns the fence value. 80 | UINT64(UNITY_INTERFACE_API * ExecuteCommandList)(ID3D12GraphicsCommandList * commandList, int stateCount, UnityGraphicsD3D12ResourceState * states); 81 | 82 | void(UNITY_INTERFACE_API * SetPhysicalVideoMemoryControlValues)(const UnityGraphicsD3D12PhysicalVideoMemoryControlValues * memInfo); 83 | }; 84 | UNITY_REGISTER_INTERFACE_GUID(0x57C3FAFE59E5E843ULL, 0xBF4F5998474BB600ULL, IUnityGraphicsD3D12v3) 85 | 86 | // Should only be used on the rendering/submission thread. 87 | UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12v2) 88 | { 89 | ID3D12Device* (UNITY_INTERFACE_API * GetDevice)(); 90 | 91 | ID3D12Fence* (UNITY_INTERFACE_API * GetFrameFence)(); 92 | // Returns the value set on the frame fence once the current frame completes or the GPU is flushed 93 | UINT64(UNITY_INTERFACE_API * GetNextFrameFenceValue)(); 94 | 95 | // Executes a given command list on a worker thread. 96 | // [Optional] Declares expected and post-execution resource states. 97 | // Returns the fence value. 98 | UINT64(UNITY_INTERFACE_API * ExecuteCommandList)(ID3D12GraphicsCommandList * commandList, int stateCount, UnityGraphicsD3D12ResourceState * states); 99 | }; 100 | UNITY_REGISTER_INTERFACE_GUID(0xEC39D2F18446C745ULL, 0xB1A2626641D6B11FULL, IUnityGraphicsD3D12v2) 101 | 102 | 103 | // Obsolete 104 | UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12) 105 | { 106 | ID3D12Device* (UNITY_INTERFACE_API * GetDevice)(); 107 | ID3D12CommandQueue* (UNITY_INTERFACE_API * GetCommandQueue)(); 108 | 109 | ID3D12Fence* (UNITY_INTERFACE_API * GetFrameFence)(); 110 | // Returns the value set on the frame fence once the current frame completes or the GPU is flushed 111 | UINT64(UNITY_INTERFACE_API * GetNextFrameFenceValue)(); 112 | 113 | // Returns the state a resource will be in after the last command list is executed 114 | bool(UNITY_INTERFACE_API * GetResourceState)(ID3D12Resource * resource, D3D12_RESOURCE_STATES * outState); 115 | // Specifies the state a resource will be in after a plugin command list with resource barriers is executed 116 | void(UNITY_INTERFACE_API * SetResourceState)(ID3D12Resource * resource, D3D12_RESOURCE_STATES state); 117 | }; 118 | UNITY_REGISTER_INTERFACE_GUID(0xEF4CEC88A45F4C4CULL, 0xBD295B6F2A38D9DEULL, IUnityGraphicsD3D12) 119 | -------------------------------------------------------------------------------- /NativePlugin/src/Unity/IUnityGraphicsD3D9.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "IUnityInterface.h" 3 | 4 | // Should only be used on the rendering thread unless noted otherwise. 5 | UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D9) 6 | { 7 | IDirect3D9* (UNITY_INTERFACE_API * GetD3D)(); 8 | IDirect3DDevice9* (UNITY_INTERFACE_API * GetDevice)(); 9 | }; 10 | UNITY_REGISTER_INTERFACE_GUID(0xE90746A523D53C4CULL, 0xAC825B19B6F82AC3ULL, IUnityGraphicsD3D9) 11 | -------------------------------------------------------------------------------- /NativePlugin/src/Unity/IUnityGraphicsMetal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "IUnityInterface.h" 3 | 4 | #ifndef __OBJC__ 5 | #error metal plugin is objc code. 6 | #endif 7 | #ifndef __clang__ 8 | #error only clang compiler is supported. 9 | #endif 10 | 11 | @class NSBundle; 12 | @protocol MTLDevice; 13 | @protocol MTLCommandBuffer; 14 | @protocol MTLCommandEncoder; 15 | @protocol MTLTexture; 16 | @class MTLRenderPassDescriptor; 17 | 18 | // Should only be used on the rendering thread unless noted otherwise. 19 | UNITY_DECLARE_INTERFACE(IUnityGraphicsMetal) 20 | { 21 | NSBundle* (UNITY_INTERFACE_API * MetalBundle)(); 22 | id(UNITY_INTERFACE_API * MetalDevice)(); 23 | 24 | id(UNITY_INTERFACE_API * CurrentCommandBuffer)(); 25 | 26 | // for custom rendering support there are two scenarios: 27 | // you want to use current in-flight MTLCommandEncoder (NB: it might be nil) 28 | id(UNITY_INTERFACE_API * CurrentCommandEncoder)(); 29 | // or you might want to create your own encoder. 30 | // In that case you should end unity's encoder before creating your own and end yours before returning control to unity 31 | void(UNITY_INTERFACE_API * EndCurrentCommandEncoder)(); 32 | 33 | // returns MTLRenderPassDescriptor used to create current MTLCommandEncoder 34 | MTLRenderPassDescriptor* (UNITY_INTERFACE_API * CurrentRenderPassDescriptor)(); 35 | 36 | // converting trampoline UnityRenderBufferHandle into native RenderBuffer 37 | UnityRenderBuffer(UNITY_INTERFACE_API * RenderBufferFromHandle)(void* bufferHandle); 38 | 39 | // access to RenderBuffer's texure 40 | // NB: you pass here *native* RenderBuffer, acquired by calling (C#) RenderBuffer.GetNativeRenderBufferPtr 41 | // AAResolvedTextureFromRenderBuffer will return nil in case of non-AA RenderBuffer or if called for depth RenderBuffer 42 | // StencilTextureFromRenderBuffer will return nil in case of no-stencil RenderBuffer or if called for color RenderBuffer 43 | id(UNITY_INTERFACE_API * TextureFromRenderBuffer)(UnityRenderBuffer buffer); 44 | id(UNITY_INTERFACE_API * AAResolvedTextureFromRenderBuffer)(UnityRenderBuffer buffer); 45 | id(UNITY_INTERFACE_API * StencilTextureFromRenderBuffer)(UnityRenderBuffer buffer); 46 | }; 47 | UNITY_REGISTER_INTERFACE_GUID(0x992C8EAEA95811E5ULL, 0x9A62C4B5B9876117ULL, IUnityGraphicsMetal) 48 | -------------------------------------------------------------------------------- /NativePlugin/src/Unity/IUnityGraphicsVulkan.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "IUnityInterface.h" 3 | 4 | #ifndef UNITY_VULKAN_HEADER 5 | #define UNITY_VULKAN_HEADER 6 | #endif 7 | 8 | #include UNITY_VULKAN_HEADER 9 | 10 | struct UnityVulkanInstance 11 | { 12 | VkPipelineCache pipelineCache; // Unity's pipeline cache is serialized to disk 13 | VkInstance instance; 14 | VkPhysicalDevice physicalDevice; 15 | VkDevice device; 16 | VkQueue graphicsQueue; 17 | PFN_vkGetInstanceProcAddr getInstanceProcAddr; // vkGetInstanceProcAddr of the Vulkan loader, same as the one passed to UnityVulkanInitCallback 18 | unsigned int queueFamilyIndex; 19 | 20 | void* reserved[8]; 21 | }; 22 | 23 | struct UnityVulkanMemory 24 | { 25 | VkDeviceMemory memory; // Vulkan memory handle 26 | VkDeviceSize offset; // offset within memory 27 | VkDeviceSize size; // size in bytes, may be less than the total size of memory; 28 | void* mapped; // pointer to mapped memory block, NULL if not mappable, offset is already applied, remaining block still has at least the given size. 29 | VkMemoryPropertyFlags flags; // Vulkan memory properties 30 | unsigned int memoryTypeIndex; // index into VkPhysicalDeviceMemoryProperties::memoryTypes 31 | 32 | void* reserved[4]; 33 | }; 34 | 35 | enum UnityVulkanResourceAccessMode 36 | { 37 | // Does not imply any pipeline barriers, should only be used to query resource attributes 38 | kUnityVulkanResourceAccess_ObserveOnly, 39 | 40 | // Handles layout transition and barriers 41 | kUnityVulkanResourceAccess_PipelineBarrier, 42 | 43 | // Recreates the backing resource (VkBuffer/VkImage) but keeps the previous one alive if it's in use 44 | kUnityVulkanResourceAccess_Recreate, 45 | }; 46 | 47 | struct UnityVulkanImage 48 | { 49 | UnityVulkanMemory memory; // memory that backs the image 50 | VkImage image; // Vulkan image handle 51 | VkImageLayout layout; // current layout, may change resource access 52 | VkImageAspectFlags aspect; 53 | VkImageUsageFlags usage; 54 | VkFormat format; 55 | VkExtent3D extent; 56 | VkImageTiling tiling; 57 | VkImageType type; 58 | VkSampleCountFlagBits samples; 59 | int layers; 60 | int mipCount; 61 | 62 | void* reserved[4]; 63 | }; 64 | 65 | struct UnityVulkanBuffer 66 | { 67 | UnityVulkanMemory memory; // memory that backs the buffer 68 | VkBuffer buffer; // Vulkan buffer handle 69 | size_t sizeInBytes; // size of the buffer in bytes, may be less than memory size 70 | VkBufferUsageFlags usage; 71 | 72 | void* reserved[4]; 73 | }; 74 | 75 | struct UnityVulkanRecordingState 76 | { 77 | VkCommandBuffer commandBuffer; // Vulkan command buffer that is currently recorded by Unity 78 | VkCommandBufferLevel commandBufferLevel; 79 | VkRenderPass renderPass; // Current render pass, a compatible one or VK_NULL_HANDLE 80 | VkFramebuffer framebuffer; // Current framebuffer or VK_NULL_HANDLE 81 | int subPassIndex; // index of the current sub pass, -1 if not inside a render pass 82 | 83 | // Resource life-time tracking counters, only relevant for resources allocated by the plugin 84 | unsigned long long currentFrameNumber; // can be used to track lifetime of own resources 85 | unsigned long long safeFrameNumber; // all resources that were used in this frame (or before) are safe to be released 86 | 87 | void* reserved[4]; 88 | }; 89 | 90 | enum UnityVulkanEventRenderPassPreCondition 91 | { 92 | // Don't care about the state on Unity's current command buffer 93 | // This is the default precondition 94 | kUnityVulkanRenderPass_DontCare, 95 | 96 | // Make sure that there is currently no RenderPass in progress. 97 | // This allows e.g. resource uploads. 98 | // There are no guarantees about the currently bound descriptor sets, vertex buffers, index buffers and pipeline objects 99 | // Unity does however set dynamic pipeline set VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR based on the current settings 100 | // If used in combination with the SRP RenderPass API the resuls is undefined 101 | kUnityVulkanRenderPass_EnsureInside, 102 | 103 | // Make sure that there is currently no RenderPass in progress. 104 | // Ends the current render pass (and resumes it afterwards if needed) 105 | // If used in combination with the SRP RenderPass API the resuls is undefined. 106 | kUnityVulkanRenderPass_EnsureOutside 107 | }; 108 | 109 | enum UnityVulkanGraphicsQueueAccess 110 | { 111 | // No queue acccess, no work must be submitted to UnityVulkanInstance::graphicsQueue from the plugin event callback 112 | kUnityVulkanGraphicsQueueAccess_DontCare, 113 | 114 | // Make sure that Unity worker threads don't access the Vulkan graphics queue 115 | // This disables access to the current Unity command buffer 116 | kUnityVulkanGraphicsQueueAccess_Allow, 117 | }; 118 | 119 | enum UnityVulkanEventConfigFlagBits 120 | { 121 | kUnityVulkanEventConfigFlag_EnsurePreviousFrameSubmission = (1 << 0), // default: set 122 | kUnityVulkanEventConfigFlag_FlushCommandBuffers = (1 << 1), // submit existing command buffers, default: not set 123 | kUnityVulkanEventConfigFlag_SyncWorkerThreads = (1 << 2), // wait for worker threads to finish, default: not set 124 | kUnityVulkanEventConfigFlag_ModifiesCommandBuffersState = (1 << 3), // should be set when descriptor set bindings, vertex buffer bindings, etc are changed (default: set) 125 | }; 126 | 127 | struct UnityVulkanPluginEventConfig 128 | { 129 | UnityVulkanEventRenderPassPreCondition renderPassPrecondition; 130 | UnityVulkanGraphicsQueueAccess graphicsQueueAccess; 131 | uint32_t flags; 132 | }; 133 | 134 | // Constant that can be used to reference the whole image 135 | const VkImageSubresource* const UnityVulkanWholeImage = NULL; 136 | 137 | // callback function, see InterceptInitialization 138 | typedef PFN_vkGetInstanceProcAddr(UNITY_INTERFACE_API * UnityVulkanInitCallback)(PFN_vkGetInstanceProcAddr getInstanceProcAddr, void* userdata); 139 | 140 | enum UnityVulkanSwapchainMode 141 | { 142 | kUnityVulkanSwapchainMode_Default, 143 | kUnityVulkanSwapchainMode_Offscreen 144 | }; 145 | 146 | struct UnityVulkanSwapchainConfiguration 147 | { 148 | UnityVulkanSwapchainMode mode; 149 | }; 150 | 151 | UNITY_DECLARE_INTERFACE(IUnityGraphicsVulkan) 152 | { 153 | // Vulkan API hooks 154 | // 155 | // Must be called before kUnityGfxDeviceEventInitialize (preload plugin) 156 | // Unity will call 'func' when initializing the Vulkan API 157 | // The 'getInstanceProcAddr' passed to the callback is the function pointer from the Vulkan Loader 158 | // The function pointer returned from UnityVulkanInitCallback may be a different implementation 159 | // This allows intercepting all Vulkan API calls 160 | // 161 | // Most rules/restrictions for implementing a Vulkan layer apply 162 | // Returns true on success, false on failure (typically because it is used too late) 163 | bool(UNITY_INTERFACE_API * InterceptInitialization)(UnityVulkanInitCallback func, void* userdata); 164 | 165 | // Intercept Vulkan API function of the given name with the given function 166 | // In contrast to InterceptInitialization this interface can be used at any time 167 | // The user must handle all synchronization 168 | // Generally this cannot be used to wrap Vulkan object because there might because there may already be non-wrapped instances 169 | // returns the previous function pointer 170 | PFN_vkVoidFunction(UNITY_INTERFACE_API * InterceptVulkanAPI)(const char* name, PFN_vkVoidFunction func); 171 | 172 | // Change the precondition for a specific user-defined event 173 | // Should be called during initialization 174 | void(UNITY_INTERFACE_API * ConfigureEvent)(int eventID, const UnityVulkanPluginEventConfig * pluginEventConfig); 175 | 176 | // Access the Vulkan instance and render queue created by Unity 177 | // UnityVulkanInstance does not change between kUnityGfxDeviceEventInitialize and kUnityGfxDeviceEventShutdown 178 | UnityVulkanInstance(UNITY_INTERFACE_API * Instance)(); 179 | 180 | // Access the current command buffer 181 | // 182 | // outCommandRecordingState is invalidated by any resource access calls. 183 | // queueAccess must be kUnityVulkanGraphicsQueueAccess_Allow when called from from a AccessQueue callback or from a event that is configured for queue access. 184 | // Otherwise queueAccess must be kUnityVulkanGraphicsQueueAccess_DontCare. 185 | bool(UNITY_INTERFACE_API * CommandRecordingState)(UnityVulkanRecordingState * outCommandRecordingState, UnityVulkanGraphicsQueueAccess queueAccess); 186 | 187 | // Resource access 188 | // 189 | // Using the following resource query APIs will mark the resources as used for the current frame. 190 | // Pipeline barriers will be inserted when needed. 191 | // 192 | // Resource access APIs may record commands, so the current UnityVulkanRecordingState is invalidated 193 | // Must not be called from event callbacks configured for queue access (UnityVulkanGraphicsQueueAccess_Allow) 194 | // or from a AccessQueue callback of an event 195 | bool(UNITY_INTERFACE_API * AccessTexture)(void* nativeTexture, const VkImageSubresource * subResource, VkImageLayout layout, 196 | VkPipelineStageFlags pipelineStageFlags, VkAccessFlags accessFlags, UnityVulkanResourceAccessMode accessMode, UnityVulkanImage * outImage); 197 | 198 | bool(UNITY_INTERFACE_API * AccessRenderBufferTexture)(UnityRenderBuffer nativeRenderBuffer, const VkImageSubresource * subResource, VkImageLayout layout, 199 | VkPipelineStageFlags pipelineStageFlags, VkAccessFlags accessFlags, UnityVulkanResourceAccessMode accessMode, UnityVulkanImage * outImage); 200 | 201 | bool(UNITY_INTERFACE_API * AccessRenderBufferResolveTexture)(UnityRenderBuffer nativeRenderBuffer, const VkImageSubresource * subResource, VkImageLayout layout, 202 | VkPipelineStageFlags pipelineStageFlags, VkAccessFlags accessFlags, UnityVulkanResourceAccessMode accessMode, UnityVulkanImage * outImage); 203 | 204 | bool(UNITY_INTERFACE_API * AccessBuffer)(void* nativeBuffer, VkPipelineStageFlags pipelineStageFlags, VkAccessFlags accessFlags, UnityVulkanResourceAccessMode accessMode, UnityVulkanBuffer * outBuffer); 205 | 206 | // Control current state of render pass 207 | // 208 | // Must not be called from event callbacks configured for queue access (UnityVulkanGraphicsQueueAccess_Allow, UnityVulkanGraphicsQueueAccess_FlushAndAllow) 209 | // or from a AccessQueue callback of an event 210 | // See kUnityVulkanRenderPass_EnsureInside, kUnityVulkanRenderPass_EnsureOutside 211 | void(UNITY_INTERFACE_API * EnsureOutsideRenderPass)(); 212 | void(UNITY_INTERFACE_API * EnsureInsideRenderPass)(); 213 | 214 | // Allow command buffer submission to the the Vulkan graphics queue from the given UnityRenderingEventAndData callback. 215 | // This is an alternative to using ConfigureEvent with kUnityVulkanGraphicsQueueAccess_Allow. 216 | // 217 | // eventId and userdata are passed to the callback 218 | // This may or may not be called synchronously or from the submission thread. 219 | // If flush is true then all Unity command buffers of this frame are submitted before UnityQueueAccessCallback 220 | void(UNITY_INTERFACE_API * AccessQueue)(UnityRenderingEventAndData, int eventId, void* userData, bool flush); 221 | 222 | // Configure swapchains that are created by Unity. 223 | // Must be called before kUnityGfxDeviceEventInitialize (preload plugin) 224 | bool(UNITY_INTERFACE_API * ConfigureSwapchain)(const UnityVulkanSwapchainConfiguration * swapChainConfig); 225 | }; 226 | UNITY_REGISTER_INTERFACE_GUID(0x95355348d4ef4e11ULL, 0x9789313dfcffcc87ULL, IUnityGraphicsVulkan) 227 | -------------------------------------------------------------------------------- /NativePlugin/src/Unity/IUnityInterface.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Unity native plugin API 4 | // Compatible with C99 5 | 6 | #if defined(__CYGWIN32__) 7 | #define UNITY_INTERFACE_API __stdcall 8 | #define UNITY_INTERFACE_EXPORT __declspec(dllexport) 9 | #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(WINAPI_FAMILY) 10 | #define UNITY_INTERFACE_API __stdcall 11 | #define UNITY_INTERFACE_EXPORT __declspec(dllexport) 12 | #elif defined(__MACH__) || defined(__ANDROID__) || defined(__linux__) 13 | #define UNITY_INTERFACE_API 14 | #define UNITY_INTERFACE_EXPORT 15 | #else 16 | #define UNITY_INTERFACE_API 17 | #define UNITY_INTERFACE_EXPORT 18 | #endif 19 | 20 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 21 | // IUnityInterface is a registry of interfaces we choose to expose to plugins. 22 | // 23 | // USAGE: 24 | // --------- 25 | // To retrieve an interface a user can do the following from a plugin, assuming they have the header file for the interface: 26 | // 27 | // IMyInterface * ptr = registry->Get(); 28 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 29 | 30 | // Unity Interface GUID 31 | // Ensures global uniqueness. 32 | // 33 | // Template specialization is used to produce a means of looking up a GUID from its interface type at compile time. 34 | // The net result should compile down to passing around the GUID. 35 | // 36 | // UNITY_REGISTER_INTERFACE_GUID should be placed in the header file of any interface definition outside of all namespaces. 37 | // The interface structure and the registration GUID are all that is required to expose the interface to other systems. 38 | struct UnityInterfaceGUID 39 | { 40 | #ifdef __cplusplus 41 | UnityInterfaceGUID(unsigned long long high, unsigned long long low) 42 | : m_GUIDHigh(high) 43 | , m_GUIDLow(low) 44 | { 45 | } 46 | 47 | UnityInterfaceGUID(const UnityInterfaceGUID& other) 48 | { 49 | m_GUIDHigh = other.m_GUIDHigh; 50 | m_GUIDLow = other.m_GUIDLow; 51 | } 52 | 53 | UnityInterfaceGUID& operator=(const UnityInterfaceGUID& other) 54 | { 55 | m_GUIDHigh = other.m_GUIDHigh; 56 | m_GUIDLow = other.m_GUIDLow; 57 | return *this; 58 | } 59 | 60 | bool Equals(const UnityInterfaceGUID& other) const { return m_GUIDHigh == other.m_GUIDHigh && m_GUIDLow == other.m_GUIDLow; } 61 | bool LessThan(const UnityInterfaceGUID& other) const { return m_GUIDHigh < other.m_GUIDHigh || (m_GUIDHigh == other.m_GUIDHigh && m_GUIDLow < other.m_GUIDLow); } 62 | #endif 63 | unsigned long long m_GUIDHigh; 64 | unsigned long long m_GUIDLow; 65 | }; 66 | #ifdef __cplusplus 67 | inline bool operator==(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return left.Equals(right); } 68 | inline bool operator!=(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return !left.Equals(right); } 69 | inline bool operator<(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return left.LessThan(right); } 70 | inline bool operator>(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return right.LessThan(left); } 71 | inline bool operator>=(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return !operator<(left, right); } 72 | inline bool operator<=(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return !operator>(left, right); } 73 | #else 74 | typedef struct UnityInterfaceGUID UnityInterfaceGUID; 75 | #endif 76 | 77 | 78 | #ifdef __cplusplus 79 | #define UNITY_DECLARE_INTERFACE(NAME) \ 80 | struct NAME : IUnityInterface 81 | 82 | // Generic version of GetUnityInterfaceGUID to allow us to specialize it 83 | // per interface below. The generic version has no actual implementation 84 | // on purpose. 85 | // 86 | // If you get errors about return values related to this method then 87 | // you have forgotten to include UNITY_REGISTER_INTERFACE_GUID with 88 | // your interface, or it is not visible at some point when you are 89 | // trying to retrieve or add an interface. 90 | template 91 | inline const UnityInterfaceGUID GetUnityInterfaceGUID(); 92 | 93 | // This is the macro you provide in your public interface header 94 | // outside of a namespace to allow us to map between type and GUID 95 | // without the user having to worry about it when attempting to 96 | // add or retrieve and interface from the registry. 97 | #define UNITY_REGISTER_INTERFACE_GUID(HASHH, HASHL, TYPE) \ 98 | template<> \ 99 | inline const UnityInterfaceGUID GetUnityInterfaceGUID() \ 100 | { \ 101 | return UnityInterfaceGUID(HASHH,HASHL); \ 102 | } 103 | 104 | // Same as UNITY_REGISTER_INTERFACE_GUID but allows the interface to live in 105 | // a particular namespace. As long as the namespace is visible at the time you call 106 | // GetUnityInterfaceGUID< INTERFACETYPE >() or you explicitly qualify it in the template 107 | // calls this will work fine, only the macro here needs to have the additional parameter 108 | #define UNITY_REGISTER_INTERFACE_GUID_IN_NAMESPACE(HASHH, HASHL, TYPE, NAMESPACE) \ 109 | const UnityInterfaceGUID TYPE##_GUID(HASHH, HASHL); \ 110 | template<> \ 111 | inline const UnityInterfaceGUID GetUnityInterfaceGUID< NAMESPACE :: TYPE >() \ 112 | { \ 113 | return UnityInterfaceGUID(HASHH,HASHL); \ 114 | } 115 | 116 | // These macros allow for C compatibility in user code. 117 | #define UNITY_GET_INTERFACE_GUID(TYPE) GetUnityInterfaceGUID< TYPE >() 118 | 119 | 120 | #else 121 | #define UNITY_DECLARE_INTERFACE(NAME) \ 122 | typedef struct NAME NAME; \ 123 | struct NAME 124 | 125 | // NOTE: This has the downside that one some compilers it will not get stripped from all compilation units that 126 | // can see a header containing this constant. However, it's only for C compatibility and thus should have 127 | // minimal impact. 128 | #define UNITY_REGISTER_INTERFACE_GUID(HASHH, HASHL, TYPE) \ 129 | const UnityInterfaceGUID TYPE##_GUID = {HASHH, HASHL}; 130 | 131 | // In general namespaces are going to be a problem for C code any interfaces we expose in a namespace are 132 | // not going to be usable from C. 133 | #define UNITY_REGISTER_INTERFACE_GUID_IN_NAMESPACE(HASHH, HASHL, TYPE, NAMESPACE) 134 | 135 | // These macros allow for C compatibility in user code. 136 | #define UNITY_GET_INTERFACE_GUID(TYPE) TYPE##_GUID 137 | #endif 138 | 139 | // Using this in user code rather than INTERFACES->Get() will be C compatible for those places in plugins where 140 | // this may be needed. Unity code itself does not need this. 141 | #define UNITY_GET_INTERFACE(INTERFACES, TYPE) (TYPE*)INTERFACES->GetInterfaceSplit (UNITY_GET_INTERFACE_GUID(TYPE).m_GUIDHigh, UNITY_GET_INTERFACE_GUID(TYPE).m_GUIDLow); 142 | 143 | 144 | #ifdef __cplusplus 145 | struct IUnityInterface 146 | { 147 | }; 148 | #else 149 | typedef void IUnityInterface; 150 | #endif 151 | 152 | 153 | typedef struct IUnityInterfaces 154 | { 155 | // Returns an interface matching the guid. 156 | // Returns nullptr if the given interface is unavailable in the active Unity runtime. 157 | IUnityInterface* (UNITY_INTERFACE_API * GetInterface)(UnityInterfaceGUID guid); 158 | 159 | // Registers a new interface. 160 | void(UNITY_INTERFACE_API * RegisterInterface)(UnityInterfaceGUID guid, IUnityInterface * ptr); 161 | 162 | // Split APIs for C 163 | IUnityInterface* (UNITY_INTERFACE_API * GetInterfaceSplit)(unsigned long long guidHigh, unsigned long long guidLow); 164 | void(UNITY_INTERFACE_API * RegisterInterfaceSplit)(unsigned long long guidHigh, unsigned long long guidLow, IUnityInterface * ptr); 165 | 166 | #ifdef __cplusplus 167 | // Helper for GetInterface. 168 | template 169 | INTERFACE* Get() 170 | { 171 | return static_cast(GetInterface(GetUnityInterfaceGUID())); 172 | } 173 | 174 | // Helper for RegisterInterface. 175 | template 176 | void Register(IUnityInterface* ptr) 177 | { 178 | RegisterInterface(GetUnityInterfaceGUID(), ptr); 179 | } 180 | 181 | #endif 182 | } IUnityInterfaces; 183 | 184 | 185 | #ifdef __cplusplus 186 | extern "C" { 187 | #endif 188 | 189 | // If exported by a plugin, this function will be called when the plugin is loaded. 190 | void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces); 191 | // If exported by a plugin, this function will be called when the plugin is about to be unloaded. 192 | void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload(); 193 | 194 | #ifdef __cplusplus 195 | } 196 | #endif 197 | 198 | struct RenderSurfaceBase; 199 | typedef struct RenderSurfaceBase* UnityRenderBuffer; 200 | typedef unsigned int UnityTextureID; 201 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AsyncGPUReadbackPlugin 2 | On Unity 2018.2 was introduced a really neat feature: being able get a frame from the gpu to the cpu without blocking the rendering. This feature is really useful for screenshot or network stream of a game camera because we need the frame on the cpu, but we don't care if there is a little delay. 3 | 4 | However this feature is only available on platform supporting DirectX (Windows) and Metal (Apple), but not OpenGL and it's not planned. (source: https://forum.unity.com/threads/graphics-asynchronous-gpu-readback-api.529901/#post-3487735). 5 | 6 | This plugin aim to provide this feature for OpenGL platform. It tries to match the official AsyncGPUReadback as closes as possible to let you easily switch between the plugin or the official API. Under the hood, it use the official API if available on the current platform. 7 | 8 | I created this plugin for a specific use case of running our Unity project under linux, so the plugin is only built for Linux and the plugin API doen't provide all the feature that the official one does (like callback, choosing mipIndex, the destination format, etc.), but if you need one of them, contact me, I will see what we can do. 9 | 10 | ## Use it 11 | ### Install 12 | This plugin has two parts that you need to copy inside your project : 13 | 14 | * `libAsyncGPUReadbackPlugin.so`: It's the linux native plugin that talk directly to OpenGL. 15 | * Copy it from `NativePlugin/build/libAsyncGPUReadbackPlugin.so` to `/Assets/Plugins` in your project. 16 | * `AsyncGPUReadbackPlugin.dll`: It's the C# part of the plugin that interface with the C++ native plugin. (Yes, that dll work under linux, it's just C# inside) 17 | * Copy it from `ManagedPlugin/bin/Release/netstandard2.0/AsyncGPUReadbackPlugin.dll` to anywhere under your `/Assets` folder. 18 | 19 | ### The API 20 | Once you copied the plugin, add `using AsyncGPUReadbackPluginNs` at the beginning of the script where you want to use it. 21 | 22 | #### `static AsyncGPUReadbackPluginRequest AsyncGPUReadbackPlugin.Request(Texture src)` 23 | Same as the official API except that it doesn't implement all the other form. It request the texture from the gpu and return a `AsyncGPUReadbackPluginRequest` object to let you watch the state of the operation and get data back. 24 | 25 | #### `AsyncGPUReadbackPluginRequest` 26 | This object let you see if the request is done and get the data you asked for. 27 | 28 | ##### Attributes 29 | 30 | * `hasError`: True if the request failed 31 | * `done`: True if the request is done and data available 32 | 33 | ##### Methods 34 | 35 | * `NativeArray GetData()`: This let you get the data you asked for in the format you want once it is available. 36 | * `void Update(bool force = false)`: This method has to be called regularly to refresh request state. It differs from the official API because you have to call it manualy if you want the request to finish. It will do nothing if the official API is used and if `force == false`. 37 | * `void Dispose()`: This plugin doens't free its buffer automatically, you have to call this methode manually once you finished working on the data you received from `GetData()`. 38 | 39 | ### Example 40 | To see a working example you can open `UnityExampleProject` with the Unity editor. It saves screenshot of the camera every 60 frames. The script taking screenshot is in `UnityExampleProject/Scripts/UsePlugin.cs` 41 | 42 | ### Differences with the official API 43 | There is two major differences: 44 | 45 | * Update(): You have to manually call Update() regularly 46 | * Dispose(): You have to manually call Dispose() when you finished with the data to avoid memory leak. 47 | 48 | ## Troubleshoots 49 | 50 | ### The type or namespace name 'AsyncGPUReadbackPluginNs' could not be found. Are you missing an assembly reference? 51 | If you click on `AsyncGPUReadbackPlugin.dll` under Unity Editor, you will see 52 | 53 | ``` 54 | Plugin targets .NET 4.x and is marked as compatible with Editor, Editor can only use assemblies targeting .NET 3.5 or lower, please unselect Editor as compatible platform 55 | ``` 56 | 57 | In this case a solution is to change you runtime version in: 58 | 59 | ``` 60 | Editor > Project Settings > Player > Other Settings > Scripting Runtime Version : Set it to '.NET 4.x Equivalent'. 61 | ``` 62 | 63 | ## Build it! 64 | 65 | ### Native plugin 66 | ``` 67 | cd NativePlugin 68 | make # The makefile only work for linux, but you could add other target inside if you want 69 | ``` 70 | You can find the built file under 71 | ``` 72 | NativePlugin/build/libAsyncGPUReadbackPlugin.so 73 | ``` 74 | 75 | ### Managed plugin 76 | You have to install the .Net SDK first to get the `dotnet` command: https://dotnet.microsoft.com/download/linux-package-manager/ubuntu18-04/sdk-current 77 | 78 | ``` 79 | cd ManagedPlugin 80 | dotnet build -c Release 81 | ``` 82 | You can then find the built file under 83 | 84 | ``` 85 | ManagedPlugin/bin/Release/netstandard2.0/AsyncGPUReadbackPlugin.dll 86 | ``` 87 | 88 | ## Thanks 89 | This project was my first Unity plugin and the first time that I played with OpenGL, so I used a lot of internet ressources to do it. Here is some work that helped me: 90 | 91 | * https://github.com/keijiro/AsyncCaptureTest 92 | * https://github.com/SlightlyMad/AsyncTextureReader 93 | * http://www.songho.ca/opengl/gl_pbo.html#pack 94 | -------------------------------------------------------------------------------- /UnityExampleProject/.gitignore: -------------------------------------------------------------------------------- 1 | [Ll]ibrary/ 2 | [Tt]emp/ 3 | [Oo]bj/ 4 | [Bb]uild/ 5 | [Bb]uilds/ 6 | Assets/AssetStoreTools* 7 | 8 | # Visual Studio cache directory 9 | .vs/ 10 | 11 | # Autogenerated VS/MD/Consulo solution and project files 12 | ExportedObj/ 13 | .consulo/ 14 | *.csproj 15 | *.unityproj 16 | *.sln 17 | *.suo 18 | *.tmp 19 | *.user 20 | *.userprefs 21 | *.pidb 22 | *.booproj 23 | *.svd 24 | *.pdb 25 | *.opendb 26 | *.VC.db 27 | 28 | # Unity3D generated meta files 29 | *.pidb.meta 30 | *.pdb.meta 31 | 32 | # Unity3D Generated File On Crash Reports 33 | sysinfo.txt 34 | 35 | # Builds 36 | *.apk 37 | *.unitypackage 38 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b65640716fb1e4d8098eefc4960d2e0d 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/Plugins/libAsyncGPUReadbackPlugin.so: -------------------------------------------------------------------------------- 1 | ../../../NativePlugin/build/libAsyncGPUReadbackPlugin.so -------------------------------------------------------------------------------- /UnityExampleProject/Assets/Plugins/libAsyncGPUReadbackPlugin.so.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6d497f7015a014ee180c43c6c9a14c5e 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | isPreloaded: 0 9 | isOverridable: 0 10 | platformData: 11 | - first: 12 | Any: 13 | second: 14 | enabled: 1 15 | settings: {} 16 | - first: 17 | Editor: Editor 18 | second: 19 | enabled: 0 20 | settings: 21 | DefaultValueInitialized: true 22 | userData: 23 | assetBundleName: 24 | assetBundleVariant: 25 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f704ae4b4f98ae41a0bce26658850c1 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/Scenes/Scene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0.45019352, g: 0.5002334, b: 0.575404, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 0 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_TemporalCoherenceThreshold: 1 54 | m_EnvironmentLightingMode: 0 55 | m_EnableBakedLightmaps: 1 56 | m_EnableRealtimeLightmaps: 0 57 | m_LightmapEditorSettings: 58 | serializedVersion: 10 59 | m_Resolution: 2 60 | m_BakeResolution: 10 61 | m_AtlasSize: 512 62 | m_AO: 0 63 | m_AOMaxDistance: 1 64 | m_CompAOExponent: 1 65 | m_CompAOExponentDirect: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 256 79 | m_PVRBounces: 2 80 | m_PVRFilterTypeDirect: 0 81 | m_PVRFilterTypeIndirect: 0 82 | m_PVRFilterTypeAO: 0 83 | m_PVRFilteringMode: 1 84 | m_PVRCulling: 1 85 | m_PVRFilteringGaussRadiusDirect: 1 86 | m_PVRFilteringGaussRadiusIndirect: 5 87 | m_PVRFilteringGaussRadiusAO: 2 88 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 89 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 90 | m_PVRFilteringAtrousPositionSigmaAO: 1 91 | m_ShowResolutionOverlay: 1 92 | m_LightingDataAsset: {fileID: 0} 93 | m_UseShadowmask: 1 94 | --- !u!196 &4 95 | NavMeshSettings: 96 | serializedVersion: 2 97 | m_ObjectHideFlags: 0 98 | m_BuildSettings: 99 | serializedVersion: 2 100 | agentTypeID: 0 101 | agentRadius: 0.5 102 | agentHeight: 2 103 | agentSlope: 45 104 | agentClimb: 0.4 105 | ledgeDropHeight: 0 106 | maxJumpAcrossDistance: 0 107 | minRegionArea: 2 108 | manualCellSize: 0 109 | cellSize: 0.16666667 110 | manualTileSize: 0 111 | tileSize: 256 112 | accuratePlacement: 0 113 | debug: 114 | m_Flags: 0 115 | m_NavMeshData: {fileID: 0} 116 | --- !u!1 &20561885 117 | GameObject: 118 | m_ObjectHideFlags: 0 119 | m_CorrespondingSourceObject: {fileID: 0} 120 | m_PrefabInternal: {fileID: 0} 121 | serializedVersion: 6 122 | m_Component: 123 | - component: {fileID: 20561886} 124 | - component: {fileID: 20561889} 125 | - component: {fileID: 20561888} 126 | - component: {fileID: 20561887} 127 | m_Layer: 0 128 | m_Name: Cube R 129 | m_TagString: Untagged 130 | m_Icon: {fileID: 0} 131 | m_NavMeshLayer: 0 132 | m_StaticEditorFlags: 0 133 | m_IsActive: 1 134 | --- !u!4 &20561886 135 | Transform: 136 | m_ObjectHideFlags: 0 137 | m_CorrespondingSourceObject: {fileID: 0} 138 | m_PrefabInternal: {fileID: 0} 139 | m_GameObject: {fileID: 20561885} 140 | m_LocalRotation: {x: -0.083019085, y: 0.7004615, z: 0.11833734, w: 0.69889754} 141 | m_LocalPosition: {x: 5.062609, y: 4.564308, z: -1.4620893} 142 | m_LocalScale: {x: 1, y: 1, z: 1} 143 | m_Children: [] 144 | m_Father: {fileID: 0} 145 | m_RootOrder: 2 146 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 147 | --- !u!65 &20561887 148 | BoxCollider: 149 | m_ObjectHideFlags: 0 150 | m_CorrespondingSourceObject: {fileID: 0} 151 | m_PrefabInternal: {fileID: 0} 152 | m_GameObject: {fileID: 20561885} 153 | m_Material: {fileID: 0} 154 | m_IsTrigger: 0 155 | m_Enabled: 1 156 | serializedVersion: 2 157 | m_Size: {x: 1, y: 1, z: 1} 158 | m_Center: {x: 0, y: 0, z: 0} 159 | --- !u!23 &20561888 160 | MeshRenderer: 161 | m_ObjectHideFlags: 0 162 | m_CorrespondingSourceObject: {fileID: 0} 163 | m_PrefabInternal: {fileID: 0} 164 | m_GameObject: {fileID: 20561885} 165 | m_Enabled: 1 166 | m_CastShadows: 1 167 | m_ReceiveShadows: 1 168 | m_DynamicOccludee: 1 169 | m_MotionVectors: 1 170 | m_LightProbeUsage: 1 171 | m_ReflectionProbeUsage: 1 172 | m_RenderingLayerMask: 4294967295 173 | m_Materials: 174 | - {fileID: 2100000, guid: e996f5cabfdfd4f53b5edf237286723f, type: 2} 175 | m_StaticBatchInfo: 176 | firstSubMesh: 0 177 | subMeshCount: 0 178 | m_StaticBatchRoot: {fileID: 0} 179 | m_ProbeAnchor: {fileID: 0} 180 | m_LightProbeVolumeOverride: {fileID: 0} 181 | m_ScaleInLightmap: 1 182 | m_PreserveUVs: 0 183 | m_IgnoreNormalsForChartDetection: 0 184 | m_ImportantGI: 0 185 | m_StitchLightmapSeams: 0 186 | m_SelectedEditorRenderState: 3 187 | m_MinimumChartSize: 4 188 | m_AutoUVMaxDistance: 0.5 189 | m_AutoUVMaxAngle: 89 190 | m_LightmapParameters: {fileID: 0} 191 | m_SortingLayerID: 0 192 | m_SortingLayer: 0 193 | m_SortingOrder: 0 194 | --- !u!33 &20561889 195 | MeshFilter: 196 | m_ObjectHideFlags: 0 197 | m_CorrespondingSourceObject: {fileID: 0} 198 | m_PrefabInternal: {fileID: 0} 199 | m_GameObject: {fileID: 20561885} 200 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 201 | --- !u!1 &170076733 202 | GameObject: 203 | m_ObjectHideFlags: 0 204 | m_CorrespondingSourceObject: {fileID: 0} 205 | m_PrefabInternal: {fileID: 0} 206 | serializedVersion: 6 207 | m_Component: 208 | - component: {fileID: 170076735} 209 | - component: {fileID: 170076734} 210 | m_Layer: 0 211 | m_Name: Directional Light 212 | m_TagString: Untagged 213 | m_Icon: {fileID: 0} 214 | m_NavMeshLayer: 0 215 | m_StaticEditorFlags: 0 216 | m_IsActive: 1 217 | --- !u!108 &170076734 218 | Light: 219 | m_ObjectHideFlags: 0 220 | m_CorrespondingSourceObject: {fileID: 0} 221 | m_PrefabInternal: {fileID: 0} 222 | m_GameObject: {fileID: 170076733} 223 | m_Enabled: 1 224 | serializedVersion: 8 225 | m_Type: 1 226 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 227 | m_Intensity: 1 228 | m_Range: 10 229 | m_SpotAngle: 30 230 | m_CookieSize: 10 231 | m_Shadows: 232 | m_Type: 2 233 | m_Resolution: -1 234 | m_CustomResolution: -1 235 | m_Strength: 1 236 | m_Bias: 0.05 237 | m_NormalBias: 0.4 238 | m_NearPlane: 0.2 239 | m_Cookie: {fileID: 0} 240 | m_DrawHalo: 0 241 | m_Flare: {fileID: 0} 242 | m_RenderMode: 0 243 | m_CullingMask: 244 | serializedVersion: 2 245 | m_Bits: 4294967295 246 | m_Lightmapping: 1 247 | m_LightShadowCasterMode: 0 248 | m_AreaSize: {x: 1, y: 1} 249 | m_BounceIntensity: 1 250 | m_ColorTemperature: 6570 251 | m_UseColorTemperature: 0 252 | m_ShadowRadius: 0 253 | m_ShadowAngle: 0 254 | --- !u!4 &170076735 255 | Transform: 256 | m_ObjectHideFlags: 0 257 | m_CorrespondingSourceObject: {fileID: 0} 258 | m_PrefabInternal: {fileID: 0} 259 | m_GameObject: {fileID: 170076733} 260 | m_LocalRotation: {x: 0.42194957, y: -0.4965706, z: -0.023763597, w: 0.7581632} 261 | m_LocalPosition: {x: 10.4, y: 11.29, z: -2.03} 262 | m_LocalScale: {x: 1, y: 1, z: 1} 263 | m_Children: [] 264 | m_Father: {fileID: 0} 265 | m_RootOrder: 0 266 | m_LocalEulerAnglesHint: {x: 38.04, y: -78.965004, z: -35.298} 267 | --- !u!1 &544430954 268 | GameObject: 269 | m_ObjectHideFlags: 0 270 | m_CorrespondingSourceObject: {fileID: 0} 271 | m_PrefabInternal: {fileID: 0} 272 | serializedVersion: 6 273 | m_Component: 274 | - component: {fileID: 544430955} 275 | - component: {fileID: 544430957} 276 | - component: {fileID: 544430956} 277 | m_Layer: 0 278 | m_Name: Camera 279 | m_TagString: Untagged 280 | m_Icon: {fileID: 0} 281 | m_NavMeshLayer: 0 282 | m_StaticEditorFlags: 0 283 | m_IsActive: 1 284 | --- !u!4 &544430955 285 | Transform: 286 | m_ObjectHideFlags: 0 287 | m_CorrespondingSourceObject: {fileID: 0} 288 | m_PrefabInternal: {fileID: 0} 289 | m_GameObject: {fileID: 544430954} 290 | m_LocalRotation: {x: -0.6435459, y: -0.35615987, z: 0.60144454, w: -0.31187057} 291 | m_LocalPosition: {x: 7.3796563, y: 7.709575, z: 0.3250594} 292 | m_LocalScale: {x: 1, y: 1, z: 1} 293 | m_Children: [] 294 | m_Father: {fileID: 0} 295 | m_RootOrder: 1 296 | m_LocalEulerAnglesHint: {x: -217.368, y: 0.10699463, z: -1.5759888} 297 | --- !u!114 &544430956 298 | MonoBehaviour: 299 | m_ObjectHideFlags: 0 300 | m_CorrespondingSourceObject: {fileID: 0} 301 | m_PrefabInternal: {fileID: 0} 302 | m_GameObject: {fileID: 544430954} 303 | m_Enabled: 1 304 | m_EditorHideFlags: 0 305 | m_Script: {fileID: 11500000, guid: 47db193163fd0473a9d3662fc2bbd11b, type: 3} 306 | m_Name: 307 | m_EditorClassIdentifier: 308 | --- !u!20 &544430957 309 | Camera: 310 | m_ObjectHideFlags: 0 311 | m_CorrespondingSourceObject: {fileID: 0} 312 | m_PrefabInternal: {fileID: 0} 313 | m_GameObject: {fileID: 544430954} 314 | m_Enabled: 1 315 | serializedVersion: 2 316 | m_ClearFlags: 1 317 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 318 | m_projectionMatrixMode: 1 319 | m_SensorSize: {x: 36, y: 24} 320 | m_LensShift: {x: 0, y: 0} 321 | m_FocalLength: 50 322 | m_NormalizedViewPortRect: 323 | serializedVersion: 2 324 | x: 0 325 | y: 0 326 | width: 1 327 | height: 1 328 | near clip plane: 0.3 329 | far clip plane: 10 330 | field of view: 31.8 331 | orthographic: 0 332 | orthographic size: 5 333 | m_Depth: 0 334 | m_CullingMask: 335 | serializedVersion: 2 336 | m_Bits: 4294967295 337 | m_RenderingPath: -1 338 | m_TargetTexture: {fileID: 0} 339 | m_TargetDisplay: 0 340 | m_TargetEye: 3 341 | m_HDR: 1 342 | m_AllowMSAA: 1 343 | m_AllowDynamicResolution: 0 344 | m_ForceIntoRT: 0 345 | m_OcclusionCulling: 1 346 | m_StereoConvergence: 10 347 | m_StereoSeparation: 0.022 348 | --- !u!1 &1657501090 349 | GameObject: 350 | m_ObjectHideFlags: 0 351 | m_CorrespondingSourceObject: {fileID: 0} 352 | m_PrefabInternal: {fileID: 0} 353 | serializedVersion: 6 354 | m_Component: 355 | - component: {fileID: 1657501091} 356 | - component: {fileID: 1657501094} 357 | - component: {fileID: 1657501093} 358 | - component: {fileID: 1657501092} 359 | m_Layer: 0 360 | m_Name: Cube G 361 | m_TagString: Untagged 362 | m_Icon: {fileID: 0} 363 | m_NavMeshLayer: 0 364 | m_StaticEditorFlags: 0 365 | m_IsActive: 1 366 | --- !u!4 &1657501091 367 | Transform: 368 | m_ObjectHideFlags: 0 369 | m_CorrespondingSourceObject: {fileID: 0} 370 | m_PrefabInternal: {fileID: 0} 371 | m_GameObject: {fileID: 1657501090} 372 | m_LocalRotation: {x: -0.083019085, y: 0.7004615, z: 0.11833734, w: 0.69889754} 373 | m_LocalPosition: {x: 5.1004524, y: 4.498183, z: 0.026172161} 374 | m_LocalScale: {x: 1, y: 1, z: 1} 375 | m_Children: [] 376 | m_Father: {fileID: 0} 377 | m_RootOrder: 3 378 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 379 | --- !u!65 &1657501092 380 | BoxCollider: 381 | m_ObjectHideFlags: 0 382 | m_CorrespondingSourceObject: {fileID: 0} 383 | m_PrefabInternal: {fileID: 0} 384 | m_GameObject: {fileID: 1657501090} 385 | m_Material: {fileID: 0} 386 | m_IsTrigger: 0 387 | m_Enabled: 1 388 | serializedVersion: 2 389 | m_Size: {x: 1, y: 1, z: 1} 390 | m_Center: {x: 0, y: 0, z: 0} 391 | --- !u!23 &1657501093 392 | MeshRenderer: 393 | m_ObjectHideFlags: 0 394 | m_CorrespondingSourceObject: {fileID: 0} 395 | m_PrefabInternal: {fileID: 0} 396 | m_GameObject: {fileID: 1657501090} 397 | m_Enabled: 1 398 | m_CastShadows: 1 399 | m_ReceiveShadows: 1 400 | m_DynamicOccludee: 1 401 | m_MotionVectors: 1 402 | m_LightProbeUsage: 1 403 | m_ReflectionProbeUsage: 1 404 | m_RenderingLayerMask: 4294967295 405 | m_Materials: 406 | - {fileID: 2100000, guid: 78036511e4c0b4f2c9c93a1edf0499f4, type: 2} 407 | m_StaticBatchInfo: 408 | firstSubMesh: 0 409 | subMeshCount: 0 410 | m_StaticBatchRoot: {fileID: 0} 411 | m_ProbeAnchor: {fileID: 0} 412 | m_LightProbeVolumeOverride: {fileID: 0} 413 | m_ScaleInLightmap: 1 414 | m_PreserveUVs: 0 415 | m_IgnoreNormalsForChartDetection: 0 416 | m_ImportantGI: 0 417 | m_StitchLightmapSeams: 0 418 | m_SelectedEditorRenderState: 3 419 | m_MinimumChartSize: 4 420 | m_AutoUVMaxDistance: 0.5 421 | m_AutoUVMaxAngle: 89 422 | m_LightmapParameters: {fileID: 0} 423 | m_SortingLayerID: 0 424 | m_SortingLayer: 0 425 | m_SortingOrder: 0 426 | --- !u!33 &1657501094 427 | MeshFilter: 428 | m_ObjectHideFlags: 0 429 | m_CorrespondingSourceObject: {fileID: 0} 430 | m_PrefabInternal: {fileID: 0} 431 | m_GameObject: {fileID: 1657501090} 432 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 433 | --- !u!1 &1667460925 434 | GameObject: 435 | m_ObjectHideFlags: 0 436 | m_CorrespondingSourceObject: {fileID: 0} 437 | m_PrefabInternal: {fileID: 0} 438 | serializedVersion: 6 439 | m_Component: 440 | - component: {fileID: 1667460926} 441 | - component: {fileID: 1667460929} 442 | - component: {fileID: 1667460928} 443 | - component: {fileID: 1667460927} 444 | m_Layer: 0 445 | m_Name: Cube B 446 | m_TagString: Untagged 447 | m_Icon: {fileID: 0} 448 | m_NavMeshLayer: 0 449 | m_StaticEditorFlags: 0 450 | m_IsActive: 1 451 | --- !u!4 &1667460926 452 | Transform: 453 | m_ObjectHideFlags: 0 454 | m_CorrespondingSourceObject: {fileID: 0} 455 | m_PrefabInternal: {fileID: 0} 456 | m_GameObject: {fileID: 1667460925} 457 | m_LocalRotation: {x: -0.083019085, y: 0.7004615, z: 0.11833734, w: 0.69889754} 458 | m_LocalPosition: {x: 5.112514, y: 4.4344893, z: 1.3215508} 459 | m_LocalScale: {x: 1, y: 1, z: 1} 460 | m_Children: [] 461 | m_Father: {fileID: 0} 462 | m_RootOrder: 4 463 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 464 | --- !u!65 &1667460927 465 | BoxCollider: 466 | m_ObjectHideFlags: 0 467 | m_CorrespondingSourceObject: {fileID: 0} 468 | m_PrefabInternal: {fileID: 0} 469 | m_GameObject: {fileID: 1667460925} 470 | m_Material: {fileID: 0} 471 | m_IsTrigger: 0 472 | m_Enabled: 1 473 | serializedVersion: 2 474 | m_Size: {x: 1, y: 1, z: 1} 475 | m_Center: {x: 0, y: 0, z: 0} 476 | --- !u!23 &1667460928 477 | MeshRenderer: 478 | m_ObjectHideFlags: 0 479 | m_CorrespondingSourceObject: {fileID: 0} 480 | m_PrefabInternal: {fileID: 0} 481 | m_GameObject: {fileID: 1667460925} 482 | m_Enabled: 1 483 | m_CastShadows: 1 484 | m_ReceiveShadows: 1 485 | m_DynamicOccludee: 1 486 | m_MotionVectors: 1 487 | m_LightProbeUsage: 1 488 | m_ReflectionProbeUsage: 1 489 | m_RenderingLayerMask: 4294967295 490 | m_Materials: 491 | - {fileID: 2100000, guid: f83eee9781cd14c97918bf5f362beb27, type: 2} 492 | m_StaticBatchInfo: 493 | firstSubMesh: 0 494 | subMeshCount: 0 495 | m_StaticBatchRoot: {fileID: 0} 496 | m_ProbeAnchor: {fileID: 0} 497 | m_LightProbeVolumeOverride: {fileID: 0} 498 | m_ScaleInLightmap: 1 499 | m_PreserveUVs: 0 500 | m_IgnoreNormalsForChartDetection: 0 501 | m_ImportantGI: 0 502 | m_StitchLightmapSeams: 0 503 | m_SelectedEditorRenderState: 3 504 | m_MinimumChartSize: 4 505 | m_AutoUVMaxDistance: 0.5 506 | m_AutoUVMaxAngle: 89 507 | m_LightmapParameters: {fileID: 0} 508 | m_SortingLayerID: 0 509 | m_SortingLayer: 0 510 | m_SortingOrder: 0 511 | --- !u!33 &1667460929 512 | MeshFilter: 513 | m_ObjectHideFlags: 0 514 | m_CorrespondingSourceObject: {fileID: 0} 515 | m_PrefabInternal: {fileID: 0} 516 | m_GameObject: {fileID: 1667460925} 517 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 518 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/Scenes/Scene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bb509b92e73fe4439839f06c1aec0245 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d79f5709fc3a4490dbd7f544e1e6bf3f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/Scripts/AsyncGPUReadbackPlugin.dll: -------------------------------------------------------------------------------- 1 | ../../../ManagedPlugin/bin/Release/netstandard2.0/AsyncGPUReadbackPlugin.dll -------------------------------------------------------------------------------- /UnityExampleProject/Assets/Scripts/AsyncGPUReadbackPlugin.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 925ba0389c98b416d9f7f66afedc6ca6 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | isPreloaded: 0 9 | isOverridable: 0 10 | platformData: 11 | - first: 12 | '': Any 13 | second: 14 | enabled: 0 15 | settings: 16 | Exclude Editor: 0 17 | Exclude Linux: 0 18 | Exclude Linux64: 0 19 | Exclude LinuxUniversal: 0 20 | Exclude OSXUniversal: 0 21 | Exclude Win: 0 22 | Exclude Win64: 0 23 | - first: 24 | Any: 25 | second: 26 | enabled: 1 27 | settings: {} 28 | - first: 29 | Editor: Editor 30 | second: 31 | enabled: 1 32 | settings: 33 | CPU: AnyCPU 34 | DefaultValueInitialized: true 35 | OS: AnyOS 36 | - first: 37 | Facebook: Win 38 | second: 39 | enabled: 0 40 | settings: 41 | CPU: AnyCPU 42 | - first: 43 | Facebook: Win64 44 | second: 45 | enabled: 0 46 | settings: 47 | CPU: AnyCPU 48 | - first: 49 | Standalone: Linux 50 | second: 51 | enabled: 1 52 | settings: 53 | CPU: x86 54 | - first: 55 | Standalone: Linux64 56 | second: 57 | enabled: 1 58 | settings: 59 | CPU: x86_64 60 | - first: 61 | Standalone: LinuxUniversal 62 | second: 63 | enabled: 1 64 | settings: {} 65 | - first: 66 | Standalone: OSXUniversal 67 | second: 68 | enabled: 1 69 | settings: 70 | CPU: AnyCPU 71 | - first: 72 | Standalone: Win 73 | second: 74 | enabled: 1 75 | settings: 76 | CPU: AnyCPU 77 | - first: 78 | Standalone: Win64 79 | second: 80 | enabled: 1 81 | settings: 82 | CPU: AnyCPU 83 | - first: 84 | Windows Store Apps: WindowsStoreApps 85 | second: 86 | enabled: 0 87 | settings: 88 | CPU: AnyCPU 89 | userData: 90 | assetBundleName: 91 | assetBundleVariant: 92 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/Scripts/UsePlugin.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System; 5 | using System.Runtime.InteropServices; 6 | using Unity.Collections; 7 | using System.IO; 8 | using AsyncGPUReadbackPluginNs; 9 | 10 | /// 11 | /// Exemple of usage inspirated from https://github.com/keijiro/AsyncCaptureTest/blob/master/Assets/AsyncCapture.cs 12 | /// 13 | public class UsePlugin : MonoBehaviour { 14 | 15 | Queue _requests = new Queue(); 16 | 17 | void Update() 18 | { 19 | while (_requests.Count > 0) 20 | { 21 | var req = _requests.Peek(); 22 | 23 | // You need to explicitly ask for an update regularly 24 | req.Update(); 25 | 26 | if (req.hasError) 27 | { 28 | Debug.LogError("GPU readback error detected."); 29 | req.Dispose(); 30 | _requests.Dequeue(); 31 | } 32 | else if (req.done) 33 | { 34 | // Get data from the request when it's done 35 | byte[] buffer = req.GetRawData(); 36 | 37 | // Save the image 38 | Camera cam = GetComponent(); 39 | SaveBitmap(buffer, cam.pixelWidth, cam.pixelHeight); 40 | 41 | // You need to explicitly Dispose data after using them 42 | req.Dispose(); 43 | 44 | _requests.Dequeue(); 45 | } 46 | else 47 | { 48 | break; 49 | } 50 | } 51 | } 52 | 53 | void OnRenderImage(RenderTexture source, RenderTexture destination) 54 | { 55 | Graphics.Blit(source, destination); 56 | 57 | if (Time.frameCount % 60 == 0) 58 | { 59 | if (_requests.Count < 8) 60 | _requests.Enqueue(AsyncGPUReadbackPlugin.Request(source)); 61 | else 62 | Debug.LogWarning("Too many requests."); 63 | } 64 | } 65 | 66 | void SaveBitmap(byte[] buffer, int width, int height) 67 | { 68 | Debug.Log("Write to file"); 69 | var tex = new Texture2D(width, height, TextureFormat.RGBAHalf, false); 70 | tex.LoadRawTextureData(buffer); 71 | tex.Apply(); 72 | File.WriteAllBytes("test.png", ImageConversion.EncodeToPNG(tex)); 73 | Destroy(tex); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/Scripts/UsePlugin.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 47db193163fd0473a9d3662fc2bbd11b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/b.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: b 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: 12 | m_LightmapFlags: 4 13 | m_EnableInstancingVariants: 0 14 | m_DoubleSidedGI: 0 15 | m_CustomRenderQueue: -1 16 | stringTagMap: {} 17 | disabledShaderPasses: [] 18 | m_SavedProperties: 19 | serializedVersion: 3 20 | m_TexEnvs: 21 | - _BumpMap: 22 | m_Texture: {fileID: 0} 23 | m_Scale: {x: 1, y: 1} 24 | m_Offset: {x: 0, y: 0} 25 | - _DetailAlbedoMap: 26 | m_Texture: {fileID: 0} 27 | m_Scale: {x: 1, y: 1} 28 | m_Offset: {x: 0, y: 0} 29 | - _DetailMask: 30 | m_Texture: {fileID: 0} 31 | m_Scale: {x: 1, y: 1} 32 | m_Offset: {x: 0, y: 0} 33 | - _DetailNormalMap: 34 | m_Texture: {fileID: 0} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | - _EmissionMap: 38 | m_Texture: {fileID: 0} 39 | m_Scale: {x: 1, y: 1} 40 | m_Offset: {x: 0, y: 0} 41 | - _MainTex: 42 | m_Texture: {fileID: 0} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | - _MetallicGlossMap: 46 | m_Texture: {fileID: 0} 47 | m_Scale: {x: 1, y: 1} 48 | m_Offset: {x: 0, y: 0} 49 | - _OcclusionMap: 50 | m_Texture: {fileID: 0} 51 | m_Scale: {x: 1, y: 1} 52 | m_Offset: {x: 0, y: 0} 53 | - _ParallaxMap: 54 | m_Texture: {fileID: 0} 55 | m_Scale: {x: 1, y: 1} 56 | m_Offset: {x: 0, y: 0} 57 | m_Floats: 58 | - _BumpScale: 1 59 | - _Cutoff: 0.5 60 | - _DetailNormalMapScale: 1 61 | - _DstBlend: 0 62 | - _GlossMapScale: 1 63 | - _Glossiness: 0.5 64 | - _GlossyReflections: 1 65 | - _Metallic: 0 66 | - _Mode: 0 67 | - _OcclusionStrength: 1 68 | - _Parallax: 0.02 69 | - _SmoothnessTextureChannel: 0 70 | - _SpecularHighlights: 1 71 | - _SrcBlend: 1 72 | - _UVSec: 0 73 | - _ZWrite: 1 74 | m_Colors: 75 | - _Color: {r: 0, g: 0, b: 1, a: 1} 76 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 77 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/b.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f83eee9781cd14c97918bf5f362beb27 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/g.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: g 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: 12 | m_LightmapFlags: 4 13 | m_EnableInstancingVariants: 0 14 | m_DoubleSidedGI: 0 15 | m_CustomRenderQueue: -1 16 | stringTagMap: {} 17 | disabledShaderPasses: [] 18 | m_SavedProperties: 19 | serializedVersion: 3 20 | m_TexEnvs: 21 | - _BumpMap: 22 | m_Texture: {fileID: 0} 23 | m_Scale: {x: 1, y: 1} 24 | m_Offset: {x: 0, y: 0} 25 | - _DetailAlbedoMap: 26 | m_Texture: {fileID: 0} 27 | m_Scale: {x: 1, y: 1} 28 | m_Offset: {x: 0, y: 0} 29 | - _DetailMask: 30 | m_Texture: {fileID: 0} 31 | m_Scale: {x: 1, y: 1} 32 | m_Offset: {x: 0, y: 0} 33 | - _DetailNormalMap: 34 | m_Texture: {fileID: 0} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | - _EmissionMap: 38 | m_Texture: {fileID: 0} 39 | m_Scale: {x: 1, y: 1} 40 | m_Offset: {x: 0, y: 0} 41 | - _MainTex: 42 | m_Texture: {fileID: 0} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | - _MetallicGlossMap: 46 | m_Texture: {fileID: 0} 47 | m_Scale: {x: 1, y: 1} 48 | m_Offset: {x: 0, y: 0} 49 | - _OcclusionMap: 50 | m_Texture: {fileID: 0} 51 | m_Scale: {x: 1, y: 1} 52 | m_Offset: {x: 0, y: 0} 53 | - _ParallaxMap: 54 | m_Texture: {fileID: 0} 55 | m_Scale: {x: 1, y: 1} 56 | m_Offset: {x: 0, y: 0} 57 | m_Floats: 58 | - _BumpScale: 1 59 | - _Cutoff: 0.5 60 | - _DetailNormalMapScale: 1 61 | - _DstBlend: 0 62 | - _GlossMapScale: 1 63 | - _Glossiness: 0.5 64 | - _GlossyReflections: 1 65 | - _Metallic: 0 66 | - _Mode: 0 67 | - _OcclusionStrength: 1 68 | - _Parallax: 0.02 69 | - _SmoothnessTextureChannel: 0 70 | - _SpecularHighlights: 1 71 | - _SrcBlend: 1 72 | - _UVSec: 0 73 | - _ZWrite: 1 74 | m_Colors: 75 | - _Color: {r: 0, g: 1, b: 0, a: 1} 76 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 77 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/g.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 78036511e4c0b4f2c9c93a1edf0499f4 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/r.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: r 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: 12 | m_LightmapFlags: 4 13 | m_EnableInstancingVariants: 0 14 | m_DoubleSidedGI: 0 15 | m_CustomRenderQueue: -1 16 | stringTagMap: {} 17 | disabledShaderPasses: [] 18 | m_SavedProperties: 19 | serializedVersion: 3 20 | m_TexEnvs: 21 | - _BumpMap: 22 | m_Texture: {fileID: 0} 23 | m_Scale: {x: 1, y: 1} 24 | m_Offset: {x: 0, y: 0} 25 | - _DetailAlbedoMap: 26 | m_Texture: {fileID: 0} 27 | m_Scale: {x: 1, y: 1} 28 | m_Offset: {x: 0, y: 0} 29 | - _DetailMask: 30 | m_Texture: {fileID: 0} 31 | m_Scale: {x: 1, y: 1} 32 | m_Offset: {x: 0, y: 0} 33 | - _DetailNormalMap: 34 | m_Texture: {fileID: 0} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | - _EmissionMap: 38 | m_Texture: {fileID: 0} 39 | m_Scale: {x: 1, y: 1} 40 | m_Offset: {x: 0, y: 0} 41 | - _MainTex: 42 | m_Texture: {fileID: 0} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | - _MetallicGlossMap: 46 | m_Texture: {fileID: 0} 47 | m_Scale: {x: 1, y: 1} 48 | m_Offset: {x: 0, y: 0} 49 | - _OcclusionMap: 50 | m_Texture: {fileID: 0} 51 | m_Scale: {x: 1, y: 1} 52 | m_Offset: {x: 0, y: 0} 53 | - _ParallaxMap: 54 | m_Texture: {fileID: 0} 55 | m_Scale: {x: 1, y: 1} 56 | m_Offset: {x: 0, y: 0} 57 | m_Floats: 58 | - _BumpScale: 1 59 | - _Cutoff: 0.5 60 | - _DetailNormalMapScale: 1 61 | - _DstBlend: 0 62 | - _GlossMapScale: 1 63 | - _Glossiness: 0.5 64 | - _GlossyReflections: 1 65 | - _Metallic: 0 66 | - _Mode: 0 67 | - _OcclusionStrength: 1 68 | - _Parallax: 0.02 69 | - _SmoothnessTextureChannel: 0 70 | - _SpecularHighlights: 1 71 | - _SrcBlend: 1 72 | - _UVSec: 0 73 | - _ZWrite: 1 74 | m_Colors: 75 | - _Color: {r: 1, g: 0, b: 0, a: 1} 76 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 77 | -------------------------------------------------------------------------------- /UnityExampleProject/Assets/r.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e996f5cabfdfd4f53b5edf237286723f 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /UnityExampleProject/Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.ads": "2.0.8", 4 | "com.unity.analytics": "2.0.16", 5 | "com.unity.package-manager-ui": "1.9.11", 6 | "com.unity.purchasing": "2.0.3", 7 | "com.unity.textmeshpro": "1.2.4", 8 | "com.unity.modules.ai": "1.0.0", 9 | "com.unity.modules.animation": "1.0.0", 10 | "com.unity.modules.assetbundle": "1.0.0", 11 | "com.unity.modules.audio": "1.0.0", 12 | "com.unity.modules.cloth": "1.0.0", 13 | "com.unity.modules.director": "1.0.0", 14 | "com.unity.modules.imageconversion": "1.0.0", 15 | "com.unity.modules.imgui": "1.0.0", 16 | "com.unity.modules.jsonserialize": "1.0.0", 17 | "com.unity.modules.particlesystem": "1.0.0", 18 | "com.unity.modules.physics": "1.0.0", 19 | "com.unity.modules.physics2d": "1.0.0", 20 | "com.unity.modules.screencapture": "1.0.0", 21 | "com.unity.modules.terrain": "1.0.0", 22 | "com.unity.modules.terrainphysics": "1.0.0", 23 | "com.unity.modules.tilemap": "1.0.0", 24 | "com.unity.modules.ui": "1.0.0", 25 | "com.unity.modules.uielements": "1.0.0", 26 | "com.unity.modules.umbra": "1.0.0", 27 | "com.unity.modules.unityanalytics": "1.0.0", 28 | "com.unity.modules.unitywebrequest": "1.0.0", 29 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 30 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 31 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 32 | "com.unity.modules.unitywebrequestwww": "1.0.0", 33 | "com.unity.modules.vehicles": "1.0.0", 34 | "com.unity.modules.video": "1.0.0", 35 | "com.unity.modules.vr": "1.0.0", 36 | "com.unity.modules.wind": "1.0.0", 37 | "com.unity.modules.xr": "1.0.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | Doppler Factor: 1 9 | Default Speaker Mode: 2 10 | m_SampleRate: 0 11 | m_DSPBufferSize: 1024 12 | m_VirtualVoiceCount: 512 13 | m_RealVoiceCount: 32 14 | m_SpatializerPlugin: 15 | m_AmbisonicDecoderPlugin: 16 | m_DisableAudio: 0 17 | m_VirtualizeEffects: 1 18 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 7 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_ClothInterCollisionDistance: 0 18 | m_ClothInterCollisionStiffness: 0 19 | m_ContactsGeneration: 1 20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21 | m_AutoSimulation: 1 22 | m_AutoSyncTransforms: 1 23 | m_ClothInterCollisionSettingsToggle: 0 24 | m_ContactPairsMode: 0 25 | m_BroadphaseType: 0 26 | m_WorldBounds: 27 | m_Center: {x: 0, y: 0, z: 0} 28 | m_Extent: {x: 250, y: 250, z: 250} 29 | m_WorldSubdivisions: 8 30 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 0 9 | path: 10 | guid: 00000000000000000000000000000000 11 | - enabled: 1 12 | path: Assets/Scenes/Scene.unity 13 | guid: bb509b92e73fe4439839f06c1aec0245 14 | m_configObjects: {} 15 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 7 7 | m_ExternalVersionControlSupport: Visible Meta Files 8 | m_SerializationMode: 2 9 | m_LineEndingsForNewScripts: 2 10 | m_DefaultBehaviorMode: 0 11 | m_SpritePackerMode: 0 12 | m_SpritePackerPaddingPower: 1 13 | m_EtcTextureCompressorBehavior: 1 14 | m_EtcTextureFastCompressor: 1 15 | m_EtcTextureNormalCompressor: 2 16 | m_EtcTextureBestCompressor: 4 17 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd 18 | m_ProjectGenerationRootNamespace: 19 | m_UserGeneratedProjectSuffix: 20 | m_CollabEditorSettings: 21 | inProgressEnabled: 1 22 | m_EnableTextureStreamingInPlayMode: 1 23 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 12 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_AlwaysIncludedShaders: 32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 38 | - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0} 39 | - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0} 40 | m_PreloadedShaders: [] 41 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 42 | type: 0} 43 | m_CustomRenderPipeline: {fileID: 0} 44 | m_TransparencySortMode: 0 45 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 46 | m_DefaultRenderingPath: 1 47 | m_DefaultMobileRenderingPath: 1 48 | m_TierSettings: [] 49 | m_LightmapStripping: 0 50 | m_FogStripping: 0 51 | m_InstancingStripping: 0 52 | m_LightmapKeepPlain: 1 53 | m_LightmapKeepDirCombined: 1 54 | m_LightmapKeepDynamicPlain: 1 55 | m_LightmapKeepDynamicDirCombined: 1 56 | m_LightmapKeepShadowMask: 1 57 | m_LightmapKeepSubtractive: 1 58 | m_FogKeepLinear: 1 59 | m_FogKeepExp: 1 60 | m_FogKeepExp2: 1 61 | m_AlbedoSwatchInfos: [] 62 | m_LightsUseLinearIntensity: 0 63 | m_LightsUseColorTemperature: 0 64 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | debug: 89 | m_Flags: 0 90 | m_SettingNames: 91 | - Humanoid 92 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!149 &1 4 | NetworkManager: 5 | m_ObjectHideFlags: 0 6 | m_DebugLevel: 0 7 | m_Sendrate: 15 8 | m_AssetToPrefab: {} 9 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 3 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_AutoSimulation: 1 23 | m_QueriesHitTriggers: 1 24 | m_QueriesStartInColliders: 1 25 | m_ChangeStopsCallbacks: 0 26 | m_CallbacksOnDisable: 1 27 | m_AutoSyncTransforms: 1 28 | m_AlwaysShowColliders: 0 29 | m_ShowColliderSleep: 1 30 | m_ShowColliderContacts: 0 31 | m_ShowColliderAABB: 0 32 | m_ContactArrowScale: 0.2 33 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 34 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 35 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 36 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 37 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 38 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1386491679 &1 4 | PresetManager: 5 | m_ObjectHideFlags: 0 6 | m_DefaultList: 7 | - type: 8 | m_NativeTypeID: 108 9 | m_ManagedTypePPtr: {fileID: 0} 10 | m_ManagedTypeFallback: 11 | defaultPresets: 12 | - m_Preset: {fileID: 2655988077585873504, guid: c1cf8506f04ef2c4a88b64b6c4202eea, 13 | type: 2} 14 | - type: 15 | m_NativeTypeID: 1020 16 | m_ManagedTypePPtr: {fileID: 0} 17 | m_ManagedTypeFallback: 18 | defaultPresets: 19 | - m_Preset: {fileID: 2655988077585873504, guid: 0cd792cc87e492d43b4e95b205fc5cc6, 20 | type: 2} 21 | - type: 22 | m_NativeTypeID: 1006 23 | m_ManagedTypePPtr: {fileID: 0} 24 | m_ManagedTypeFallback: 25 | defaultPresets: 26 | - m_Preset: {fileID: 2655988077585873504, guid: 7a99f8aa944efe94cb9bd74562b7d5f9, 27 | type: 2} 28 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!129 &1 4 | PlayerSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 15 7 | productGUID: 5680f74c79b4a4d9fb9b6c2e60fb0230 8 | AndroidProfiler: 0 9 | AndroidFilterTouchesWhenObscured: 0 10 | AndroidEnableSustainedPerformanceMode: 0 11 | defaultScreenOrientation: 4 12 | targetDevice: 2 13 | useOnDemandResources: 0 14 | accelerometerFrequency: 60 15 | companyName: DefaultCompany 16 | productName: UnityExampleProject 17 | defaultCursor: {fileID: 0} 18 | cursorHotspot: {x: 0, y: 0} 19 | m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} 20 | m_ShowUnitySplashScreen: 1 21 | m_ShowUnitySplashLogo: 1 22 | m_SplashScreenOverlayOpacity: 1 23 | m_SplashScreenAnimation: 1 24 | m_SplashScreenLogoStyle: 1 25 | m_SplashScreenDrawMode: 0 26 | m_SplashScreenBackgroundAnimationZoom: 1 27 | m_SplashScreenLogoAnimationZoom: 1 28 | m_SplashScreenBackgroundLandscapeAspect: 1 29 | m_SplashScreenBackgroundPortraitAspect: 1 30 | m_SplashScreenBackgroundLandscapeUvs: 31 | serializedVersion: 2 32 | x: 0 33 | y: 0 34 | width: 1 35 | height: 1 36 | m_SplashScreenBackgroundPortraitUvs: 37 | serializedVersion: 2 38 | x: 0 39 | y: 0 40 | width: 1 41 | height: 1 42 | m_SplashScreenLogos: [] 43 | m_VirtualRealitySplashScreen: {fileID: 0} 44 | m_HolographicTrackingLossScreen: {fileID: 0} 45 | defaultScreenWidth: 1024 46 | defaultScreenHeight: 768 47 | defaultScreenWidthWeb: 960 48 | defaultScreenHeightWeb: 600 49 | m_StereoRenderingPath: 0 50 | m_ActiveColorSpace: 0 51 | m_MTRendering: 1 52 | m_StackTraceTypes: 010000000100000001000000010000000100000001000000 53 | iosShowActivityIndicatorOnLoading: -1 54 | androidShowActivityIndicatorOnLoading: -1 55 | iosAppInBackgroundBehavior: 0 56 | displayResolutionDialog: 0 57 | iosAllowHTTPDownload: 1 58 | allowedAutorotateToPortrait: 1 59 | allowedAutorotateToPortraitUpsideDown: 1 60 | allowedAutorotateToLandscapeRight: 1 61 | allowedAutorotateToLandscapeLeft: 1 62 | useOSAutorotation: 1 63 | use32BitDisplayBuffer: 1 64 | preserveFramebufferAlpha: 0 65 | disableDepthAndStencilBuffers: 0 66 | androidBlitType: 0 67 | defaultIsNativeResolution: 1 68 | macRetinaSupport: 1 69 | runInBackground: 1 70 | captureSingleScreen: 0 71 | muteOtherAudioSources: 0 72 | Prepare IOS For Recording: 0 73 | Force IOS Speakers When Recording: 0 74 | deferSystemGesturesMode: 0 75 | hideHomeButton: 0 76 | submitAnalytics: 1 77 | usePlayerLog: 0 78 | bakeCollisionMeshes: 0 79 | forceSingleInstance: 1 80 | resizableWindow: 1 81 | useMacAppStoreValidation: 0 82 | macAppStoreCategory: public.app-category.games 83 | gpuSkinning: 1 84 | graphicsJobs: 0 85 | xboxPIXTextureCapture: 0 86 | xboxEnableAvatar: 0 87 | xboxEnableKinect: 0 88 | xboxEnableKinectAutoTracking: 0 89 | xboxEnableFitness: 0 90 | visibleInBackground: 1 91 | allowFullscreenSwitch: 1 92 | graphicsJobMode: 0 93 | fullscreenMode: 3 94 | xboxSpeechDB: 0 95 | xboxEnableHeadOrientation: 0 96 | xboxEnableGuest: 0 97 | xboxEnablePIXSampling: 0 98 | metalFramebufferOnly: 0 99 | n3dsDisableStereoscopicView: 0 100 | n3dsEnableSharedListOpt: 1 101 | n3dsEnableVSync: 0 102 | xboxOneResolution: 0 103 | xboxOneSResolution: 0 104 | xboxOneXResolution: 3 105 | xboxOneMonoLoggingLevel: 0 106 | xboxOneLoggingLevel: 1 107 | xboxOneDisableEsram: 0 108 | xboxOnePresentImmediateThreshold: 0 109 | switchQueueCommandMemory: 0 110 | videoMemoryForVertexBuffers: 0 111 | psp2PowerMode: 0 112 | psp2AcquireBGM: 1 113 | vulkanEnableSetSRGBWrite: 0 114 | vulkanUseSWCommandBuffers: 0 115 | m_SupportedAspectRatios: 116 | 4:3: 1 117 | 5:4: 1 118 | 16:10: 1 119 | 16:9: 1 120 | Others: 1 121 | bundleVersion: 0.1 122 | preloadedAssets: [] 123 | metroInputSource: 0 124 | wsaTransparentSwapchain: 0 125 | m_HolographicPauseOnTrackingLoss: 1 126 | xboxOneDisableKinectGpuReservation: 0 127 | xboxOneEnable7thCore: 0 128 | vrSettings: 129 | cardboard: 130 | depthFormat: 0 131 | enableTransitionView: 0 132 | daydream: 133 | depthFormat: 0 134 | useSustainedPerformanceMode: 0 135 | enableVideoLayer: 0 136 | useProtectedVideoMemory: 0 137 | minimumSupportedHeadTracking: 0 138 | maximumSupportedHeadTracking: 1 139 | hololens: 140 | depthFormat: 1 141 | depthBufferSharingEnabled: 0 142 | oculus: 143 | sharedDepthBuffer: 0 144 | dashSupport: 0 145 | enable360StereoCapture: 0 146 | protectGraphicsMemory: 0 147 | useHDRDisplay: 0 148 | m_ColorGamuts: 00000000 149 | targetPixelDensity: 30 150 | resolutionScalingMode: 0 151 | androidSupportedAspectRatio: 1 152 | androidMaxAspectRatio: 2.1 153 | applicationIdentifier: {} 154 | buildNumber: {} 155 | AndroidBundleVersionCode: 1 156 | AndroidMinSdkVersion: 16 157 | AndroidTargetSdkVersion: 0 158 | AndroidPreferredInstallLocation: 1 159 | aotOptions: 160 | stripEngineCode: 1 161 | iPhoneStrippingLevel: 0 162 | iPhoneScriptCallOptimization: 0 163 | ForceInternetPermission: 0 164 | ForceSDCardPermission: 0 165 | CreateWallpaper: 0 166 | APKExpansionFiles: 0 167 | keepLoadedShadersAlive: 0 168 | StripUnusedMeshComponents: 1 169 | VertexChannelCompressionMask: 4054 170 | iPhoneSdkVersion: 988 171 | iOSTargetOSVersionString: 8.0 172 | tvOSSdkVersion: 0 173 | tvOSRequireExtendedGameController: 0 174 | tvOSTargetOSVersionString: 9.0 175 | uIPrerenderedIcon: 0 176 | uIRequiresPersistentWiFi: 0 177 | uIRequiresFullScreen: 1 178 | uIStatusBarHidden: 1 179 | uIExitOnSuspend: 0 180 | uIStatusBarStyle: 0 181 | iPhoneSplashScreen: {fileID: 0} 182 | iPhoneHighResSplashScreen: {fileID: 0} 183 | iPhoneTallHighResSplashScreen: {fileID: 0} 184 | iPhone47inSplashScreen: {fileID: 0} 185 | iPhone55inPortraitSplashScreen: {fileID: 0} 186 | iPhone55inLandscapeSplashScreen: {fileID: 0} 187 | iPhone58inPortraitSplashScreen: {fileID: 0} 188 | iPhone58inLandscapeSplashScreen: {fileID: 0} 189 | iPadPortraitSplashScreen: {fileID: 0} 190 | iPadHighResPortraitSplashScreen: {fileID: 0} 191 | iPadLandscapeSplashScreen: {fileID: 0} 192 | iPadHighResLandscapeSplashScreen: {fileID: 0} 193 | appleTVSplashScreen: {fileID: 0} 194 | appleTVSplashScreen2x: {fileID: 0} 195 | tvOSSmallIconLayers: [] 196 | tvOSSmallIconLayers2x: [] 197 | tvOSLargeIconLayers: [] 198 | tvOSLargeIconLayers2x: [] 199 | tvOSTopShelfImageLayers: [] 200 | tvOSTopShelfImageLayers2x: [] 201 | tvOSTopShelfImageWideLayers: [] 202 | tvOSTopShelfImageWideLayers2x: [] 203 | iOSLaunchScreenType: 0 204 | iOSLaunchScreenPortrait: {fileID: 0} 205 | iOSLaunchScreenLandscape: {fileID: 0} 206 | iOSLaunchScreenBackgroundColor: 207 | serializedVersion: 2 208 | rgba: 0 209 | iOSLaunchScreenFillPct: 100 210 | iOSLaunchScreenSize: 100 211 | iOSLaunchScreenCustomXibPath: 212 | iOSLaunchScreeniPadType: 0 213 | iOSLaunchScreeniPadImage: {fileID: 0} 214 | iOSLaunchScreeniPadBackgroundColor: 215 | serializedVersion: 2 216 | rgba: 0 217 | iOSLaunchScreeniPadFillPct: 100 218 | iOSLaunchScreeniPadSize: 100 219 | iOSLaunchScreeniPadCustomXibPath: 220 | iOSUseLaunchScreenStoryboard: 0 221 | iOSLaunchScreenCustomStoryboardPath: 222 | iOSDeviceRequirements: [] 223 | iOSURLSchemes: [] 224 | iOSBackgroundModes: 0 225 | iOSMetalForceHardShadows: 0 226 | metalEditorSupport: 1 227 | metalAPIValidation: 1 228 | iOSRenderExtraFrameOnPause: 0 229 | appleDeveloperTeamID: 230 | iOSManualSigningProvisioningProfileID: 231 | tvOSManualSigningProvisioningProfileID: 232 | iOSManualSigningProvisioningProfileType: 0 233 | tvOSManualSigningProvisioningProfileType: 0 234 | appleEnableAutomaticSigning: 0 235 | iOSRequireARKit: 0 236 | appleEnableProMotion: 0 237 | vulkanEditorSupport: 0 238 | clonedFromGUID: c0afd0d1d80e3634a9dac47e8a0426ea 239 | templatePackageId: com.unity.3d@1.0.2 240 | templateDefaultScene: Assets/Scenes/SampleScene.unity 241 | AndroidTargetArchitectures: 5 242 | AndroidSplashScreenScale: 0 243 | androidSplashScreen: {fileID: 0} 244 | AndroidKeystoreName: 245 | AndroidKeyaliasName: 246 | AndroidBuildApkPerCpuArchitecture: 0 247 | AndroidTVCompatibility: 1 248 | AndroidIsGame: 1 249 | AndroidEnableTango: 0 250 | androidEnableBanner: 1 251 | androidUseLowAccuracyLocation: 0 252 | m_AndroidBanners: 253 | - width: 320 254 | height: 180 255 | banner: {fileID: 0} 256 | androidGamepadSupportLevel: 0 257 | resolutionDialogBanner: {fileID: 0} 258 | m_BuildTargetIcons: [] 259 | m_BuildTargetPlatformIcons: [] 260 | m_BuildTargetBatching: 261 | - m_BuildTarget: Standalone 262 | m_StaticBatching: 1 263 | m_DynamicBatching: 0 264 | - m_BuildTarget: tvOS 265 | m_StaticBatching: 1 266 | m_DynamicBatching: 0 267 | - m_BuildTarget: Android 268 | m_StaticBatching: 1 269 | m_DynamicBatching: 0 270 | - m_BuildTarget: iPhone 271 | m_StaticBatching: 1 272 | m_DynamicBatching: 0 273 | - m_BuildTarget: WebGL 274 | m_StaticBatching: 0 275 | m_DynamicBatching: 0 276 | m_BuildTargetGraphicsAPIs: 277 | - m_BuildTarget: AndroidPlayer 278 | m_APIs: 0b00000015000000 279 | m_Automatic: 1 280 | - m_BuildTarget: iOSSupport 281 | m_APIs: 10000000 282 | m_Automatic: 1 283 | - m_BuildTarget: AppleTVSupport 284 | m_APIs: 10000000 285 | m_Automatic: 0 286 | - m_BuildTarget: WebGLSupport 287 | m_APIs: 0b000000 288 | m_Automatic: 1 289 | - m_BuildTarget: LinuxStandaloneSupport 290 | m_APIs: 1100000015000000 291 | m_Automatic: 1 292 | m_BuildTargetVRSettings: 293 | - m_BuildTarget: Standalone 294 | m_Enabled: 0 295 | m_Devices: 296 | - Oculus 297 | - OpenVR 298 | m_BuildTargetEnableVuforiaSettings: [] 299 | openGLRequireES31: 0 300 | openGLRequireES31AEP: 0 301 | m_TemplateCustomTags: {} 302 | mobileMTRendering: 303 | Android: 1 304 | iPhone: 1 305 | tvOS: 1 306 | m_BuildTargetGroupLightmapEncodingQuality: [] 307 | m_BuildTargetGroupLightmapSettings: [] 308 | playModeTestRunnerEnabled: 0 309 | runPlayModeTestAsEditModeTest: 0 310 | actionOnDotNetUnhandledException: 1 311 | enableInternalProfiler: 0 312 | logObjCUncaughtExceptions: 1 313 | enableCrashReportAPI: 0 314 | cameraUsageDescription: 315 | locationUsageDescription: 316 | microphoneUsageDescription: 317 | switchNetLibKey: 318 | switchSocketMemoryPoolSize: 6144 319 | switchSocketAllocatorPoolSize: 128 320 | switchSocketConcurrencyLimit: 14 321 | switchScreenResolutionBehavior: 2 322 | switchUseCPUProfiler: 0 323 | switchApplicationID: 0x01004b9000490000 324 | switchNSODependencies: 325 | switchTitleNames_0: 326 | switchTitleNames_1: 327 | switchTitleNames_2: 328 | switchTitleNames_3: 329 | switchTitleNames_4: 330 | switchTitleNames_5: 331 | switchTitleNames_6: 332 | switchTitleNames_7: 333 | switchTitleNames_8: 334 | switchTitleNames_9: 335 | switchTitleNames_10: 336 | switchTitleNames_11: 337 | switchTitleNames_12: 338 | switchTitleNames_13: 339 | switchTitleNames_14: 340 | switchPublisherNames_0: 341 | switchPublisherNames_1: 342 | switchPublisherNames_2: 343 | switchPublisherNames_3: 344 | switchPublisherNames_4: 345 | switchPublisherNames_5: 346 | switchPublisherNames_6: 347 | switchPublisherNames_7: 348 | switchPublisherNames_8: 349 | switchPublisherNames_9: 350 | switchPublisherNames_10: 351 | switchPublisherNames_11: 352 | switchPublisherNames_12: 353 | switchPublisherNames_13: 354 | switchPublisherNames_14: 355 | switchIcons_0: {fileID: 0} 356 | switchIcons_1: {fileID: 0} 357 | switchIcons_2: {fileID: 0} 358 | switchIcons_3: {fileID: 0} 359 | switchIcons_4: {fileID: 0} 360 | switchIcons_5: {fileID: 0} 361 | switchIcons_6: {fileID: 0} 362 | switchIcons_7: {fileID: 0} 363 | switchIcons_8: {fileID: 0} 364 | switchIcons_9: {fileID: 0} 365 | switchIcons_10: {fileID: 0} 366 | switchIcons_11: {fileID: 0} 367 | switchIcons_12: {fileID: 0} 368 | switchIcons_13: {fileID: 0} 369 | switchIcons_14: {fileID: 0} 370 | switchSmallIcons_0: {fileID: 0} 371 | switchSmallIcons_1: {fileID: 0} 372 | switchSmallIcons_2: {fileID: 0} 373 | switchSmallIcons_3: {fileID: 0} 374 | switchSmallIcons_4: {fileID: 0} 375 | switchSmallIcons_5: {fileID: 0} 376 | switchSmallIcons_6: {fileID: 0} 377 | switchSmallIcons_7: {fileID: 0} 378 | switchSmallIcons_8: {fileID: 0} 379 | switchSmallIcons_9: {fileID: 0} 380 | switchSmallIcons_10: {fileID: 0} 381 | switchSmallIcons_11: {fileID: 0} 382 | switchSmallIcons_12: {fileID: 0} 383 | switchSmallIcons_13: {fileID: 0} 384 | switchSmallIcons_14: {fileID: 0} 385 | switchManualHTML: 386 | switchAccessibleURLs: 387 | switchLegalInformation: 388 | switchMainThreadStackSize: 1048576 389 | switchPresenceGroupId: 390 | switchLogoHandling: 0 391 | switchReleaseVersion: 0 392 | switchDisplayVersion: 1.0.0 393 | switchStartupUserAccount: 0 394 | switchTouchScreenUsage: 0 395 | switchSupportedLanguagesMask: 0 396 | switchLogoType: 0 397 | switchApplicationErrorCodeCategory: 398 | switchUserAccountSaveDataSize: 0 399 | switchUserAccountSaveDataJournalSize: 0 400 | switchApplicationAttribute: 0 401 | switchCardSpecSize: -1 402 | switchCardSpecClock: -1 403 | switchRatingsMask: 0 404 | switchRatingsInt_0: 0 405 | switchRatingsInt_1: 0 406 | switchRatingsInt_2: 0 407 | switchRatingsInt_3: 0 408 | switchRatingsInt_4: 0 409 | switchRatingsInt_5: 0 410 | switchRatingsInt_6: 0 411 | switchRatingsInt_7: 0 412 | switchRatingsInt_8: 0 413 | switchRatingsInt_9: 0 414 | switchRatingsInt_10: 0 415 | switchRatingsInt_11: 0 416 | switchLocalCommunicationIds_0: 417 | switchLocalCommunicationIds_1: 418 | switchLocalCommunicationIds_2: 419 | switchLocalCommunicationIds_3: 420 | switchLocalCommunicationIds_4: 421 | switchLocalCommunicationIds_5: 422 | switchLocalCommunicationIds_6: 423 | switchLocalCommunicationIds_7: 424 | switchParentalControl: 0 425 | switchAllowsScreenshot: 1 426 | switchAllowsVideoCapturing: 1 427 | switchAllowsRuntimeAddOnContentInstall: 0 428 | switchDataLossConfirmation: 0 429 | switchSupportedNpadStyles: 3 430 | switchNativeFsCacheSize: 32 431 | switchIsHoldTypeHorizontal: 0 432 | switchSupportedNpadCount: 8 433 | switchSocketConfigEnabled: 0 434 | switchTcpInitialSendBufferSize: 32 435 | switchTcpInitialReceiveBufferSize: 64 436 | switchTcpAutoSendBufferSizeMax: 256 437 | switchTcpAutoReceiveBufferSizeMax: 256 438 | switchUdpSendBufferSize: 9 439 | switchUdpReceiveBufferSize: 42 440 | switchSocketBufferEfficiency: 4 441 | switchSocketInitializeEnabled: 1 442 | switchNetworkInterfaceManagerInitializeEnabled: 1 443 | switchPlayerConnectionEnabled: 1 444 | ps4NPAgeRating: 12 445 | ps4NPTitleSecret: 446 | ps4NPTrophyPackPath: 447 | ps4ParentalLevel: 11 448 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000 449 | ps4Category: 0 450 | ps4MasterVersion: 01.00 451 | ps4AppVersion: 01.00 452 | ps4AppType: 0 453 | ps4ParamSfxPath: 454 | ps4VideoOutPixelFormat: 0 455 | ps4VideoOutInitialWidth: 1920 456 | ps4VideoOutBaseModeInitialWidth: 1920 457 | ps4VideoOutReprojectionRate: 60 458 | ps4PronunciationXMLPath: 459 | ps4PronunciationSIGPath: 460 | ps4BackgroundImagePath: 461 | ps4StartupImagePath: 462 | ps4StartupImagesFolder: 463 | ps4IconImagesFolder: 464 | ps4SaveDataImagePath: 465 | ps4SdkOverride: 466 | ps4BGMPath: 467 | ps4ShareFilePath: 468 | ps4ShareOverlayImagePath: 469 | ps4PrivacyGuardImagePath: 470 | ps4NPtitleDatPath: 471 | ps4RemotePlayKeyAssignment: -1 472 | ps4RemotePlayKeyMappingDir: 473 | ps4PlayTogetherPlayerCount: 0 474 | ps4EnterButtonAssignment: 1 475 | ps4ApplicationParam1: 0 476 | ps4ApplicationParam2: 0 477 | ps4ApplicationParam3: 0 478 | ps4ApplicationParam4: 0 479 | ps4DownloadDataSize: 0 480 | ps4GarlicHeapSize: 2048 481 | ps4ProGarlicHeapSize: 2560 482 | ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ 483 | ps4pnSessions: 1 484 | ps4pnPresence: 1 485 | ps4pnFriends: 1 486 | ps4pnGameCustomData: 1 487 | playerPrefsSupport: 0 488 | enableApplicationExit: 0 489 | restrictedAudioUsageRights: 0 490 | ps4UseResolutionFallback: 0 491 | ps4ReprojectionSupport: 0 492 | ps4UseAudio3dBackend: 0 493 | ps4SocialScreenEnabled: 0 494 | ps4ScriptOptimizationLevel: 0 495 | ps4Audio3dVirtualSpeakerCount: 14 496 | ps4attribCpuUsage: 0 497 | ps4PatchPkgPath: 498 | ps4PatchLatestPkgPath: 499 | ps4PatchChangeinfoPath: 500 | ps4PatchDayOne: 0 501 | ps4attribUserManagement: 0 502 | ps4attribMoveSupport: 0 503 | ps4attrib3DSupport: 0 504 | ps4attribShareSupport: 0 505 | ps4attribExclusiveVR: 0 506 | ps4disableAutoHideSplash: 0 507 | ps4videoRecordingFeaturesUsed: 0 508 | ps4contentSearchFeaturesUsed: 0 509 | ps4attribEyeToEyeDistanceSettingVR: 0 510 | ps4IncludedModules: [] 511 | monoEnv: 512 | psp2Splashimage: {fileID: 0} 513 | psp2NPTrophyPackPath: 514 | psp2NPSupportGBMorGJP: 0 515 | psp2NPAgeRating: 12 516 | psp2NPTitleDatPath: 517 | psp2NPCommsID: 518 | psp2NPCommunicationsID: 519 | psp2NPCommsPassphrase: 520 | psp2NPCommsSig: 521 | psp2ParamSfxPath: 522 | psp2ManualPath: 523 | psp2LiveAreaGatePath: 524 | psp2LiveAreaBackroundPath: 525 | psp2LiveAreaPath: 526 | psp2LiveAreaTrialPath: 527 | psp2PatchChangeInfoPath: 528 | psp2PatchOriginalPackage: 529 | psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui 530 | psp2KeystoneFile: 531 | psp2MemoryExpansionMode: 0 532 | psp2DRMType: 0 533 | psp2StorageType: 0 534 | psp2MediaCapacity: 0 535 | psp2DLCConfigPath: 536 | psp2ThumbnailPath: 537 | psp2BackgroundPath: 538 | psp2SoundPath: 539 | psp2TrophyCommId: 540 | psp2TrophyPackagePath: 541 | psp2PackagedResourcesPath: 542 | psp2SaveDataQuota: 10240 543 | psp2ParentalLevel: 1 544 | psp2ShortTitle: Not Set 545 | psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF 546 | psp2Category: 0 547 | psp2MasterVersion: 01.00 548 | psp2AppVersion: 01.00 549 | psp2TVBootMode: 0 550 | psp2EnterButtonAssignment: 2 551 | psp2TVDisableEmu: 0 552 | psp2AllowTwitterDialog: 1 553 | psp2Upgradable: 0 554 | psp2HealthWarning: 0 555 | psp2UseLibLocation: 0 556 | psp2InfoBarOnStartup: 0 557 | psp2InfoBarColor: 0 558 | psp2ScriptOptimizationLevel: 0 559 | splashScreenBackgroundSourceLandscape: {fileID: 0} 560 | splashScreenBackgroundSourcePortrait: {fileID: 0} 561 | spritePackerPolicy: 562 | webGLMemorySize: 256 563 | webGLExceptionSupport: 1 564 | webGLNameFilesAsHashes: 0 565 | webGLDataCaching: 1 566 | webGLDebugSymbols: 0 567 | webGLEmscriptenArgs: 568 | webGLModulesDirectory: 569 | webGLTemplate: APPLICATION:Default 570 | webGLAnalyzeBuildSize: 0 571 | webGLUseEmbeddedResources: 0 572 | webGLCompressionFormat: 1 573 | webGLLinkerTarget: 1 574 | scriptingDefineSymbols: {} 575 | platformArchitecture: {} 576 | scriptingBackend: {} 577 | il2cppCompilerConfiguration: {} 578 | incrementalIl2cppBuild: {} 579 | allowUnsafeCode: 1 580 | additionalIl2CppArgs: 581 | scriptingRuntimeVersion: 1 582 | apiCompatibilityLevelPerPlatform: {} 583 | m_RenderingPath: 1 584 | m_MobileRenderingPath: 1 585 | metroPackageName: Template_3D 586 | metroPackageVersion: 587 | metroCertificatePath: 588 | metroCertificatePassword: 589 | metroCertificateSubject: 590 | metroCertificateIssuer: 591 | metroCertificateNotAfter: 0000000000000000 592 | metroApplicationDescription: Template_3D 593 | wsaImages: {} 594 | metroTileShortName: 595 | metroTileShowName: 0 596 | metroMediumTileShowName: 0 597 | metroLargeTileShowName: 0 598 | metroWideTileShowName: 0 599 | metroDefaultTileSize: 1 600 | metroTileForegroundText: 2 601 | metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} 602 | metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, 603 | a: 1} 604 | metroSplashScreenUseBackgroundColor: 0 605 | platformCapabilities: {} 606 | metroFTAName: 607 | metroFTAFileTypes: [] 608 | metroProtocolName: 609 | metroCompilationOverrides: 1 610 | n3dsUseExtSaveData: 0 611 | n3dsCompressStaticMem: 1 612 | n3dsExtSaveDataNumber: 0x12345 613 | n3dsStackSize: 131072 614 | n3dsTargetPlatform: 2 615 | n3dsRegion: 7 616 | n3dsMediaSize: 0 617 | n3dsLogoStyle: 3 618 | n3dsTitle: GameName 619 | n3dsProductCode: 620 | n3dsApplicationId: 0xFF3FF 621 | XboxOneProductId: 622 | XboxOneUpdateKey: 623 | XboxOneSandboxId: 624 | XboxOneContentId: 625 | XboxOneTitleId: 626 | XboxOneSCId: 627 | XboxOneGameOsOverridePath: 628 | XboxOnePackagingOverridePath: 629 | XboxOneAppManifestOverridePath: 630 | XboxOneVersion: 1.0.0.0 631 | XboxOnePackageEncryption: 0 632 | XboxOnePackageUpdateGranularity: 2 633 | XboxOneDescription: 634 | XboxOneLanguage: 635 | - enus 636 | XboxOneCapability: [] 637 | XboxOneGameRating: {} 638 | XboxOneIsContentPackage: 0 639 | XboxOneEnableGPUVariability: 0 640 | XboxOneSockets: {} 641 | XboxOneSplashScreen: {fileID: 0} 642 | XboxOneAllowedProductIds: [] 643 | XboxOnePersistentLocalStorageSize: 0 644 | XboxOneXTitleMemory: 8 645 | xboxOneScriptCompiler: 0 646 | vrEditorSettings: 647 | daydream: 648 | daydreamIconForeground: {fileID: 0} 649 | daydreamIconBackground: {fileID: 0} 650 | cloudServicesEnabled: 651 | UNet: 1 652 | facebookSdkVersion: 7.9.4 653 | apiCompatibilityLevel: 3 654 | cloudProjectId: 655 | projectName: 656 | organizationId: 657 | cloudEnabled: 0 658 | enableNativePlatformBackendsForNewInputSystem: 0 659 | disableOldInputManagerSupport: 0 660 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2018.2.7f1 2 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 4 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Very Low 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 3 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 0 21 | blendWeights: 1 22 | textureQuality: 1 23 | anisotropicTextures: 0 24 | antiAliasing: 0 25 | softParticles: 0 26 | softVegetation: 0 27 | realtimeReflectionProbes: 0 28 | billboardsFaceCameraPosition: 0 29 | vSyncCount: 0 30 | lodBias: 0.3 31 | maximumLODLevel: 0 32 | particleRaycastBudget: 4 33 | asyncUploadTimeSlice: 2 34 | asyncUploadBufferSize: 4 35 | resolutionScalingFixedDPIFactor: 1 36 | excludedTargetPlatforms: [] 37 | - serializedVersion: 2 38 | name: Low 39 | pixelLightCount: 0 40 | shadows: 0 41 | shadowResolution: 0 42 | shadowProjection: 1 43 | shadowCascades: 1 44 | shadowDistance: 20 45 | shadowNearPlaneOffset: 3 46 | shadowCascade2Split: 0.33333334 47 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 48 | shadowmaskMode: 0 49 | blendWeights: 2 50 | textureQuality: 0 51 | anisotropicTextures: 0 52 | antiAliasing: 0 53 | softParticles: 0 54 | softVegetation: 0 55 | realtimeReflectionProbes: 0 56 | billboardsFaceCameraPosition: 0 57 | vSyncCount: 0 58 | lodBias: 0.4 59 | maximumLODLevel: 0 60 | particleRaycastBudget: 16 61 | asyncUploadTimeSlice: 2 62 | asyncUploadBufferSize: 4 63 | resolutionScalingFixedDPIFactor: 1 64 | excludedTargetPlatforms: [] 65 | - serializedVersion: 2 66 | name: Medium 67 | pixelLightCount: 1 68 | shadows: 1 69 | shadowResolution: 0 70 | shadowProjection: 1 71 | shadowCascades: 1 72 | shadowDistance: 20 73 | shadowNearPlaneOffset: 3 74 | shadowCascade2Split: 0.33333334 75 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 76 | shadowmaskMode: 0 77 | blendWeights: 2 78 | textureQuality: 0 79 | anisotropicTextures: 1 80 | antiAliasing: 0 81 | softParticles: 0 82 | softVegetation: 0 83 | realtimeReflectionProbes: 0 84 | billboardsFaceCameraPosition: 0 85 | vSyncCount: 1 86 | lodBias: 0.7 87 | maximumLODLevel: 0 88 | particleRaycastBudget: 64 89 | asyncUploadTimeSlice: 2 90 | asyncUploadBufferSize: 4 91 | resolutionScalingFixedDPIFactor: 1 92 | excludedTargetPlatforms: [] 93 | - serializedVersion: 2 94 | name: High 95 | pixelLightCount: 2 96 | shadows: 2 97 | shadowResolution: 1 98 | shadowProjection: 1 99 | shadowCascades: 2 100 | shadowDistance: 40 101 | shadowNearPlaneOffset: 3 102 | shadowCascade2Split: 0.33333334 103 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 104 | shadowmaskMode: 1 105 | blendWeights: 2 106 | textureQuality: 0 107 | anisotropicTextures: 1 108 | antiAliasing: 2 109 | softParticles: 0 110 | softVegetation: 1 111 | realtimeReflectionProbes: 1 112 | billboardsFaceCameraPosition: 1 113 | vSyncCount: 1 114 | lodBias: 1 115 | maximumLODLevel: 0 116 | particleRaycastBudget: 256 117 | asyncUploadTimeSlice: 2 118 | asyncUploadBufferSize: 4 119 | resolutionScalingFixedDPIFactor: 1 120 | excludedTargetPlatforms: [] 121 | - serializedVersion: 2 122 | name: Very High 123 | pixelLightCount: 3 124 | shadows: 2 125 | shadowResolution: 2 126 | shadowProjection: 1 127 | shadowCascades: 2 128 | shadowDistance: 40 129 | shadowNearPlaneOffset: 3 130 | shadowCascade2Split: 0.33333334 131 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 132 | shadowmaskMode: 1 133 | blendWeights: 4 134 | textureQuality: 0 135 | anisotropicTextures: 1 136 | antiAliasing: 4 137 | softParticles: 1 138 | softVegetation: 1 139 | realtimeReflectionProbes: 1 140 | billboardsFaceCameraPosition: 1 141 | vSyncCount: 1 142 | lodBias: 1.5 143 | maximumLODLevel: 0 144 | particleRaycastBudget: 1024 145 | asyncUploadTimeSlice: 2 146 | asyncUploadBufferSize: 4 147 | resolutionScalingFixedDPIFactor: 1 148 | excludedTargetPlatforms: [] 149 | - serializedVersion: 2 150 | name: Ultra 151 | pixelLightCount: 4 152 | shadows: 2 153 | shadowResolution: 2 154 | shadowProjection: 1 155 | shadowCascades: 4 156 | shadowDistance: 150 157 | shadowNearPlaneOffset: 3 158 | shadowCascade2Split: 0.33333334 159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 160 | shadowmaskMode: 1 161 | blendWeights: 4 162 | textureQuality: 0 163 | anisotropicTextures: 1 164 | antiAliasing: 4 165 | softParticles: 1 166 | softVegetation: 1 167 | realtimeReflectionProbes: 1 168 | billboardsFaceCameraPosition: 1 169 | vSyncCount: 1 170 | lodBias: 2 171 | maximumLODLevel: 0 172 | particleRaycastBudget: 4096 173 | asyncUploadTimeSlice: 2 174 | asyncUploadBufferSize: 4 175 | resolutionScalingFixedDPIFactor: 1 176 | excludedTargetPlatforms: [] 177 | m_PerPlatformDefaultQuality: 178 | Android: 2 179 | Nintendo 3DS: 5 180 | Nintendo Switch: 5 181 | PS4: 5 182 | PSP2: 2 183 | Standalone: 5 184 | Tizen: 2 185 | WebGL: 3 186 | WiiU: 5 187 | Windows Store Apps: 5 188 | XboxOne: 5 189 | iPhone: 2 190 | tvOS: 2 191 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - PostProcessing 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.1 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /UnityExampleProject/ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | m_Enabled: 1 7 | m_TestMode: 0 8 | m_TestEventUrl: 9 | m_TestConfigUrl: 10 | m_TestInitMode: 0 11 | CrashReportingSettings: 12 | m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes 13 | m_NativeEventUrl: https://perf-events.cloud.unity3d.com/symbolicate 14 | m_Enabled: 0 15 | m_CaptureEditorExceptions: 1 16 | UnityPurchasingSettings: 17 | m_Enabled: 0 18 | m_TestMode: 0 19 | UnityAnalyticsSettings: 20 | m_Enabled: 0 21 | m_InitializeOnStartup: 1 22 | m_TestMode: 0 23 | m_TestEventUrl: 24 | m_TestConfigUrl: 25 | UnityAdsSettings: 26 | m_Enabled: 0 27 | m_InitializeOnStartup: 1 28 | m_TestMode: 0 29 | m_IosGameId: 30 | m_AndroidGameId: 31 | m_GameIds: {} 32 | m_GameId: 33 | PerformanceReportingSettings: 34 | m_Enabled: 0 35 | --------------------------------------------------------------------------------