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); } } }
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); }