Example #1
0
 /// <summary>
 /// Destroys the instance of the skinned item
 /// </summary>
 /// <param name="rItem"></param>
 public void RemoveSkinnedItemInstance(SkinnedItem rItem)
 {
     if (rItem == null || rItem._GameObject == null) { return; }
     rItem.DestroyInstance();
 }
Example #2
0
        /// <summary>
        /// Instanciate a child GameObject and use the parent bones in order to drive this child's skinned mesh.
        /// Since skinned meshes wrap specific bones, we don't need a parent bone to attach the child to.
        /// </summary>
        /// <param name="rItemPath">Path to the prefab we'll instanciate</param>
        /// <returns>MountItem containing the results of the instanciation</returns>
        public SkinnedItem AddSkinnedItem(string rItemPath)
        {
            if (rItemPath == null || rItemPath.Length == 0) { return null; }

            SkinnedItem lItem = new SkinnedItem();
            lItem.ResourcePath = rItemPath;

            bool lCreated = AddSkinnedItem(lItem);
            if (!lCreated) { return null; }

            return lItem;
        }
Example #3
0
        /// <summary>
        /// Removes the skinned mesh from the list of items
        /// </summary>
        /// <param name="rItem"></param>
        public void RemoveSkinnedItem(SkinnedItem rItem)
        {
            if (rItem == null) { return; }

            rItem.DestroyInstance();
            SkinnedItems.Remove(rItem);

            // Apply the body masks if needed
            ApplyBodyMasks();
        }
Example #4
0
        /// <summary>
        /// Instanciate a child GameObject and use the parent bones in order to drive this child's skinned mesh.
        /// Since skinned meshes wrap specific bones, we don't need a parent bone to attach the child to.
        /// </summary>
        /// <param name="rItem">MountItem containing the location of the prefab and mask to instanciate</param>
        /// <returns>Boolean that determines if we added the skinned mesh</returns>
        public bool AddSkinnedItem(SkinnedItem rItem)
        {
            if (SkinnedItems.Contains(rItem)) { return false; }

            rItem.IsVisible = (rItem.ResourcePath.Length > 0); 
            rItem.IsMaskVisible = (rItem.MaskPath.Length > 0);

            // Create the instance from the path
            if (rItem.ResourcePath.Length > 0)
            {
                rItem.CreateInstance(this);
                if (rItem.GameObject == null) { return false; }
            }

            // Add the mount item to the list
            if (_UseBodyMasks && rItem.MaskPath.Length > 0)
            {
                rItem.CreateMask();
            }

            // Add the item to our list
            SkinnedItems.Add(rItem);

            // Apply the body masks if needed
            ApplyBodyMasks();

            // Return success
            return true;
        }
    /// <summary>
    /// Renders the properties of the motion so they can be changed here
    /// </summary>
    /// <param name="rLayerIndex">Layer the motion belongs to</param>
    /// <param name="rMotionIndex">Motions whose properites are to be listed</param>
    private bool DrawItemDetailItem(SkinnedItem rItem)
    {
        bool lIsDirty = false;

        EditorHelper.DrawSmallTitle(rItem.Name);

        // Warning about the resource not being found
        if (rItem._GameObject == null && rItem._ResourcePath.Length > 0 && Resources.Load(rItem._ResourcePath) == null)
        {
            EditorHelper.DrawInspectorDescription("Resource not found. If you want to instantiate the item at run-time, please ensure the file is in a 'Resources' folder.", MessageType.None);
            GUILayout.Space(5);
        }
        else
        {
            EditorGUILayout.LabelField("", GUILayout.Height(1f));
        }

        // Friendly name
        string lNewName = EditorGUILayout.TextField(new GUIContent("Name", "Friendly name of the skinned item."), rItem.Name);
        if (lNewName != rItem.Name)
        {
            lIsDirty = true;
            rItem.Name = lNewName;
        }

        // Resource Path
        string lNewResourcePath = EditorGUILayout.TextField(new GUIContent("Resource Path", "Path to the prefab resource that is the item."), rItem.ResourcePath);
        if (lNewResourcePath != rItem.ResourcePath)
        {
            lIsDirty = true;
            rItem.ResourcePath = lNewResourcePath;
        }

        // Mask Path
        string lNewMaskPath = EditorGUILayout.TextField(new GUIContent("Mask Path", "Path to the texture resource that will mask the body."), rItem.MaskPath);
        if (lNewMaskPath != rItem.MaskPath)
        {
            lIsDirty = true;

            // Now we can set the mask
            rItem.MaskPath = lNewMaskPath;

            // If it was visible or if it is now, we need to apply the mask
            if (Application.isPlaying && mTarget.UseBodyMasks)
            {
                rItem.CreateMask();
                mTarget.ApplyBodyMasks();
            }
        }

        bool lNewInstanciateOnStart = EditorGUILayout.Toggle(new GUIContent("Instantiate On Start", "Determines if we create an instance of the object and mask when the game starts."), rItem.InstantiateOnStart);
        if (lNewInstanciateOnStart != rItem.InstantiateOnStart)
        {
            lIsDirty = true;
            rItem.InstantiateOnStart = lNewInstanciateOnStart;
        }

        bool lNewIsVisible = EditorGUILayout.Toggle(new GUIContent("Is Instance Visible", "Determines if the object itself is visible."), rItem.IsVisible);
        if (lNewIsVisible != rItem.IsVisible)
        {
            lIsDirty = true;
            rItem.IsVisible = lNewIsVisible;
        }

        bool lNewIsMaskVisible = EditorGUILayout.Toggle(new GUIContent("Is Mask Visible", "Determines if the body mask is visible."), rItem.IsMaskVisible);
        if (lNewIsMaskVisible != rItem.IsMaskVisible)
        {
            lIsDirty = true;

            // Now we can set the visability
            rItem.IsMaskVisible = lNewIsMaskVisible;

            // If it was visible or if it is now, we need to apply the mask
            if (Application.isPlaying && mTarget.UseBodyMasks)
            {
                mTarget.ApplyBodyMasks();
            }
        }

        // Object
        EditorHelper.DrawLine();

        EditorGUILayout.BeginHorizontal();

        GUILayout.Label("Instance:", GUILayout.Width(60));

        if (rItem.GameObject == null)
        {
            GUILayout.Label("<none>", GUILayout.MinWidth(100));

            if (GUILayout.Button(new GUIContent("", "Create instance"), EditorHelper.BlueAddButton, GUILayout.Width(16), GUILayout.Height(16)))
            {
                rItem.CreateInstance(mTarget);

                if (mTarget.UseBodyMasks)
                {
                    rItem.CreateMask();
                    mTarget.ApplyBodyMasks();
                }
            }
        }
        else
        {
            GUILayout.Label(rItem.GameObject.name, GUILayout.MinWidth(100));

            if (GUILayout.Button(new GUIContent("", "Select instance"), EditorHelper.BlueSelectButton, GUILayout.Width(16), GUILayout.Height(16)))
            {
                Selection.activeGameObject = rItem.GameObject;
            }

            if (GUILayout.Button(new GUIContent("", "Delete instance"), EditorHelper.RedXButton, GUILayout.Width(16), GUILayout.Height(16)))
            {
                mTarget.RemoveSkinnedItemInstance(rItem);
            }
        }

        GUILayout.Space(2);

        EditorGUILayout.EndHorizontal();

        GUILayout.Space(5);

        return lIsDirty;
    }
    /// <summary>
    /// Allows us to add to a list
    /// </summary>
    /// <param name="rList"></param>
    private void OnItemListItemAdd(ReorderableList rList)
    {
        // Create a skinned item
        SkinnedItem lItem = new SkinnedItem();
        mTarget.AddSkinnedItem(lItem);

        // Set the visible values after we add it 
        lItem.IsVisible = true;
        lItem.IsMaskVisible = true;

        // Make it the selected one
        mItemList.index = mTarget.SkinnedItems.Count - 1;
        OnItemListItemSelect(rList);

        mIsDirty = true;
    }
Example #7
0
    /// <summary>
    /// Renders the properties of the motion so they can be changed here
    /// </summary>
    /// <param name="rLayerIndex">Layer the motion belongs to</param>
    /// <param name="rMotionIndex">Motions whose properites are to be listed</param>
    private bool DrawItemDetailItem(SkinnedItem rItem)
    {
        bool lIsDirty = false;

        EditorHelper.DrawSmallTitle(rItem.Name);

        // Warning about the resource not being found
        if (rItem._GameObject == null && rItem._ResourcePath.Length > 0 && Resources.Load(rItem._ResourcePath) == null)
        {
            EditorHelper.DrawInspectorDescription("Resource not found. If you want to instantiate the item at run-time, please ensure the file is in a 'Resources' folder.", MessageType.None);
            GUILayout.Space(5);
        }
        else
        {
            EditorGUILayout.LabelField("", GUILayout.Height(1f));
        }

        // Friendly name
        string lNewName = EditorGUILayout.TextField(new GUIContent("Name", "Friendly name of the skinned item."), rItem.Name);

        if (lNewName != rItem.Name)
        {
            lIsDirty   = true;
            rItem.Name = lNewName;
        }

        // Resource Path
        EditorGUILayout.BeginHorizontal();

        string lNewResourcePath = EditorGUILayout.TextField(new GUIContent("Resource Path", "Path to the prefab resource that is the item."), rItem.ResourcePath);

        if (lNewResourcePath != rItem.ResourcePath)
        {
            lIsDirty           = true;
            rItem.ResourcePath = lNewResourcePath;
        }

        if (GUILayout.Button(new GUIContent("...", "Select resource"), EditorStyles.miniButton, GUILayout.Width(20)))
        {
            lNewResourcePath = EditorUtility.OpenFilePanel("Select the file", mLastPath, "fbx,prefab");
            if (lNewResourcePath.Length != 0)
            {
                mLastPath = lNewResourcePath;

                int lStartResource = lNewResourcePath.IndexOf("Resources");
                if (lStartResource >= 0)
                {
                    lNewResourcePath = lNewResourcePath.Substring(lStartResource + 10);
                }

                lStartResource = lNewResourcePath.IndexOf("Assets");
                if (lStartResource >= 0)
                {
                    lNewResourcePath = lNewResourcePath.Substring(lStartResource + 7);
                }

                int lStartExtension = lNewResourcePath.LastIndexOf(".");
                if (lStartExtension > 0)
                {
                    lNewResourcePath = lNewResourcePath.Substring(0, lStartExtension);
                }

                if (lNewResourcePath != rItem.ResourcePath)
                {
                    lIsDirty           = true;
                    rItem.ResourcePath = lNewResourcePath;
                }
            }
        }

        EditorGUILayout.EndHorizontal();

        // Mask Path
        EditorGUILayout.BeginHorizontal();

        string lNewMaskPath = EditorGUILayout.TextField(new GUIContent("Mask Path", "Path to the texture resource that will mask the body."), rItem.MaskPath);

        if (lNewMaskPath != rItem.MaskPath)
        {
            lIsDirty = true;

            // Now we can set the mask
            rItem.MaskPath = lNewMaskPath;

            // If it was visible or if it is now, we need to apply the mask
            if (Application.isPlaying && mTarget.UseBodyMasks)
            {
                rItem.CreateMask();
                mTarget.ApplyBodyMasks();
            }
        }

        if (GUILayout.Button(new GUIContent("...", "Select mask"), EditorStyles.miniButton, GUILayout.Width(20)))
        {
            lNewMaskPath = EditorUtility.OpenFilePanel("Select the file", mLastPath, "png,jpg,psd");
            if (lNewMaskPath.Length != 0)
            {
                mLastPath = lNewMaskPath;

                int lStartResource = lNewMaskPath.IndexOf("Resources");
                if (lStartResource >= 0)
                {
                    lNewMaskPath = lNewMaskPath.Substring(lStartResource + 10);
                }

                lStartResource = lNewMaskPath.IndexOf("Assets");
                if (lStartResource >= 0)
                {
                    lNewMaskPath = lNewMaskPath.Substring(lStartResource + 7);
                }

                int lStartExtension = lNewMaskPath.LastIndexOf(".");
                if (lStartExtension > 0)
                {
                    lNewMaskPath = lNewMaskPath.Substring(0, lStartExtension);
                }

                if (lNewMaskPath != rItem.MaskPath)
                {
                    lIsDirty = true;

                    // Now we can set the mask
                    rItem.MaskPath = lNewMaskPath;

                    // If it was visible or if it is now, we need to apply the mask
                    if (Application.isPlaying && mTarget.UseBodyMasks)
                    {
                        rItem.CreateMask();
                        mTarget.ApplyBodyMasks();
                    }
                }
            }
        }

        EditorGUILayout.EndHorizontal();

        bool lNewInstanciateOnStart = EditorGUILayout.Toggle(new GUIContent("Instantiate On Start", "Determines if we create an instance of the object and mask when the game starts."), rItem.InstantiateOnStart);

        if (lNewInstanciateOnStart != rItem.InstantiateOnStart)
        {
            lIsDirty = true;
            rItem.InstantiateOnStart = lNewInstanciateOnStart;
        }

        bool lNewIsVisible = EditorGUILayout.Toggle(new GUIContent("Is Instance Visible", "Determines if the object itself is visible."), rItem.IsVisible);

        if (lNewIsVisible != rItem.IsVisible)
        {
            lIsDirty        = true;
            rItem.IsVisible = lNewIsVisible;
        }

        bool lNewIsMaskVisible = EditorGUILayout.Toggle(new GUIContent("Is Mask Visible", "Determines if the body mask is visible."), rItem.IsMaskVisible);

        if (lNewIsMaskVisible != rItem.IsMaskVisible)
        {
            lIsDirty = true;

            // Now we can set the visability
            rItem.IsMaskVisible = lNewIsMaskVisible;

            // If it was visible or if it is now, we need to apply the mask
            if (Application.isPlaying && mTarget.UseBodyMasks)
            {
                mTarget.ApplyBodyMasks();
            }
        }

        bool lNewUpdateWhenOffScreen = EditorGUILayout.Toggle(new GUIContent("Update Offscreen", "Useful if Unity hides the item at-runtime."), rItem.UpdateWhenOffScreen);

        if (lNewUpdateWhenOffScreen != rItem.UpdateWhenOffScreen)
        {
            lIsDirty = true;
            rItem.UpdateWhenOffScreen = lNewUpdateWhenOffScreen;
        }

        // Object
        EditorHelper.DrawLine();

        EditorGUILayout.BeginHorizontal();

        GUILayout.Label("Instance:", GUILayout.Width(60));

        if (rItem.GameObject == null)
        {
            GUILayout.Label("<none>", GUILayout.MinWidth(100));

            if (GUILayout.Button(new GUIContent("", "Create instance"), EditorHelper.BlueAddButton, GUILayout.Width(16), GUILayout.Height(16)))
            {
                rItem.CreateInstance(mTarget);

                if (mTarget.UseBodyMasks)
                {
                    rItem.CreateMask();
                    mTarget.ApplyBodyMasks();
                }
            }
        }
        else
        {
            GUILayout.Label(rItem.GameObject.name, GUILayout.MinWidth(100));

            if (GUILayout.Button(new GUIContent("", "Select instance"), EditorHelper.BlueSelectButton, GUILayout.Width(16), GUILayout.Height(16)))
            {
                Selection.activeGameObject = rItem.GameObject;
            }

            if (GUILayout.Button(new GUIContent("", "Delete instance"), EditorHelper.RedXButton, GUILayout.Width(16), GUILayout.Height(16)))
            {
                mTarget.RemoveSkinnedItemInstance(rItem);
            }
        }

        GUILayout.Space(2);

        EditorGUILayout.EndHorizontal();

        GUILayout.Space(5);

        return(lIsDirty);
    }
Example #8
0
    /// <summary>
    /// Called when the inspector needs to draw
    /// </summary>
    public override void OnInspectorGUI()
    {
        // Pulls variables from runtime so we have the latest values.
        mTargetSO.Update();

        // Clean up the mount points to ensure everything stays in sync
        PreProcessPoints();

        GUILayout.Space(5);

        EditorHelper.DrawInspectorTitle("ootii Mount List");

        EditorHelper.DrawInspectorDescription("Manages multiple mount point and allows for others to connect. Also supports skinned meshes.", MessageType.None);

        GUILayout.Space(5);

        float lNewSnapDistance = EditorGUILayout.FloatField(new GUIContent("Snap Distance", "Snap distance for all mount points."), MountPoints.EditorSnapDistance);

        if (lNewSnapDistance != MountPoints.EditorSnapDistance)
        {
            MountPoints.EditorSnapDistance = lNewSnapDistance;
        }

        if (!IsAddMountPointEnabled(mTarget))
        {
            GUILayout.Space(5);

            EditorGUILayout.HelpBox("Unity prevents mount points from being parented directly on the prefab. Instead, add them to a prefab instance and then press 'apply' to update the prefab.", MessageType.Warning);
        }

        // Show the points
        GUILayout.BeginVertical(EditorHelper.GroupBox);
        mPointList.DoLayoutList();
        GUILayout.EndVertical();

        if (mPointList.index >= 0)
        {
            EditorGUILayout.BeginVertical(EditorHelper.Box);

            MountPoint lPoint = mTarget.Points[mPointList.index];

            bool lItemIsDirty = DrawPointDetailItem(lPoint);
            if (lItemIsDirty)
            {
                mIsDirty = true;
            }

            EditorGUILayout.EndVertical();
        }

        GUILayout.Space(5);
        EditorHelper.DrawLine();
        GUILayout.Space(5);

        SkinnedMeshRenderer lNewRenderer = EditorGUILayout.ObjectField(new GUIContent("Body Skin Renderer", "Skinned Mesh Renderer containing the bones and materials we'll use."), mTarget.Renderer, typeof(SkinnedMeshRenderer), true) as SkinnedMeshRenderer;

        if (lNewRenderer != mTarget.Renderer)
        {
            mIsDirty         = true;
            mTarget.Renderer = lNewRenderer;
        }

        bool lNewUseBodyMasks = EditorGUILayout.Toggle(new GUIContent("Use Body Masks", "Processes mask textures to hide parts of the main body."), mTarget.UseBodyMasks);

        if (lNewUseBodyMasks != mTarget.UseBodyMasks)
        {
            mIsDirty             = true;
            mTarget.UseBodyMasks = lNewUseBodyMasks;
        }

        if (mTarget.UseBodyMasks)
        {
            int lNewBodyMaskIndex = EditorGUILayout.IntField(new GUIContent("  Material Index", "Index of the material that is the skin texture to modify."), mTarget.MaterialIndex);
            if (lNewBodyMaskIndex != mTarget.MaterialIndex)
            {
                mIsDirty = true;
                mTarget.MaterialIndex = lNewBodyMaskIndex;
            }

            EditorHelper.DrawInspectorDescription("Ensure your actor's body material Rendering Mode is set to 'Cutout' or 'Transparency'.", MessageType.None);
            GUILayout.Space(5);
        }

        // Show the skinned items
        GUILayout.BeginVertical(EditorHelper.GroupBox);
        mItemList.DoLayoutList();
        GUILayout.EndVertical();

        if (mItemList.index >= 0)
        {
            if (mItemList.index < mTarget.SkinnedItems.Count)
            {
                EditorGUILayout.BeginVertical(EditorHelper.Box);

                SkinnedItem lItem = mTarget.SkinnedItems[mItemList.index];

                bool lItemIsDirty = DrawItemDetailItem(lItem);
                if (lItemIsDirty)
                {
                    mIsDirty = true;
                }

                EditorGUILayout.EndVertical();
            }
            else
            {
                mItemList.index = -1;
            }
        }

        GUILayout.Space(5);

        // If there is a change... update.
        if (mIsDirty)
        {
            // Flag the object as needing to be saved
            EditorUtility.SetDirty(mTarget);

#if UNITY_4_0 || UNITY_4_0_1 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2
            EditorApplication.MarkSceneDirty();
#else
            if (!EditorApplication.isPlaying)
            {
                UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene());
            }
#endif

            // Pushes the values back to the runtime so it has the changes
            mTargetSO.ApplyModifiedProperties();

            // Clear out the dirty flag
            mIsDirty = false;
        }
    }