예제 #1
0
        /// <summary>
        /// Creates a mount point at run-time. This won't persist unless you
        /// serialize the data yourself during run-time.
        /// </summary>
        /// <param name="rName">Name of the mount point</param>
        /// <param name="rBoneName">Bone name to attach it to or empty string to attach to root</param>
        /// <param name="rIgnoreParentScale">Determines if we should ignore the parent object's scale value</param>
        /// <returns></returns>
        public MountPoint CreateMountPoint(string rName, string rBoneName, bool rIgnoreParentScale)
        {
            // Create the mount point
            MountPoint lPoint = new MountPoint();

            lPoint.Owner    = gameObject;
            lPoint.Name     = rName;
            lPoint.BoneName = rBoneName;

            // Attach it to the right bone
            Transform lParentTransform = gameObject.transform;

            lPoint.Anchor      = new GameObject();
            lPoint.Anchor.name = "MP_" + lPoint.Anchor.GetInstanceID();

            if (lPoint.BoneName.Length > 0)
            {
                Animator lAnimator = gameObject.GetComponent <Animator>();
                if (lAnimator != null)
                {
                    int lBoneIndex = MountPoints.GetHumanBodyBoneID(lPoint.BoneName);
                    if (lBoneIndex >= 0 && lBoneIndex <= (int)HumanBodyBones.LastBone)
                    {
                        lParentTransform = lAnimator.GetBoneTransform((HumanBodyBones)lBoneIndex);
                    }
                    else
                    {
                        Transform lBoneTransform = MountPoints.FindBone(transform, lPoint.BoneName);
                        if (lBoneTransform != null)
                        {
                            lParentTransform = lBoneTransform;
                        }
                    }
                }
            }

            lPoint.Anchor.transform.position = lParentTransform.position;
            lPoint.Anchor.transform.rotation = lParentTransform.rotation;
            lPoint.Anchor.transform.parent   = lParentTransform;

            // Initialize by ignoring the scale
            lPoint.IgnoreParentScale = rIgnoreParentScale;

            // Add to the list of mount points
            Points.Add(lPoint);

            // Return the point
            return(lPoint);
        }
예제 #2
0
        /// <summary>
        /// Anchors the mount point to the specified bone, essencially making
        /// this mount point a child of the bone.
        /// </summary>
        /// <param name="rBoneName">Bone name to anchor to or empty string to anchor to the root</param>
        public void AnchorTo(string rBoneName)
        {
            Transform lParentTransform = _Owner.transform;

            if (_Anchor == null)
            {
                _Anchor      = new GameObject();
                _Anchor.name = "MP_" + _Anchor.GetInstanceID();
            }

            _BoneName = rBoneName;
            if (_BoneName.Length > 0)
            {
                Animator lAnimator = _Owner.GetComponent <Animator>();
                if (lAnimator != null)
                {
                    int lBoneIndex = MountPoints.GetHumanBodyBoneID(_BoneName);
                    if (lBoneIndex >= 0 && lBoneIndex < (int)HumanBodyBones.LastBone)
                    {
                        lParentTransform = lAnimator.GetBoneTransform((HumanBodyBones)lBoneIndex);
                    }
                    else
                    {
                        Transform lBoneTransform = MountPoints.FindBone(_Owner.transform, _BoneName);
                        if (lBoneTransform != null)
                        {
                            lParentTransform = lBoneTransform;
                        }
                    }
                }
            }

            // Parent the mount point to this new transform. We don't
            // change it's position or rotation since we may need an offset.
            _Anchor.transform.parent = lParentTransform;
        }
예제 #3
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);
        }