コード例 #1
0
        public override void OnInspectorGUI()
        {
            EditorGUI.BeginDisabledGroup(true);
            DrawDefaultInspector();
            EditorGUI.EndDisabledGroup();

            HullPainterChild child = target as HullPainterChild;

            if (child.parent != null)
            {
                Hull sourceHull = child.parent.FindSourceHull(child);
                if (sourceHull != null)
                {
                    EditorGUI.BeginDisabledGroup(true);
                    EditorGUILayout.TextField("Source Hull", sourceHull.name);
                    EditorGUI.EndDisabledGroup();
                }
                else
                {
                    EditorGUILayout.LabelField("No souce hull for this child");
                }
            }
            else
            {
                EditorGUILayout.LabelField("Missing parent!");
            }
        }
コード例 #2
0
        private void AddMapping(Hull hull, Collider col, HullPainterChild painterChild)
        {
            HullMapping newMapping = new HullMapping()
            {
                sourceHull        = hull,
                generatedCollider = col,
                targetChild       = painterChild
            };

            this.hullMapping.Add(newMapping);
        }
コード例 #3
0
        /** Gui drawn if the selected object does not have a valid and initialised hull painter on it
         */
        private void DrawInactiveGui()
        {
            if (Selection.transforms.Length == 1)
            {
                // Have a single scene selection, is it viable?

                GameObject       selectedObject = Selection.transforms[0].gameObject;
                MeshFilter       srcMesh        = SelectionUtil.FindSelectedMeshFilter();
                HullPainterChild child          = SelectionUtil.FindSelectedHullPainterChild();

                if (srcMesh != null)
                {
                    GUILayout.Space(10);
                    GUILayout.Label("Generate an asset to start painting:");
                    CommonUi.DrawGenerateOrReconnectGui(selectedObject, srcMesh.sharedMesh);
                }
                else if (child != null)
                {
                    GUILayout.Space(10);
                    GUILayout.Label("Child hulls are not edited directly - select the parent to continue painting this hull");
                }
                else
                {
                    // No mesh filter, might have a hull painter (or not)

                    GUILayout.Space(10);
                    GUILayout.Label("To start painting, select a single scene object");
                    GUILayout.Label("The object must contain a MeshFilter");

                    GUILayout.Space(10);
                    GUILayout.Label("No MeshFilter on selected object", EditorStyles.centeredGreyMiniLabel);
                }
            }
            else
            {
                // No single scene selection
                // Could be nothing selected
                // Could be multiple selection
                // Could be an asset in the project selected

                GUILayout.Space(10);
                GUILayout.Label("To start painting, select a single scene object");
                GUILayout.Label("The object must contain a MeshFilter");

                if (GUILayout.Button("Open quick start guide"))
                {
                    string projectPath = Application.dataPath.Replace("Assets", "");
                    string docsPdf     = projectPath + FindInstallPath() + "Technie Collider Creator Readme.pdf";
                    Application.OpenURL(docsPdf);
                }
            }
        }
コード例 #4
0
ファイル: SelectionUtil.cs プロジェクト: jalin0315/030
        public static HullPainterChild FindSelectedHullPainterChild()
        {
            // Works for components in the scene, causes NPEs for selected prefabs in the assets dir
            if (Selection.transforms.Length == 1)
            {
                GameObject currentSelection = Selection.transforms[0].gameObject;

                HullPainterChild painter = currentSelection.GetComponent <HullPainterChild>();
                if (painter != null)
                {
                    return(painter);
                }
            }
            return(null);
        }
コード例 #5
0
        private HullMapping FindMapping(HullPainterChild child)
        {
            if (hullMapping == null)
            {
                return(null);
            }

            foreach (HullMapping h in hullMapping)
            {
                if (h.targetChild == child)
                {
                    return(h);
                }
            }
            return(null);
        }
コード例 #6
0
        private bool IsMapped(HullPainterChild child)
        {
            if (hullMapping == null)
            {
                return(false);
            }

            foreach (HullMapping map in hullMapping)
            {
                if (map.targetChild == child)
                {
                    return(true);
                }
            }
            return(false);
        }
コード例 #7
0
        public Hull FindSourceHull(HullPainterChild child)
        {
            if (hullMapping == null)
            {
                // TODO: Hull mapping should be serialised, when it is remove this message as it'll only exist to catch un-upgraded assets
                //	Debug.LogError("No hull mapping present!");
                return(null);
            }

            foreach (HullMapping h in hullMapping)
            {
                if (h.targetChild == child)
                {
                    return(h.sourceHull);
                }
            }
            return(null);
        }
コード例 #8
0
        private void CreateCollider <T>(Hull sourceHull) where T : Collider
        {
            if (sourceHull.isChildCollider)
            {
                //	GameObject newChild = new GameObject(sourceHull.name);
                GameObject newChild = CreateGameObject(sourceHull.name);
                newChild.transform.SetParent(this.transform, false);
                newChild.transform.localPosition = Vector3.zero;
                newChild.transform.localRotation = Quaternion.identity;
                newChild.transform.localScale    = Vector3.one;

                HullPainterChild childPainter = AddComponent <HullPainterChild>(newChild);
                childPainter.parent = this;

                T col = AddComponent <T>(newChild);
                AddMapping(sourceHull, col, childPainter);
            }
            else
            {
                T col = AddComponent <T>(this.gameObject);
                AddMapping(sourceHull, col, null);
            }
        }
コード例 #9
0
        private void CreateHullMapping()
        {
            if (hullMapping == null)
            {
                //	hullMapping = new Dictionary<Hull, Collider>();
                hullMapping = new List <HullMapping>();
            }

            // Remove any invalid entries from the hull mapping
            //	null entries are garbage and can be dropped
            //	null source hull means the hull has been deleted and this mapping is no longer relevant
            //	missing *both* generated collider *and* target child means there's no data to point at, so might as well remove it and regen from scratch
            for (int i = hullMapping.Count - 1; i >= 0; i--)
            {
                HullMapping mapping = hullMapping[i];
                if (mapping == null ||
                    mapping.sourceHull == null ||
                    (mapping.generatedCollider == null && mapping.targetChild == null))
                {
                    hullMapping.RemoveAt(i);
                }
            }

            // Check to see if any existing mappings need updating (hull.type doesn't match Collider type, or child type no longer matches)

            foreach (Hull hull in paintingData.hulls)
            {
                if (IsMapped(hull))
                {
                    // We already have a mapping for this, but is it still of the correct type?

                    Collider value = FindExistingCollider(hullMapping, hull);

                    bool isHullOk   = (hull.type == HullType.ConvexHull && value is MeshCollider);
                    bool isBoxOk    = (hull.type == HullType.Box && value is BoxCollider);
                    bool isSphereOk = (hull.type == HullType.Sphere && value is SphereCollider);
                    bool isFaceOk   = (hull.type == HullType.Face && value is MeshCollider);

                    bool isColliderTypeOk = (isHullOk || isBoxOk || isSphereOk || isFaceOk);
                    bool isChildTypeOk    = value == null || ((hull.isChildCollider) == (value.transform.parent == this.transform));

                    if (isColliderTypeOk && isChildTypeOk)
                    {
                        // All good
                    }
                    else
                    {
                        // Mismatch - hull.type doesn't match collider type
                        // Delete the collider and remove the mapping
                        // This hull will then be orphaned, and a new collider added back in accordingly
                        DestroyImmediateWithUndo(value);
                        RemoveMapping(hull);
                    }
                }
            }

            // Connect orphans
            //
            // Find hulls without a Collider
            // Find Colliders without hulls
            // Try and map the two together

            // First find orphans - hull, colliders or childs that aren't already mapped

            List <Hull>             orphanedHulls     = new List <Hull>();
            List <Collider>         orphanedColliders = new List <Collider>();
            List <HullPainterChild> orphanedChilds    = new List <HullPainterChild>();

            foreach (Hull h in paintingData.hulls)
            {
                if (!IsMapped(h))
                {
                    orphanedHulls.Add(h);
                }
            }

            foreach (Collider c in FindLocal <Collider>())
            {
                if (!IsMapped(c))
                {
                    orphanedColliders.Add(c);
                }
            }

            foreach (HullPainterChild c in FindLocal <HullPainterChild>())
            {
                if (!IsMapped(c))
                {
                    orphanedChilds.Add(c);
                }
            }

            // Try and connect orphaned hulls with orphaned colliders

            for (int i = orphanedHulls.Count - 1; i >= 0; i--)
            {
                Hull h = orphanedHulls[i];

                for (int j = orphanedColliders.Count - 1; j >= 0; j--)
                {
                    Collider c = orphanedColliders[j];

                    // Find the HullPainterChild adjacent to the collider (if a child collider)
                    HullPainterChild child = null;
                    if (c.transform.parent == this.transform)
                    {
                        child = c.gameObject.GetComponent <HullPainterChild>();
                    }

                    // todo needs better handling
                    bool isMatchingChild = h.isChildCollider && c.transform.parent == this.transform;
                    if (isMatchingChild)
                    {
                        BoxCollider    boxCol    = c as BoxCollider;
                        SphereCollider sphereCol = c as SphereCollider;
                        MeshCollider   meshCol   = c as MeshCollider;

                        bool isMatchingBox        = h.type == HullType.Box && c is BoxCollider && Approximately(h.collisionBox.center, boxCol.center) && Approximately(h.collisionBox.size, boxCol.size);
                        bool isMatchingSphere     = h.type == HullType.Sphere && c is SphereCollider && h.collisionSphere != null && Approximately(h.collisionSphere.center, sphereCol.center) && Approximately(h.collisionSphere.radius, sphereCol.radius);
                        bool isMatchingConvexHull = h.type == HullType.ConvexHull && c is MeshCollider && meshCol.sharedMesh == h.collisionMesh;
                        bool isMatchingFace       = h.type == HullType.Face && c is MeshCollider && meshCol.sharedMesh == h.faceCollisionMesh;

                        if (isMatchingBox || isMatchingSphere || isMatchingConvexHull || isMatchingFace)
                        {
                            // Found a pair, so add a mapping and remove the orphans
                            AddMapping(h, c, child);

                            // These are no longer orphaned, so remove them from these lists
                            orphanedHulls.RemoveAt(i);
                            orphanedColliders.RemoveAt(j);

                            // Remove the no-longer orphaned child
                            for (int k = 0; k < orphanedChilds.Count; k++)
                            {
                                if (orphanedChilds[k] == child)
                                {
                                    orphanedChilds.RemoveAt(k);
                                    break;
                                }
                            }

                            break;
                        }
                    }
                }
            }


            // We've tried to connect hulls to existing colliders, now try and connect hulls to existing HullPainterChilds
            // These will be child without a collider (as otherwise they'd have be picked up earlier)
            for (int i = orphanedHulls.Count - 1; i >= 0; i--)
            {
                Hull h = orphanedHulls[i];

                if (!h.isChildCollider)
                {
                    continue;
                }

                for (int j = orphanedChilds.Count - 1; j >= 0; j--)
                {
                    HullPainterChild child   = orphanedChilds[j];
                    HullMapping      mapping = FindMapping(child);

                    if (mapping != null && mapping.sourceHull != null)
                    {
                        // Found a match for hull-mapping-child

                        // Ensure this still has a collider
                        if (mapping.generatedCollider == null)
                        {
                            // Recreate the collider of the correct type with the existing hull-mapping-child

                            RecreateChildCollider(mapping);
                        }

                        orphanedHulls.RemoveAt(i);
                        orphanedChilds.RemoveAt(j);
                        break;
                    }
                }
            }

            // Create colliders for any hull mapping children without colliders
            foreach (HullMapping mapping in hullMapping)
            {
                if (mapping.targetChild != null && mapping.generatedCollider == null)
                {
                    RecreateChildCollider(mapping);
                }
            }

            // Create child components for child colliders without them
            foreach (HullMapping mapping in hullMapping)
            {
                if (mapping.targetChild == null && mapping.generatedCollider != null && mapping.generatedCollider.transform.parent == this.transform)
                {
                    // Mapping has a child collider but no HullPainterChild
                    // Recreate the child component
                    HullPainterChild newChild = AddComponent <HullPainterChild>(mapping.generatedCollider.gameObject);
                    newChild.parent     = this;
                    mapping.targetChild = newChild;
                }
            }

            // Create colliders for any left over hulls

            foreach (Hull h in orphanedHulls)
            {
                if (h.type == HullType.Box)
                {
                    CreateCollider <BoxCollider>(h);
                }
                else if (h.type == HullType.Sphere)
                {
                    CreateCollider <SphereCollider>(h);
                }
                else if (h.type == HullType.ConvexHull)
                {
                    CreateCollider <MeshCollider>(h);
                }
                else if (h.type == HullType.Face)
                {
                    CreateCollider <MeshCollider>(h);
                }
            }

            // Delete any left over colliders
            // TODO: This probably isn't properly undo-aware

            foreach (Collider c in orphanedColliders)
            {
                if (c.gameObject == this.gameObject)
                {
                    DestroyImmediateWithUndo(c);
                }
                else
                {
                    // Child collider - delete collider, HullPainterChild (if any) and GameObject (if empty)

                    GameObject go = c.gameObject;
                    DestroyImmediateWithUndo(c);
                    DestroyImmediateWithUndo(go.GetComponent <HullPainterChild>());
                    if (IsDeletable(go))
                    {
                        DestroyImmediateWithUndo(go);
                    }
                }
            }

            // Delete any left over hull painter childs
            // TODO: This probably isn't undo-aware

            foreach (HullPainterChild child in orphanedChilds)
            {
                if (child == null)
                {
                    continue;
                }

                // Delete child, collider (if any) and GameObject (if empty)
                GameObject go = child.gameObject;
                DestroyImmediateWithUndo(child);
                DestroyImmediateWithUndo(go.GetComponent <Collider>());
                if (IsDeletable(go))
                {
                    DestroyImmediateWithUndo(go);
                }
            }

            // Sanity check - all hull mappings should have a collider of the right type now
            //	foreach (HullMapping mapping in hullMapping)
            //	{
            //		if (mapping.generatedCollider == null)
            //			Debug.LogWarning("Null collider for hull: " + mapping.sourceHull.name);
            //	}
        }