Пример #1
0
        public Skybox(Material material)
        {
            this.material = material;
            this.material.LoadMaterial();

            cube = MeshPrimitives.CreateCube(1);
            cube.SetVertexLayout(new VertexBufferLayout[]
            {
                new VertexBufferLayout(VertexAttribute.Position, VertexAttributeFormat.Float32, 3),
            });
        }
Пример #2
0
    static void LoadGLTF(string path)
    {
        string  json = File.ReadAllText(path);
        JObject gltf = JObject.Parse(json);

        gltf["path"] = path;

        var    fileInfo = new FileInfo(path);
        string gltfName = fileInfo.Name;

        gltfName = gltfName.Substring(0, gltfName.Length - fileInfo.Extension.Length);

        string dir = string.Format("Assets/glTF/{0}", gltfName);

        if (Directory.Exists(dir) == false)
        {
            Directory.CreateDirectory(dir);
        }

        Cache cache = new Cache();

        // load buffers
        int bufferCount = (gltf["buffers"] as JArray).Count;

        for (int i = 0; i < bufferCount; ++i)
        {
            cache.buffers.Add(LoadGLTFBuffer(gltf, cache, i));
        }

        // load meshes
        int meshCount = (gltf["meshes"] as JArray).Count;

        for (int i = 0; i < meshCount; ++i)
        {
            MeshPrimitives mp = LoadGLTFMesh(gltf, cache, i);
            cache.meshes.Add(mp);

            AssetDatabase.CreateAsset(mp.mesh, string.Format("Assets/glTF/{0}/{1}.asset", gltfName, mp.mesh.name));
        }

        // load textures
        int textureCount = (gltf["textures"] as JArray).Count;

        for (int i = 0; i < textureCount; ++i)
        {
            Texture2D texture = LoadGLTFTexture(gltf, cache, i, dir);
            cache.textures.Add(texture);
        }

        // load materials
        int materialCount = (gltf["materials"] as JArray).Count;

        for (int i = 0; i < materialCount; ++i)
        {
            Material material = LoadGLTFMaterial(gltf, cache, i);
            cache.materials.Add(material);

            AssetDatabase.CreateAsset(material, string.Format("Assets/glTF/{0}/{1}.mat", gltfName, material.name));
        }

        // load nodes
        var root = new GameObject(gltfName);

        int scene  = GetPropertyInt(gltf, "scene", 0);
        var jnodes = gltf["scenes"][scene]["nodes"] as JArray;

        for (int i = 0; i < jnodes.Count; ++i)
        {
            int node = (int)jnodes[i];
            LoadGLTFNode(gltf, cache, node, root);
        }

        PrefabUtility.CreatePrefab(string.Format("Assets/glTF/{0}/{1}.prefab", gltfName, gltfName), root, ReplacePrefabOptions.ConnectToPrefab);
    }
Пример #3
0
    static MeshPrimitives LoadGLTFMesh(JObject gltf, Cache cache, int meshIndex)
    {
        var jmesh = gltf["meshes"][meshIndex];

        List <float[]> vertexValues      = new List <float[]>();
        List <float[]> normalValues      = new List <float[]>();
        List <float[]> tangentValues     = new List <float[]>();
        List <float[]> uvValues          = new List <float[]>();
        List <float[]> uv2Values         = new List <float[]>();
        List <float[]> colorValues       = new List <float[]>();
        List <short[]> blendIndexValues  = new List <short[]>();
        List <float[]> blendWeightValues = new List <float[]>();
        List <int[]>   indices           = new List <int[]>();
        List <int>     materials         = new List <int>();

        int vertexCount = 0;

        var jprimitives    = jmesh["primitives"] as JArray;
        int primitiveCount = jprimitives.Count;

        for (int i = 0; i < primitiveCount; ++i)
        {
            var jprimitive = jprimitives[i] as JObject;

            var jattributes = jprimitive["attributes"] as JObject;
            AccessGLTFBuffer(gltf, cache, jattributes, "POSITION", vertexValues, 3, 4);
            AccessGLTFBuffer(gltf, cache, jattributes, "NORMAL", normalValues, 3, 4);
            AccessGLTFBuffer(gltf, cache, jattributes, "TANGENT", tangentValues, 4, 4);
            AccessGLTFBuffer(gltf, cache, jattributes, "TEXCOORD_0", uvValues, 2, 4);
            AccessGLTFBuffer(gltf, cache, jattributes, "TEXCOORD_1", uv2Values, 2, 4);
            AccessGLTFBuffer(gltf, cache, jattributes, "COLOR_0", colorValues, 4, 4);
            AccessGLTFBuffer(gltf, cache, jattributes, "JOINTS_0", blendIndexValues, 4, 2);
            AccessGLTFBuffer(gltf, cache, jattributes, "WEIGHTS_0", blendWeightValues, 4, 4);

            int indicesAccessor = GetPropertyInt(jprimitive, "indices", -1);
            if (indicesAccessor >= 0)
            {
                var jaccessor = gltf["accessors"][indicesAccessor];

                int bufferViewIndex = GetPropertyInt(jaccessor, "bufferView", -1);
                if (bufferViewIndex >= 0)
                {
                    int   count      = GetPropertyInt(jaccessor, "count", -1);
                    int[] subIndices = new int[count];
                    for (int j = 0; j < count; ++j)
                    {
                        int index = AccessBuffer <ushort>(gltf, cache, jaccessor, bufferViewIndex, j, 1, 2)[0];
                        subIndices[j] = index + vertexCount;
                    }
                    indices.Add(subIndices);
                }
            }

            int materialIndex = GetPropertyInt(jprimitive, "material", -1);
            materials.Add(materialIndex);

            vertexCount += vertexValues.Count;
        }

        Vector3[] vertices = new Vector3[vertexValues.Count];
        for (int i = 0; i < vertexValues.Count; ++i)
        {
            vertices[i] = new Vector3(-vertexValues[i][0], vertexValues[i][1], vertexValues[i][2]);
        }

        Vector3[] normals = new Vector3[normalValues.Count];
        for (int i = 0; i < normalValues.Count; ++i)
        {
            normals[i] = new Vector3(-normalValues[i][0], normalValues[i][1], normalValues[i][2]);
        }

        Vector4[] tangents = new Vector4[tangentValues.Count];
        for (int i = 0; i < tangentValues.Count; ++i)
        {
            tangents[i] = new Vector4(-tangentValues[i][0], tangentValues[i][1], tangentValues[i][2], tangentValues[i][3]);
        }

        Vector2[] uv = new Vector2[uvValues.Count];
        for (int i = 0; i < uvValues.Count; ++i)
        {
            uv[i] = new Vector2(uvValues[i][0], 1.0f - uvValues[i][1]);
        }

        Vector2[] uv2 = new Vector2[uv2Values.Count];
        for (int i = 0; i < uv2Values.Count; ++i)
        {
            uv2[i] = new Vector2(uv2Values[i][0], 1.0f - uv2Values[i][1]);
        }

        Color[] colors = new Color[colorValues.Count];
        for (int i = 0; i < colorValues.Count; ++i)
        {
            colors[i] = new Color(colorValues[i][0], colorValues[i][1], colorValues[i][2], colorValues[i][3]);
        }

        BoneWeight[] boneWeights = new BoneWeight[blendIndexValues.Count];
        for (int i = 0; i < blendIndexValues.Count; ++i)
        {
            BoneWeight w = new BoneWeight();
            w.boneIndex0   = blendIndexValues[i][0];
            w.boneIndex1   = blendIndexValues[i][1];
            w.boneIndex2   = blendIndexValues[i][2];
            w.boneIndex3   = blendIndexValues[i][3];
            w.weight0      = blendWeightValues[i][0];
            w.weight1      = blendWeightValues[i][1];
            w.weight2      = blendWeightValues[i][2];
            w.weight3      = blendWeightValues[i][3];
            boneWeights[i] = w;
        }

        var mesh = new Mesh();

        mesh.vertices     = vertices;
        mesh.normals      = normals;
        mesh.tangents     = tangents;
        mesh.uv           = uv;
        mesh.uv2          = uv2;
        mesh.colors       = colors;
        mesh.boneWeights  = boneWeights;
        mesh.subMeshCount = indices.Count;

        for (int i = 0; i < indices.Count; ++i)
        {
            int   triangleCount = indices[i].Length / 3;
            int[] subIndices    = new int[triangleCount * 3];
            for (int j = 0; j < triangleCount; ++j)
            {
                subIndices[j * 3 + 0] = indices[i][j * 3 + 0];
                subIndices[j * 3 + 1] = indices[i][j * 3 + 2];
                subIndices[j * 3 + 2] = indices[i][j * 3 + 1];
            }
            mesh.SetTriangles(subIndices, i);
        }

        string name = GetPropertyString(jmesh, "name", null);

        if (string.IsNullOrEmpty(name) == false)
        {
            name = string.Format("mesh_{0}", name);
        }
        else
        {
            name = string.Format("mesh_{0}", meshIndex);
        }
        mesh.name = name;

        MeshPrimitives mp = new MeshPrimitives();

        mp.mesh      = mesh;
        mp.materials = materials;

        return(mp);
    }
Пример #4
0
        protected override async System.Threading.Tasks.Task CreateVmsAndGms(CRenderContext rc, uint meshIndex)
        {
            if (!mImportOption.ImportMesh)
            {
                return;
            }
            //导入不经过MeshPrimitivesManager
            //var meshPrimitive = CEngine.Instance.MeshPrimitivesManager.NewMeshPrimitives(rc,, 1);
            //meshPrimitive.Name

            var namePtr    = SDK_AssetImporter_GetMeshNameByIndex(mCoreObject, meshIndex);
            var ansiString = Marshal.PtrToStringAnsi(namePtr);

            if (MeshPrimitives.ContainsKey(ansiString))
            {
                ansiString += meshIndex.ToString();
            }
            var atom          = SDK_AssetImporter_GetMesAtomByIndex(mCoreObject, meshIndex);
            var meshPrimitive = new EngineNS.Graphics.Mesh.CGfxMeshPrimitives();
            var fullPath      = RName.EditorOnly_GetRNameFromAbsFile(mAbsSavePath + "/" + ansiString + CEngineDesc.MeshSourceExtension);

            CEngine.Instance.MeshPrimitivesManager.RemoveMeshPimitives(fullPath);
            if (Async)
            {
                await CEngine.Instance.EventPoster.Post(async() =>
                {
                    OnResourceImportCheck(this, AsseetImportType.AIT_Import, "CreateMeshPrimitive");
                    meshPrimitive.Init(rc, fullPath, atom);
                    SDK_AssetImporter_GetMeshPrimitiveByIndex(mCoreObject, rc.CoreObject, meshIndex, meshPrimitive.CoreObject);
                    var skinNativePointer = SDK_AssetImporter_BuildMeshPrimitiveSkinModifierByIndex(mCoreObject, rc.CoreObject, meshIndex, meshPrimitive.CoreObject);
                    if (skinNativePointer.GetPointer() != IntPtr.Zero)
                    {
                        var skinModifier      = new CGfxSkinModifier(skinNativePointer);
                        var nativeSkeleton    = CGfxSkinModifier.SDK_GfxSkinModifier_GetSkeleton(skinNativePointer);
                        CGfxSkeleton skeleton = new CGfxSkeleton(nativeSkeleton);
                        EngineNS.Bricks.Animation.Pose.CGfxSkeletonPose pose = new EngineNS.Bricks.Animation.Pose.CGfxSkeletonPose();
                        for (uint i = 0; i < skeleton.BoneTab.BoneNumberNative; ++i)
                        {
                            pose.NewBone(skeleton.BoneTab.GetBoneNative(i).BoneDescNative);
                        }
                        CGfxSkeleton csSkeleton = new CGfxSkeleton();
                        csSkeleton.BoneTab      = pose;
                        skinModifier.Skeleton   = csSkeleton;
                        meshPrimitive.MdfQueue.AddModifier(skinModifier);
                        if (mImportOption.SkeletonAssetName != null && mImportOption.SkeletonAssetName != RName.EmptyName)
                        {
                            var skeletonAsset          = EngineNS.CEngine.Instance.SkeletonAssetManager.GetSkeleton(rc, mImportOption.SkeletonAssetName, false);
                            skinModifier.SkeletonAsset = mImportOption.SkeletonAssetName.Name;
                            mSkeletonAsset             = mImportOption.SkeletonAssetName.Name;
                        }
                        else
                        {
                            OnResourceImportCheck(this, AsseetImportType.AIT_Import, "CreateSkeleton");
                            var pureName               = CEngine.Instance.FileManager.GetPureFileFromFullName(mAbsFileName, false);
                            var path                   = mAbsSavePath + "/" + pureName + CEngineDesc.SkeletonExtension;
                            var assetName              = RName.EditorOnly_GetRNameFromAbsFile(path);
                            var skeletonAsset          = EngineNS.CEngine.Instance.SkeletonAssetManager.CreateSkeletonAsset(rc, assetName, skinModifier);
                            skinModifier.SkeletonAsset = assetName.Name;
                            mSkeletonAsset             = assetName.Name;
                            if (!mSkeletonNeedInfo.ContainsKey(pureName))
                            {
                                mSkeletonNeedInfo.Add(pureName, assetName);
                            }
                        }
                    }
                    MeshPrimitives.Add(ansiString, meshPrimitive);
                    if (mImportOption.AsPhyGemoConvex || mImportOption.AsPhyGemoTri)
                    {
                        foreach (var i in MeshPrimitives.Values)
                        {
                            CGfxMeshPrimitives meshprimitive = i as CGfxMeshPrimitives;
                            if (mImportOption.AsPhyGemoConvex)
                            {
                                meshprimitive.CookAndSavePhyiscsGeomAsConvex(CEngine.Instance.RenderContext, EngineNS.CEngine.Instance.PhyContext);
                            }
                            else if (mImportOption.AsPhyGemoTri)
                            {
                                meshprimitive.CookAndSavePhyiscsGeomAsTriMesh(CEngine.Instance.RenderContext, EngineNS.CEngine.Instance.PhyContext);
                            }
                        }
                    }
                    else
                    {
                        await CEngine.Instance.EventPoster.Post(() =>
                        {
                            meshPrimitive.SaveMesh();
                            return(true);
                        }, EngineNS.Thread.Async.EAsyncTarget.Render);
                        //gms
                        if (mImportOption.CreatedGms)
                        {
                            OnResourceImportCheck(this, AsseetImportType.AIT_Import, "CreateMesh");
                            var meshRName = RName.EditorOnly_GetRNameFromAbsFile(mAbsSavePath + "/" + ansiString + CEngineDesc.MeshExtension);
                            var mesh      = CEngine.Instance.MeshManager.CreateMesh(rc, meshRName, meshPrimitive);
                            CEngine.Instance.MeshManager.RemoveMesh(meshRName);
                            mesh.Init(rc, meshRName, meshPrimitive);
                            var mtl = await EngineNS.CEngine.Instance.MaterialInstanceManager.GetMaterialInstanceAsync(rc, RName.GetRName("Material/defaultmaterial.instmtl"));
                            for (int i = 0; i < mesh.MtlMeshArray.Length; ++i)
                            {
                                await mesh.SetMaterialInstanceAsync(rc, (uint)i, mtl, CEngine.Instance.PrebuildPassData.DefaultShadingEnvs);
                            }
                            Meshes.Add(ansiString, mesh);
                            mesh.SaveMesh();
                        }
                    }
                    return(true);
                }, EngineNS.Thread.Async.EAsyncTarget.AsyncEditor);
            }
            else
            {
                OnResourceImportCheck(this, AsseetImportType.AIT_Import, "CreateMeshPrimitive");
                meshPrimitive.Init(rc, fullPath, atom);
                SDK_AssetImporter_GetMeshPrimitiveByIndex(mCoreObject, rc.CoreObject, meshIndex, meshPrimitive.CoreObject);
                var skinNativePointer = SDK_AssetImporter_BuildMeshPrimitiveSkinModifierByIndex(mCoreObject, rc.CoreObject, meshIndex, meshPrimitive.CoreObject);
                if (skinNativePointer.GetPointer() != IntPtr.Zero)
                {
                    var skinModifier = new CGfxSkinModifier(skinNativePointer);
                    meshPrimitive.MdfQueue.AddModifier(skinModifier);
                    if (mImportOption.SkeletonAssetName != null)
                    {
                        var skeletonAsset = EngineNS.CEngine.Instance.SkeletonAssetManager.GetSkeleton(rc, mImportOption.SkeletonAssetName, false);
                        skinModifier.SkeletonAsset = mImportOption.SkeletonAssetName.Name;
                    }
                    else
                    {
                        var pureName      = CEngine.Instance.FileManager.GetPureFileFromFullName(mAbsFileName, false);
                        var path          = mAbsSavePath + "/" + pureName + CEngineDesc.SkeletonExtension;
                        var assetName     = RName.EditorOnly_GetRNameFromAbsFile(path);
                        var skeletonAsset = EngineNS.CEngine.Instance.SkeletonAssetManager.CreateSkeletonAsset(rc, assetName, skinModifier);
                        skinModifier.SkeletonAsset = assetName.Name;
                        if (!mSkeletonNeedInfo.ContainsKey(pureName))
                        {
                            mSkeletonNeedInfo.Add(pureName, assetName);
                        }
                    }
                }
                MeshPrimitives.Add(ansiString, meshPrimitive);
                meshPrimitive.SaveMesh();

                //gms
                if (mImportOption.CreatedGms)
                {
                    OnResourceImportCheck(this, AsseetImportType.AIT_Import, "CreateMes");
                    var meshRName = RName.EditorOnly_GetRNameFromAbsFile(mAbsSavePath + "/" + ansiString + CEngineDesc.MeshExtension);
                    var mesh      = CEngine.Instance.MeshManager.CreateMesh(rc, meshRName, meshPrimitive);
                    CEngine.Instance.MeshManager.RemoveMesh(meshRName);
                    mesh.Init(rc, meshRName, meshPrimitive);
                    var mtl = await EngineNS.CEngine.Instance.MaterialInstanceManager.GetMaterialInstanceAsync(rc, RName.GetRName("Material/defaultmaterial.instmtl"));

                    for (int i = 0; i < mesh.MtlMeshArray.Length; ++i)
                    {
                        await mesh.SetMaterialInstanceAsync(rc, (uint)i, mtl, CEngine.Instance.PrebuildPassData.DefaultShadingEnvs);
                    }
                    Meshes.Add(ansiString, mesh);
                    mesh.SaveMesh();
                }
            }
            //foreach(var mp in MeshPrimitives)
            //{
            //    mp.Value.SaveMesh();
            //}
            //foreach(var mesh in Meshes)
            //{
            //    mesh.Value.SaveMesh();
            //}
            //var info = await EditorCommon.Resources.ResourceInfoManager.Instance.CreateResourceInfoFromResource(fullPath.Address);
            //info.Save();
            return;
        }
Пример #5
0
        public static void LoadEngine()
        {
            if (loadedEngine)
            {
                return;
            }

            loadedEngine = true;

            Ogl.enableErrorCheck = true;

            InitConsole();

            DevConsole.Log(LogType.Info, "Creating Entity World...");

            coreWorker = new WorkerCycleCore();
            EntityWorld world = InitEcs();

            RenderPipelineCore.SetPipeline(new ForwardRenderPipeline());

            InitPhysics();
            InitSkybox();
            InitUI(world);
            InitLight();
            InitScene(world);

            DevConsole.Log(LogType.Info, "Entity world created.");

            Ogl.ClearColor(0.1f, 0.1f, 0.2f, 1.0f);
            Ogl.Enable(EnableCap.DepthTest);
            Ogl.Enable(EnableCap.CullFace);
            Ogl.Enable(EnableCap.ProgramPointSize);
            Ogl.PointSize(10f);

            EntityWorld InitEcs()
            {
                EntityWorld world = EntityWorld.CreateWorld();

                world.Runner.AssignToWorker(coreWorker).CreateSystemsAuto(world);
                EntityWorld.SetActive(world);
                return(world);
            }

            void InitPhysics()
            {
                PhysicsRunner physicsRunner = new PhysicsRunner();
                PhysicsWorld  world         = new PhysicsWorld();

                PhysicsWorld.SetDefaultWorld(world);
                physicsRunner.AddWorld(world);
                physicsRunner.AssignToWorker(coreWorker);
            }

            void InitScene(EntityWorld world)
            {
                Mesh   meshResource   = MeshPrimitives.CreateCube(1);
                Shader shaderResource = Shader.CreateShaderWithPath(AssetBrowser.Utilities.LocalToAbsolutePath(@"Shaders\standard.vert"),
                                                                    AssetBrowser.Utilities.LocalToAbsolutePath(@"Shaders\standard.frag"), "Standard Shader");

                Texture2D     texture          = new Texture2D(AssetBrowser.Utilities.LocalToAbsolutePath(@"Textures\Box.png"), "Box");
                Material      materialResource = new Material(shaderResource, texture);
                SC_RenderMesh renderMesh       = new SC_RenderMesh(meshResource, materialResource);

                EntityArchetype meshArchetype = new EntityArchetype(typeof(SC_RenderMesh), typeof(C_Transform), typeof(C_Position));
                EntityArchetype boxArchetype  = new EntityArchetype(typeof(SC_RenderMesh), typeof(C_Transform), typeof(C_Position), typeof(C_BoxTag));

                Entity planeEntity = world.EntityManager.CreateEntity(meshArchetype);

                world.EntityManager.SetComponent(planeEntity, new C_Position()
                {
                    value = new Vec3f(0, 0, 0)
                });
                //world.EntityManager.SetComponent(planeEntity, new C_PhysicsBody() { body = new PhysicBody() { isStatic = true } });
                Mesh     planeMesh     = MeshPrimitives.CreatePlaneXZ(50);
                Material planeMaterial = new Material(shaderResource, Texture2D.CreateWhiteTexture(64, 64));

                world.EntityManager.SetSharedComponent(planeEntity, new SC_RenderMesh(planeMesh, planeMaterial));

                Entity planeEntity2 = world.EntityManager.CreateEntity(meshArchetype);

                world.EntityManager.SetComponent(planeEntity2, new C_Position()
                {
                    value = new Vec3f(0, 5, -10)
                });
                //world.EntityManager.SetComponent(planeEntity2, new C_PhysicsBody() { body = new PhysicBody() { isStatic = true } });

                Mesh     planeMesh2     = MeshPrimitives.CreatePlaneXY(10);
                Material planeMaterial2 = new Material(shaderResource, texture);

                world.EntityManager.SetSharedComponent(planeEntity2, new SC_RenderMesh(planeMesh2, planeMaterial2));

                Entity boxEntity = world.EntityManager.CreateEntity(boxArchetype);

                world.EntityManager.SetComponent(boxEntity, new C_Position()
                {
                    value = new Vec3f(0, 2, 0)
                });
                //world.EntityManager.SetComponent(boxEntity, new C_PhysicsBody() { body = new PhysicBody() });
                world.EntityManager.SetSharedComponent(boxEntity, renderMesh);

                Entity boxEntity2 = world.EntityManager.CreateEntity(boxArchetype);

                world.EntityManager.SetComponent(boxEntity2, new C_Position()
                {
                    value = new Vec3f(2, 2, 0)
                });
                //world.EntityManager.SetComponent(boxEntity2, new C_PhysicsBody() { body = new PhysicBody() });
                world.EntityManager.SetSharedComponent(boxEntity2, renderMesh);

                Entity boxEntity3 = world.EntityManager.CreateEntity(boxArchetype);

                world.EntityManager.SetComponent(boxEntity3, new C_Position()
                {
                    value = new Vec3f(-2, 2, 0)
                });
                //world.EntityManager.SetComponent(boxEntity3, new C_PhysicsBody() { body = new PhysicBody() });

                world.EntityManager.SetSharedComponent(boxEntity3, renderMesh);

                EntityArchetype editorCameraArchetype = new EntityArchetype(typeof(C_Camera), typeof(C_Transform), typeof(C_EditorCamera));
                Entity          cameraEditorEntity    = world.EntityManager.CreateEntity(editorCameraArchetype);

                world.EntityManager.SetComponent(cameraEditorEntity, new C_Camera()
                {
                    cameraData = CameraData.CreatePerpectiveCamera(45f, 800f / 600f, 0.1f, 100f)
                });

                world.EntityManager.SetComponent(cameraEditorEntity, new C_EditorCamera()
                {
                    speed = 10f, focusPoint = new Vector3(0, 2, 0), focusDistance = 12, pitch = 20, yaw = 115, sensitivity = 20
                });
            }

            void InitLight()
            {
                if (RenderPipelineCore.TryGetContext(out LightsRenderData lightData))
                {
                    lightData.lights.Add(new DirectionalLight());
                }
            }

            void InitUI(EntityWorld world)
            {
                EntityArchetype canvasArch = new EntityArchetype(typeof(C_UICanvas));
                var             entity     = world.EntityManager.CreateEntity(canvasArch);

                world.EntityManager.SetComponent(entity, new C_UICanvas()
                {
                    canvas = new UICanvas()
                });
            }