public static void AdjustPose(Transform newParent, ModelDataTemplate.ModelImportData modelData, Bounds bounds)
        {
            //set custom properties
            newParent.transform.localScale *= modelData.scale;

            //Check for our highest extent to know how much to offset it up (to lift it up in relation to its scale)
            var lowestPoint = Mathf.Infinity;

            if (lowestPoint > bounds.extents.y)
            {
                lowestPoint = bounds.extents.y;
            }

            newParent.transform.position += Vector3.up * lowestPoint;

            newParent.rotation = Quaternion.Euler(modelData.euler_rotation);
        }
예제 #2
0
        public void VerifyModelData(ModelDataTemplate.ModelImportData data)
        {
            if (string.IsNullOrEmpty(data.name) || string.IsNullOrWhiteSpace(data.name))
            {
                throw new System.Exception("model name cannot be empty.");
            }

            if (string.IsNullOrEmpty(data.url) || string.IsNullOrWhiteSpace(data.url))
            {
                throw new System.Exception("Asset Data URL cannot be empty.");
            }

            if (data.scale < 0.001 && data.scale > -0.001)
            {
                Debug.LogWarning($"Scale of imported model {data.name} is between -0.001 and 0.001. Results may not be as expected.");
            }

            if (data.scale > 1000 || data.scale < -1000)
            {
                Debug.LogWarning($"Scale of imported model {data.name} is above 1000 or below -1000. Results may not be as expected.");
            }
        }
        /// <summary>
        /// Set up imported objects with colliders, register them to be used accross the network, and set properties from the data received and the setup flags from AssetImportSetupSettings
        /// </summary>
        /// <param name="menuButtonIndex"> index of Menu Button. </param>
        /// <param name="modelData"> custom data received by the network</param>
        /// <param name="loadedObject"> our loaded object</param>
        /// <param name="setupFlags"> setup instructions</param>
        /// <returns></returns>
        public static GameObject SetUpGameObject(int menuButtonIndex, ModelDataTemplate.ModelImportData modelData, GameObject loadedObject, ModelImportSettings setupFlags = null)
        {
            const float defaultFitToScale       = 2;
            const bool  defaultDoSetUpColliders = true;
            const bool  defaultIsNetworked      = true;
            const float defaultModelSpawnHeight = 0.0f;

            if (loadedObject == null)
            {
                throw new System.Exception("Failed to import an model at runtime because the loaded object was null. Please ensure your custom runtime importer properly returns a valid GameObject.");
            }

            if (setupFlags == null)
            {
                setupFlags                  = ScriptableObject.CreateInstance <ModelImportSettings>();
                setupFlags.fitToScale       = defaultFitToScale;
                setupFlags.doSetUpColliders = defaultDoSetUpColliders;
                setupFlags.isNetworked      = defaultIsNetworked;
                setupFlags.spawnHeight      = defaultModelSpawnHeight;
            }

            //parent of model in list
            Transform newParent = new GameObject(menuButtonIndex.ToString()).transform;

            NetworkedGameObject nRGO = default;

            if (setupFlags.isNetworked)
            {
                //set up reference to use with network
                nRGO = NetworkedObjectsManager.Instance.CreateNetworkedGameObject(newParent.gameObject, menuButtonIndex, modelData.id);
            }

            //provide appropriate tag to enable it to be grabbed
            newParent.gameObject.gameObject.tag = TagList.interactable;

            newParent.gameObject.SetActive(false);

            Bounds bounds = new Bounds();

            if (setupFlags.doSetUpColliders)
            {
                SetUpColliders(loadedObject, bounds, newParent, modelData, setupFlags, menuButtonIndex);

                //turn off whole colliders for non-whole objects
                if (!modelData.isWholeObject)
                {
                    SetUpSubObjects(newParent, loadedObject, menuButtonIndex);
                }

                SetUpAnimation(newParent, loadedObject, modelData.isWholeObject);
                AdjustHeight(newParent, setupFlags);
                AdjustScale(newParent, bounds, setupFlags);
            }

            AdjustPose(newParent, modelData, bounds);

            //Initialize fields for ECS
            ConvertObjectsToEntities(nRGO, newParent, menuButtonIndex);

            newParent.gameObject.SetActive(false);

            return(newParent.gameObject);
        }
        public static void SetUpColliders(GameObject loadedObject, Bounds bounds, Transform newParent, ModelDataTemplate.ModelImportData modelData, ModelImportSettings setupFlags, int menuButtonIndex)
        {
            //clear subobjectlist for new object processiong
            List <Bounds> subObjectBounds = new List <Bounds>();

            //reset rotation to avoid align axis bounding errors
            loadedObject.transform.rotation = Quaternion.identity;

            //obtain all bounds from skinned mesh renderer and skinned mesh remderer
            CombineMesh(loadedObject.transform, subObjectBounds);

            if (subObjectBounds.Count > 0)
            {
                bounds = new Bounds(subObjectBounds[0].center, Vector3.one * 0.02f);
            }

            //set bounds from all sub-objects
            for (int i = 0; i < subObjectBounds.Count; i++)
            {
                bounds.Encapsulate(new Bounds(subObjectBounds[i].center, subObjectBounds[i].size));
            }

            //set collider properties
            var wholeCollider = newParent.gameObject.AddComponent <BoxCollider>();

            //center the collider to our new parent and send proper size of it based on the renderers picked up
            wholeCollider.center = Vector3.zero;// bounds.center;
            wholeCollider.size   = bounds.size;

            //set parent to be the center of our loaded object to show correct deformations with scalling
            newParent.transform.position = bounds.center;

            loadedObject.transform.SetParent(newParent.transform, true);
        }