public override void OnReset(NavigationMesh navMesh)
        {
            if (!Application.isPlaying)
            {
                return;
            }

            is2D = true;
            ResetHoles(navMesh);

            if (navMesh != null && navMesh.characterEvasion != CharacterEvasion.None && navMesh.GetComponent <PolygonCollider2D>() != null)
            {
                PolygonCollider2D[] polys = navMesh.GetComponents <PolygonCollider2D>();

                if (polys != null && polys.Length > 1)
                {
                    ACDebug.LogWarning("Character evasion cannot occur for multiple PolygonColliders - only the first on the active NavMesh will be affected.");
                }

                for (int i = 0; i < polys.Length; i++)
                {
                    if (!polys[i].isTrigger)
                    {
                        ACDebug.LogWarning("The PolygonCollider2D on " + navMesh.gameObject.name + " is not a Trigger.");
                    }
                }
            }

            if (navMesh == null && KickStarter.settingsManager != null && KickStarter.settingsManager.movementMethod == MovementMethod.PointAndClick)
            {
                ACDebug.LogWarning("Could not initialise NavMesh - was one set as the Default in the Settings Manager?");
            }
        }
        public override void OnReset(NavigationMesh navMesh)
        {
            if (!Application.isPlaying)
            {
                return;
            }

            is2D = true;
            ResetHoles(navMesh);

            if (navMesh != null && navMesh.characterEvasion != CharacterEvasion.None && navMesh.GetComponent <PolygonCollider2D>() != null)
            {
                PolygonCollider2D[] polys = navMesh.GetComponents <PolygonCollider2D>();

                if (polys != null && polys.Length > 1)
                {
                    ACDebug.LogWarning("Character evasion cannot occur for multiple PolygonColliders - only the first on the active NavMesh will be affected.");
                }

                for (int i = 0; i < polys.Length; i++)
                {
                    if (!polys[i].isTrigger)
                    {
                        ACDebug.LogWarning("The PolygonCollider2D on " + navMesh.gameObject.name + " is not a Trigger.");
                    }
                }
            }
        }
        private void ResetHoles(NavigationMesh navMesh, bool rebuild)
        {
            if (navMesh == null)
            {
                return;
            }
            CalcSearchRadius(navMesh);

            PolygonCollider2D[] polys = navMesh.GetComponents <PolygonCollider2D>();
            if (polys == null || polys.Length == 0)
            {
                return;
            }

            for (int p = 0; p < polys.Length; p++)
            {
                polys[p].pathCount = 1;

                // Holes can only go in the first polygon
                if (p > 0 || navMesh.polygonColliderHoles.Count == 0)
                {
                    if (rebuild)
                    {
                        RebuildVertexArray(navMesh.transform, polys[p], p);
                        CreateCache(p);
                    }
                    continue;
                }

                Vector2 scaleFac = new Vector2(1f / navMesh.transform.localScale.x, 1f / navMesh.transform.localScale.y);
                foreach (PolygonCollider2D hole in navMesh.polygonColliderHoles)
                {
                    if (hole != null)
                    {
                        polys[p].pathCount++;

                        List <Vector2> newPoints = new List <Vector2>();
                        foreach (Vector2 holePoint in hole.points)
                        {
                            Vector2 relativePosition = hole.transform.TransformPoint(holePoint) - navMesh.transform.position;
                            newPoints.Add(new Vector2(relativePosition.x * scaleFac.x, relativePosition.y * scaleFac.y));
                        }

                        polys[p].SetPath(polys[p].pathCount - 1, newPoints.ToArray());
                        hole.gameObject.layer = LayerMask.NameToLayer(KickStarter.settingsManager.deactivatedLayer);
                        hole.isTrigger        = true;
                    }
                }

                if (rebuild)
                {
                    RebuildVertexArray(navMesh.transform, polys[p], p);
                    CreateCache(p);
                }
            }
        }
Beispiel #4
0
        public override NavigationMesh NavigationMeshGUI(NavigationMesh _target)
        {
            _target = base.NavigationMeshGUI(_target);

            _target.characterEvasion = (CharacterEvasion)CustomGUILayout.EnumPopup("Character evasion:", _target.characterEvasion, "", "The condition for which dynamic 2D pathfinding can occur by generating holes around characters");
            if (_target.characterEvasion != CharacterEvasion.None)
            {
                _target.characterEvasionPoints = (CharacterEvasionPoints)CustomGUILayout.EnumPopup("Evasion accuracy:", _target.characterEvasionPoints, "", "The number of vertices created around characters to evade");
                _target.characterEvasionYScale = CustomGUILayout.Slider("Evasion y-scale:", _target.characterEvasionYScale, 0.1f, 1f, "", "The scale of generated character evasion 'holes' in the NavMesh in the y-axis, relative to the x-axis");

                EditorGUILayout.HelpBox("Note: Characters can only be avoided if they have a Circle Collider 2D (no Trigger) component on their base.\n\n" +
                                        "For best results, set a non-zero 'Pathfinding update time' in the Settings Manager.", MessageType.Info);

                if (_target.transform.lossyScale != Vector3.one)
                {
                    EditorGUILayout.HelpBox("For character evasion to work, the NavMesh must have a unit scale (1,1,1).", MessageType.Warning);
                }

                                #if UNITY_ANDROID || UNITY_IOS
                EditorGUILayout.HelpBox("This is an expensive calculation - consider setting this to 'None' for mobile platforms.", MessageType.Warning);
                                #endif
            }

            _target.accuracy    = CustomGUILayout.Slider("Accuracy:", _target.accuracy, 0f, 1f, "", "A float that can be used as an accuracy parameter, should the algorithm require one");
            _target.gizmoColour = CustomGUILayout.ColorField("Gizmo colour:", _target.gizmoColour, "", "The colour of its Gizmo when used for 2D polygons");

            EditorGUILayout.Separator();
            GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(1));
            EditorGUILayout.LabelField("NavMesh holes", EditorStyles.boldLabel);

            for (int i = 0; i < _target.polygonColliderHoles.Count; i++)
            {
                EditorGUILayout.BeginHorizontal();
                _target.polygonColliderHoles [i] = (PolygonCollider2D)CustomGUILayout.ObjectField <PolygonCollider2D> ("Hole #" + i.ToString() + ":", _target.polygonColliderHoles [i], true, "", "A shape within the boundary of this PolygonCollider2D to create a hole from");

                if (GUILayout.Button("-", GUILayout.MaxWidth(20f)))
                {
                    _target.polygonColliderHoles.RemoveAt(i);
                    i = -1;
                    continue;
                }

                EditorGUILayout.EndHorizontal();

                if (_target.polygonColliderHoles[i] != null && _target.polygonColliderHoles[i].GetComponent <NavMeshBase>())
                {
                    EditorGUILayout.HelpBox("A NavMesh cannot use its own Polygon Collider component as a hole!", MessageType.Warning);
                }
            }

            if (GUILayout.Button("Create new hole"))
            {
                _target.polygonColliderHoles.Add(null);
            }

            if (_target.GetComponent <PolygonCollider2D>() != null)
            {
                int numPolys = _target.GetComponents <PolygonCollider2D>().Length;
                if (numPolys > 1)
                {
                    if (_target.polygonColliderHoles.Count > 0)
                    {
                        EditorGUILayout.HelpBox("Holes will only work if they are within the boundaries of " + _target.gameObject.name + "'s FIRST PolygonCollider component.", MessageType.Warning);
                    }
                    if (_target.characterEvasion != CharacterEvasion.None)
                    {
                        EditorGUILayout.HelpBox("Character-evasion will only work within the boundaries of " + _target.gameObject.name + "'s FIRST PolygonCollider component.", MessageType.Warning);
                    }
                }
            }

            return(_target);
        }
        public override NavigationMesh NavigationMeshGUI(NavigationMesh _target)
        {
            _target = base.NavigationMeshGUI(_target);

            _target.characterEvasion = (CharacterEvasion)EditorGUILayout.EnumPopup("Character evasion:", _target.characterEvasion);
            if (_target.characterEvasion != CharacterEvasion.None)
            {
                _target.characterEvasionPoints = (CharacterEvasionPoints)EditorGUILayout.EnumPopup("Evasion accuracy:", _target.characterEvasionPoints);
                _target.characterEvasionYScale = EditorGUILayout.Slider("Evasion y-scale:", _target.characterEvasionYScale, 0.1f, 1f);

                EditorGUILayout.HelpBox("Note: Characters can only be avoided if they have a Circle Collider 2D (no Trigger) component on their base.\n\n" +
                                        "For best results, set a non-zero 'Pathfinding update time' in the Settings Manager.", MessageType.Info);

                if (_target.transform.lossyScale != Vector3.one)
                {
                    EditorGUILayout.HelpBox("For character evasion to work, the NavMesh must have a unit scale (1,1,1).", MessageType.Warning);
                }

                                #if UNITY_ANDROID || UNITY_IOS
                EditorGUILayout.HelpBox("This is an expensive calculation - consider setting this to 'None' for mobile platforms.", MessageType.Warning);
                                #endif
            }

            _target.accuracy    = EditorGUILayout.Slider("Accuracy:", _target.accuracy, 0f, 1f);
            _target.gizmoColour = EditorGUILayout.ColorField("Gizmo colour:", _target.gizmoColour);

            EditorGUILayout.Separator();
            GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(1));
            EditorGUILayout.LabelField("NavMesh holes", EditorStyles.boldLabel);

            for (int i = 0; i < _target.polygonColliderHoles.Count; i++)
            {
                EditorGUILayout.BeginHorizontal();
                _target.polygonColliderHoles [i] = (PolygonCollider2D)EditorGUILayout.ObjectField("Hole #" + i.ToString() + ":", _target.polygonColliderHoles [i], typeof(PolygonCollider2D), true);

                if (GUILayout.Button("-", GUILayout.MaxWidth(20f)))
                {
                    _target.polygonColliderHoles.RemoveAt(i);
                    i = -1;
                }

                EditorGUILayout.EndHorizontal();

                if (_target.polygonColliderHoles[i] != null && _target.polygonColliderHoles[i].GetComponent <NavMeshBase>())
                {
                    EditorGUILayout.HelpBox("A NavMesh cannot use its own Polygon Collider component as a hole!", MessageType.Warning);
                }
            }

            if (GUILayout.Button("Create new hole"))
            {
                _target.polygonColliderHoles.Add(null);
            }

            if (_target.GetComponent <PolygonCollider2D>() != null)
            {
                int numPolys = _target.GetComponents <PolygonCollider2D>().Length;
                if (numPolys > 1)
                {
                    if (_target.polygonColliderHoles.Count > 0)
                    {
                        EditorGUILayout.HelpBox("Holes will only work if they are within the boundaries of " + _target.gameObject.name + "'s FIRST PolygonCollider component.", MessageType.Warning);
                    }
                    if (_target.characterEvasion != CharacterEvasion.None)
                    {
                        EditorGUILayout.HelpBox("Character-evasion will only work within the boundaries of " + _target.gameObject.name + "'s FIRST PolygonCollider component.", MessageType.Warning);
                    }
                }
            }

            return(_target);
        }
        public override NavigationMesh NavigationMeshGUI(NavigationMesh _target)
        {
            _target = base.NavigationMeshGUI(_target);

            _target.characterEvasion = (CharacterEvasion)EditorGUILayout.EnumPopup("Character evasion:", _target.characterEvasion);
            if (_target.characterEvasion != CharacterEvasion.None)
            {
                _target.characterEvasionPoints = (CharacterEvasionPoints)EditorGUILayout.EnumPopup("Evasion accuracy:", _target.characterEvasionPoints);
                _target.characterEvasionYScale = EditorGUILayout.Slider("Evasion y-scale:", _target.characterEvasionYScale, 0.1f, 1f);

                EditorGUILayout.HelpBox("Note: Characters can only be avoided if they have a Circle Collider 2D (no Trigger) component on their base.\n\n" +
                                        "For best results, set a non-zero 'Pathfinding update time' in the Settings Manager.", MessageType.Info);

                if (_target.transform.lossyScale != Vector3.one)
                {
                    EditorGUILayout.HelpBox("For character evasion to work, the NavMesh must have a unit scale (1,1,1).", MessageType.Warning);
                }

                                #if UNITY_ANDROID || UNITY_IOS
                EditorGUILayout.HelpBox("This is an expensive calculation - consider setting this to 'None' for mobile platforms.", MessageType.Warning);
                                #endif
            }

            _target.accuracy = EditorGUILayout.Slider("Accuracy:", _target.accuracy, 0f, 1f);

            int numOptions = _target.polygonColliderHoles.Count;
            numOptions = EditorGUILayout.IntField("Number of holes:", _target.polygonColliderHoles.Count);
            if (numOptions < 0)
            {
                numOptions = 0;
            }

            if (numOptions < _target.polygonColliderHoles.Count)
            {
                _target.polygonColliderHoles.RemoveRange(numOptions, _target.polygonColliderHoles.Count - numOptions);
            }
            else if (numOptions > _target.polygonColliderHoles.Count)
            {
                if (numOptions > _target.polygonColliderHoles.Capacity)
                {
                    _target.polygonColliderHoles.Capacity = numOptions;
                }
                for (int i = _target.polygonColliderHoles.Count; i < numOptions; i++)
                {
                    _target.polygonColliderHoles.Add(null);
                }
            }

            for (int i = 0; i < _target.polygonColliderHoles.Count; i++)
            {
                _target.polygonColliderHoles [i] = (PolygonCollider2D)EditorGUILayout.ObjectField("Hole #" + i.ToString() + ":", _target.polygonColliderHoles [i], typeof(PolygonCollider2D), true);
            }

            if (_target.GetComponent <PolygonCollider2D>() != null)
            {
                int numPolys = _target.GetComponents <PolygonCollider2D>().Length;
                if (numPolys > 1)
                {
                    if (numOptions > 0)
                    {
                        EditorGUILayout.HelpBox("Holes will only work if they are within the boundaries of " + _target.gameObject.name + "'s FIRST PolygonCollider component.", MessageType.Warning);
                    }
                    if (_target.characterEvasion != CharacterEvasion.None)
                    {
                        EditorGUILayout.HelpBox("Character-evasion will only work within the boundaries of " + _target.gameObject.name + "'s FIRST PolygonCollider component.", MessageType.Warning);
                    }
                }
            }

            return(_target);
        }