示例#1
0
        /// <summary>
        /// Creates an instance of the prefab at the resource path
        /// </summary>
        /// <param name="rParent">MountPoints that will be the parent of the instance</param>
        /// <returns>Instance that was created</returns>
        public GameObject CreateInstance(MountPoints rParent)
        {
            if (_ResourcePath.Length == 0)
            {
                return(null);
            }

            // Extract out the parent's skinned mesh renderer. This should be a high level
            // renderer that contains all the bones we'll need.
            SkinnedMeshRenderer lParentSMR = rParent._Renderer;

            if (lParentSMR == null)
            {
                lParentSMR = rParent.gameObject.GetComponent <SkinnedMeshRenderer>();
            }
            if (lParentSMR == null)
            {
                lParentSMR = rParent.gameObject.GetComponentInChildren <SkinnedMeshRenderer>();
            }
            if (lParentSMR == null)
            {
                return(null);
            }

            // Create the child
            UnityEngine.Object lResource = Resources.Load(_ResourcePath);

#if UNITY_EDITOR
            if (lResource == null)
            {
                lResource = UnityEditor.AssetDatabase.LoadAssetAtPath <GameObject>("Assets\\" + _ResourcePath);
            }
            if (lResource == null)
            {
                lResource = UnityEditor.AssetDatabase.LoadAssetAtPath <GameObject>("Assets\\" + _ResourcePath + ".prefab");
            }
            if (lResource == null)
            {
                lResource = UnityEditor.AssetDatabase.LoadAssetAtPath <GameObject>("Assets\\" + _ResourcePath + ".fbx");
            }
#endif

            if (lResource == null)
            {
                return(null);
            }

            _GameObject = (GameObject)GameObject.Instantiate(lResource);
            if (_GameObject == null)
            {
                return(null);
            }


            //NetworkServer.Spawn(_GameObject);

            // Don't show the child in the hierarchy
            //lChild.hideFlags = HideFlags.HideInHierarchy;

            // Extract out the Skinned Mesh Renderers
            SkinnedMeshRenderer[] lChildSMRs = _GameObject.GetComponents <SkinnedMeshRenderer>();
            if (lChildSMRs == null || lChildSMRs.Length == 0)
            {
                lChildSMRs = _GameObject.GetComponentsInChildren <SkinnedMeshRenderer>();
            }

            // If there's no skinned mesh renderer, we can't really continue
            if (lChildSMRs == null || lChildSMRs.Length == 0)
            {
                DestroyInstance();
                return(null);
            }

            // For each of the renderers, we need to set the bones
            List <Transform> lOldRootBones = new List <Transform>();

            for (int i = 0; i < lChildSMRs.Length; i++)
            {
                SkinnedMeshRenderer lChildSMR = lChildSMRs[i];

                Cloth lChildSMRCloth = lChildSMR.gameObject.GetComponent <Cloth>();

                // Parent it to the parent
                _GameObject.transform.parent        = rParent.gameObject.transform;
                _GameObject.transform.localPosition = Vector3.zero;
                _GameObject.transform.localRotation = Quaternion.identity;
                _GameObject.transform.localScale    = Vector3.one;

                // Go through the bones of the new SM and try to find matching
                // bones from the parent
                List <Transform> lChildBones  = new List <Transform>();
                List <Transform> lTargetBones = new List <Transform>();

                for (int j = 0; j < lChildSMR.bones.Length; j++)
                {
                    Transform lChildBone  = lChildSMR.bones[j];
                    Transform lTargetBone = null;

                    for (int k = 0; k < lParentSMR.bones.Length; k++)
                    {
                        if (MountPoints.CompareBoneNames(lParentSMR.bones[k].name, lChildBone.name))
                        {
                            lTargetBone = lParentSMR.bones[k];
                            break;
                        }
                    }

                    if (lTargetBone == null)
                    {
                        lTargetBone = MountPoints.FindBone(rParent.gameObject.transform, lChildBone.name);
                    }

                    if (lTargetBone != null)
                    {
                        lChildBones.Add(lChildBone);
                        lTargetBones.Add(lTargetBone);
                    }
                }

                lChildSMR.bones = lTargetBones.ToArray();

                // We want to grab the parent's bone that corresponds to our root. We don't
                // just take the parent's root bone since it could be different (ie for boots).
                if (!lOldRootBones.Contains(lChildSMR.rootBone))
                {
                    lOldRootBones.Add(lChildSMR.rootBone);
                }
                lChildSMR.rootBone = MountPoints.FindBone(rParent.gameObject.transform, lChildSMR.rootBone.name);

                // If we're dealing with clothe we need to reassign the colliders
                // Handle clothing if it exists. We may need to move colliders
                if (lChildSMRCloth != null && lChildSMRCloth.capsuleColliders != null)
                {
                    List <CapsuleCollider> lTargetColliders = new List <CapsuleCollider>();

                    for (int j = 0; j < lChildSMRCloth.capsuleColliders.Length; j++)
                    {
                        if (lChildSMRCloth.capsuleColliders[j] == null)
                        {
                            lTargetColliders.Add(null); continue;
                        }

                        int lIndex = lChildBones.IndexOf(lChildSMRCloth.capsuleColliders[j].transform);

                        // If the clothing bone has a collider, our real skeleton may need one too
                        CapsuleCollider lChildCollider = lChildSMRCloth.capsuleColliders[j];
                        if (lChildCollider != null)
                        {
                            // If there's not one, create it
                            CapsuleCollider lParentCollider = lTargetBones[lIndex].GetComponent <CapsuleCollider>();
                            if (lParentCollider == null)
                            {
                                lParentCollider = lTargetBones[lIndex].gameObject.AddComponent <CapsuleCollider>();
                                lParentCollider.GetCopyOf(lChildCollider);
                            }

                            // Change the collider in the clothing
                            for (int k = 0; k < lChildSMRCloth.capsuleColliders.Length; k++)
                            {
                                if (lChildSMRCloth.capsuleColliders[k] == lChildCollider)
                                {
                                    lTargetColliders.Add(lParentCollider);
                                }
                            }
                        }
                    }

                    lChildSMRCloth.capsuleColliders = lTargetColliders.ToArray();
                }

                // Set the update flag per request
                if (_UpdateWhenOffScreen)
                {
                    lChildSMR.updateWhenOffscreen = _UpdateWhenOffScreen;
                }
            }

            // Destroy any old root bones
            for (int i = lOldRootBones.Count - 1; i >= 0; i--)
            {
                if (Application.isPlaying)
                {
                    UnityEngine.GameObject.Destroy(lOldRootBones[i].gameObject);
                }
                else
                {
                    UnityEngine.GameObject.DestroyImmediate(lOldRootBones[i].gameObject);
                }
            }

            // Destroy any old animators
            Animator[] lOldAnimators = _GameObject.GetComponents <Animator>();
            if (lOldAnimators == null || lOldAnimators.Length == 0)
            {
                _GameObject.GetComponentsInChildren <Animator>();
            }

            for (int i = lOldAnimators.Length - 1; i >= 0; i--)
            {
                if (Application.isPlaying)
                {
                    UnityEngine.Component.Destroy(lOldAnimators[i]);
                }
                else
                {
                    UnityEngine.Component.DestroyImmediate(lOldAnimators[i]);
                }
            }

            // Disable visibility if we need to
            if (!_IsVisible)
            {
                Renderer lRenderer = _GameObject.GetComponent <Renderer>();
                if (lRenderer == null)
                {
                    lRenderer = _GameObject.GetComponentInChildren <Renderer>();
                }
                if (lRenderer != null)
                {
                    lRenderer.enabled = false;
                }
            }

            // Return the new game object
            return(_GameObject);
        }