Files
BITFALL/Assets/Plugins/FImpossible Creations/Plugins - Level Design/PGG/Rules Logics/Utilities/Windows/PathSettingsWindow.cs
CortexCore ba342d6627 1
2023-11-30 00:23:23 +08:00

784 lines
34 KiB
C#

#if UNITY_EDITOR
using UnityEditor;
using FIMSpace.FEditor;
#endif
using System.Collections.Generic;
using UnityEngine;
using FIMSpace.Generating.Checker;
namespace FIMSpace.Generating
{
[System.Serializable]
public class Checker3DPathFindSetup
{
/// <summary> Helper to define if to use path find setup or to use default setup </summary>
public bool Activated = false;
public bool WorldSpace = false;
public bool UseLimits = false;
public Vector3 LimitMinValues = new Vector3(-1000, -1000, -1000);
public Vector3 LimitMaxValues = new Vector3(1000, 1000, 1000);
public int SearchStepsLimit = 650;
public int SeparateSelfYCells = 1;
/// <summary> x is above, y is below </summary>
public Vector2 SeparateCollisionY = Vector2.zero;
//public int AllowChangeDirectionEvery = 1;
public bool SphericalDistanceMeasuring = false;
public bool OnAnyContact = false;
public bool PrioritizePerpendicular = false;
public bool PrioritizeTargetYLevel = true;
public bool ForceStartPathOnSide = true;
//public bool AllowAlignJoin = false;
/// <summary> Realign Ending Cell</summary>
public bool TryEndCentered = false;
public bool SingleStepMode = false;
public bool AdjustEndingCell = false;
public bool ConnectEvenDiscarded = false;
public bool IgnoreSelfCollision = true;
public bool DiscardOnNoPathFound = true;
//public bool TryStartCentered = true;
public float SnapToInstructionsOnDistance = 0;
public bool LogWarnings = true;
public int DontAllowFinishId = -1;
public float DontAllowFinishDist = 0;
public bool DontAllowStartToo = false;
public bool DiscardIfAligning = false;
public float ExistingCellsCostMultiplier = 1f;
public float SelfCellsExtraSearchRange = 1f;
public CheckerField3D.EPathFindFocusLevel PathFindFocusLevel = CheckerField3D.EPathFindFocusLevel.Middle;
public enum EPathFindCategory { MainSettings, Handling, ExtraConditions }
public EPathFindCategory DrawCategory = EPathFindCategory.MainSettings;
public List<PathStep> Directions = new List<PathStep>();
[System.Serializable]
public struct PathStep
{
public Vector3Int StepDirection;
public float StepCost;
public int ForceChangeDirAfter;
public bool DisallowFinishOn;
public int AllowUseSinceStep;
public int DirectionContinuityRequirement;
public int DirectionOriginationRequirement;
public float ChangeDirectionCost;
public float KeepDirectionCost;
public string Name
{
get
{
string _tempName = "";
if (StepDirection.x > 0) _tempName += "Right";
if (StepDirection.y > 0) _tempName += "Up";
if (StepDirection.z > 0) _tempName += "Forw";
if (StepDirection.x < 0) _tempName += "Left";
if (StepDirection.y < 0) _tempName += "Down";
if (StepDirection.z < 0) _tempName += "Back";
return _tempName;
}
}
#if UNITY_EDITOR
static GUIContent _gui = null;
public PathStep(Vector3Int stepDir)
{
StepDirection = stepDir;
StepCost = 1;
ForceChangeDirAfter = 0;
DisallowFinishOn = false;
AllowUseSinceStep = 0;
DirectionContinuityRequirement = 0;
DirectionOriginationRequirement = 0;
ChangeDirectionCost = 0f;
KeepDirectionCost = 0f;
}
public PathStep Copy()
{
return (PathStep)MemberwiseClone();
}
public PathStep _Editor_GUI_Display(Checker3DPathFindSetup setup)
{
PathStep s = this;
if (_gui == null) _gui = new GUIContent();
s.StepDirection = EditorGUILayout.Vector3IntField("Step Direction:", StepDirection);
// TODO Support for few cells jump (create cells betweem - line)
if (s.StepDirection.x > 1) s.StepDirection.x = 1;
if (s.StepDirection.x < -1) s.StepDirection.x = -1;
if (s.StepDirection.y > 1) s.StepDirection.y = 1;
if (s.StepDirection.y < -1) s.StepDirection.y = -1;
if (s.StepDirection.z > 1) s.StepDirection.z = 1;
if (s.StepDirection.z < -1) s.StepDirection.z = -1;
float preCost = StepCost;
EditorGUIUtility.labelWidth = 100;
GUILayout.Space(6);
_gui.text = "Step Cost:"; _gui.tooltip = "Step cost is defining how worth is using selected path direction step";
s.StepCost = EditorGUILayout.FloatField(_gui, StepCost);
if (StepCost <= 0f) s.StepCost = preCost;
if (StepCost <= 0f) s.StepCost = 1f;
FGUI_Inspector.DrawUILineCommon();
EditorGUIUtility.labelWidth = 220;
_gui.text = "Force Change This Direction After:"; _gui.tooltip = "(dedicated for Y axis steps) Set zero to not use it!\nIt's disabling this direction step if it was used few times in a row.\nUseful for start-like paths - to prevent generating two/more path steps straight down.";
s.ForceChangeDirAfter = EditorGUILayout.IntField(_gui, ForceChangeDirAfter);
if (s.ForceChangeDirAfter < 0) s.ForceChangeDirAfter = 0;
GUILayout.Space(6);
_gui.text = "Require Direction Continuity:"; _gui.tooltip = "(dedicated for Y axis steps) Allow to use this direction again only after few steps facing towards the same direction. (useful when preventing creating side-to-side stairways)";
s.DirectionContinuityRequirement = EditorGUILayout.IntField(_gui, DirectionContinuityRequirement);
if (s.DirectionContinuityRequirement < 0) s.DirectionContinuityRequirement = 0;
GUILayout.Space(2);
_gui.text = "Require Direction Origination:"; _gui.tooltip = "(only for Y axis steps) Require using previous forward direction after using this direction. It can help supporting stairs generating Field Setup logics.";
s.DirectionOriginationRequirement = EditorGUILayout.Toggle(_gui, DirectionOriginationRequirement > 0) ? 1 : 0;
//s.DirectionOriginationRequirement = EditorGUILayout.IntField(_gui, DirectionOriginationRequirement);
//if (s.DirectionOriginationRequirement < 0) s.DirectionOriginationRequirement = 0;
//if (s.DirectionOriginationRequirement > 3) s.DirectionOriginationRequirement = 3;
FGUI_Inspector.DrawUILineCommon();
_gui.text = "Disallow Finish Using This Direction:"; _gui.tooltip = "You can don't let path end using this direction.\nIt can be helpful to prevent ending path on room floor when using multi-floor-level setups.";
s.DisallowFinishOn = EditorGUILayout.Toggle(_gui, DisallowFinishOn);
_gui.text = "Allow Use Since Path Step:"; _gui.tooltip = "Unlocking this direction when path already generated some steps.\nIt can be useful if you don't want to start path immedietely with stairs if doing multi-floor-level setups.";
s.AllowUseSinceStep = EditorGUILayout.IntField(_gui, AllowUseSinceStep);
if (s.AllowUseSinceStep < 0) s.AllowUseSinceStep = 0;
FGUI_Inspector.DrawUILineCommon();
EditorGUILayout.BeginHorizontal();
_gui.text = "Change Direction Cost:"; _gui.tooltip = "";
s.ChangeDirectionCost = EditorGUILayout.FloatField(_gui, s.ChangeDirectionCost);
if (GUILayout.Button(new GUIContent("A", "Apply this value to all steps"), GUILayout.Width(26)))
{
for (int i = 0; i < setup.Directions.Count; i++)
{
var d = setup.Directions[i];
d.ChangeDirectionCost = s.ChangeDirectionCost;
setup.Directions[i] = d;
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
_gui.text = "Keep Direction Cost:"; _gui.tooltip = "";
s.KeepDirectionCost = EditorGUILayout.FloatField(_gui, s.KeepDirectionCost);
if (GUILayout.Button(new GUIContent("A", "Apply this value to all steps"), GUILayout.Width(26)))
{
for (int i = 0; i < setup.Directions.Count; i++)
{
var d = setup.Directions[i];
d.KeepDirectionCost = s.KeepDirectionCost;
setup.Directions[i] = d;
}
}
EditorGUILayout.EndHorizontal();
EditorGUIUtility.labelWidth = 0;
return s;
}
#endif
}
int selected = -1;
#if UNITY_EDITOR
GUIContent _guiC = null;
public void _Editor_GUI_DrawPathFindSetup(Object toDirty)
{
if (_guiC == null) _guiC = new GUIContent();
EditorGUI.BeginChangeCheck();
Activated = true;
EditorGUIUtility.labelWidth = 210;
_guiC.text = "Search Step Count Safety Limit:"; _guiC.tooltip = "Path find algorithm iteration limit to prevent searching path towards target endlessly";
SearchStepsLimit = EditorGUILayout.IntField(_guiC, SearchStepsLimit);
FGUI_Inspector.DrawUILine(0.25f, 0.6f, 1, 10);
EditorGUILayout.BeginHorizontal();
GUI.backgroundColor = DrawCategory == EPathFindCategory.MainSettings ? Color.green : Color.white;
if (GUILayout.Button("Main Settings", EditorStyles.miniButtonLeft)) { DrawCategory = EPathFindCategory.MainSettings; }
GUI.backgroundColor = DrawCategory == EPathFindCategory.Handling ? Color.green : Color.white;
if (GUILayout.Button("Handling", EditorStyles.miniButtonMid)) { DrawCategory = EPathFindCategory.Handling; }
GUI.backgroundColor = DrawCategory == EPathFindCategory.ExtraConditions ? Color.green : Color.white;
if (GUILayout.Button("Extra", EditorStyles.miniButtonRight)) { DrawCategory = EPathFindCategory.ExtraConditions; }
GUI.backgroundColor = Color.white;
EditorGUILayout.EndHorizontal();
GUILayout.Space(5);
if (DrawCategory == EPathFindCategory.Handling)
{
GUILayout.Space(5);
EditorGUIUtility.labelWidth = 110;
UseLimits = EditorGUILayout.Toggle("Use Limits:", UseLimits);
if (UseLimits)
{
EditorGUI.indentLevel += 1;
GUILayout.Space(2);
WorldSpace = EditorGUILayout.Toggle("World Space:", WorldSpace);
GUILayout.Space(4);
EditorGUIUtility.labelWidth = 60;
EditorGUILayout.BeginHorizontal();
LimitMinValues.x = EditorGUILayout.FloatField("Min X:", LimitMinValues.x);
LimitMaxValues.x = EditorGUILayout.FloatField("Max X:", LimitMaxValues.x);
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
LimitMinValues.y = EditorGUILayout.FloatField("Min Y:", LimitMinValues.y);
LimitMaxValues.y = EditorGUILayout.FloatField("Max Y:", LimitMaxValues.y);
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
LimitMinValues.z = EditorGUILayout.FloatField("Min Z:", LimitMinValues.z);
LimitMaxValues.z = EditorGUILayout.FloatField("Max Z:", LimitMaxValues.z);
EditorGUILayout.EndHorizontal();
EditorGUIUtility.labelWidth = 0;
EditorGUI.indentLevel -= 1;
}
FGUI_Inspector.DrawUILineCommon(14, 1, 0.9f);
EditorGUILayout.BeginHorizontal();
EditorGUIUtility.labelWidth = 164;
_guiC.text = "Discard On No Path Found:"; _guiC.tooltip = "If no path has been found, no path shape will be forwarded.";
DiscardOnNoPathFound = EditorGUILayout.Toggle(_guiC, DiscardOnNoPathFound);
GUILayout.Space(4);
GUILayout.FlexibleSpace();
EditorGUIUtility.labelWidth = 144;
_guiC.text = "Connect If Discarded:"; _guiC.tooltip = "If there was found cell connected with target field but was discarded because of some light conditions (command max distance, side cells) still try generate path using discarded target position";
ConnectEvenDiscarded = EditorGUILayout.Toggle(_guiC, ConnectEvenDiscarded);
GUILayout.Space(4);
EditorGUILayout.EndHorizontal();
FGUI_Inspector.DrawUILineCommon(14, 1, 0.9f);
EditorGUIUtility.labelWidth = 164;
_guiC.text = "Separate Self Y Cells:"; _guiC.tooltip = "If you don't want to place cells too near each other in Y axis, increase this value. (it's self collision separation)";
SeparateSelfYCells = EditorGUILayout.IntField(_guiC, SeparateSelfYCells);
if (SeparateSelfYCells < 0) SeparateSelfYCells = 0;
GUILayout.Space(5);
EditorGUILayout.BeginHorizontal();
_guiC.text = "Height Collision Margins:"; _guiC.tooltip = "if you want to prevent generating path behind some cells but make some more spacing";
EditorGUILayout.LabelField(_guiC, GUILayout.Width(184));
EditorGUIUtility.labelWidth = 50;
SeparateCollisionY.x = EditorGUILayout.FloatField("Above:", SeparateCollisionY.x);
if (SeparateCollisionY.x < 0) SeparateCollisionY.x = 0;
GUILayout.Space(14);
SeparateCollisionY.y = EditorGUILayout.FloatField("Below:", SeparateCollisionY.y);
if (SeparateCollisionY.y < 0) SeparateCollisionY.y = 0;
EditorGUILayout.EndHorizontal();
GUILayout.Space(4);
}
else if (DrawCategory == EPathFindCategory.MainSettings)
{
EditorGUIUtility.labelWidth = 194;
EditorGUILayout.BeginHorizontal();
_guiC.text = "Start Path Inside Field Center:"; _guiC.tooltip = "Starting generating path inside the center on field or startinhon nearest side. (Enable if you want to generate path which starts in the ceiling instead of wall side)";
ForceStartPathOnSide = !EditorGUILayout.Toggle(_guiC, ForceStartPathOnSide);
GUILayout.Space(4);
GUILayout.FlexibleSpace();
EditorGUIUtility.labelWidth = 154;
_guiC.text = "Realign End Cell Centered:"; _guiC.tooltip = "(Calculated after finding path) Ensuring left/right side of the ending path cell is having neightbour cells";
TryEndCentered = EditorGUILayout.Toggle(_guiC, TryEndCentered);
GUILayout.Space(4);
EditorGUILayout.EndHorizontal();
//if (ForceStartPathOnSide == false) GUI.enabled = false;
//EditorGUIUtility.labelWidth = 284;
//_guiC.text = " ^ Allow Instant Path when Fields Are Aligning:"; _guiC.tooltip = "If fields are just next to each other, aligning with cells but not colliding, then generating path intantly out of two neightbour-aligning cells found.\nHelpful when generating connections between rectangle-packed rooms.";
//AllowAlignJoin = EditorGUILayout.Toggle(_guiC, AllowAlignJoin);
//GUILayout.Space(4);
//GUI.enabled = true;
EditorGUIUtility.labelWidth = 154;
_guiC.text = "Adjust Ending Cell:"; _guiC.tooltip = "(Calculated before finding path) Ensuring left/right side of the ending path cell is having neightbour cells";
AdjustEndingCell = EditorGUILayout.Toggle(_guiC, AdjustEndingCell);
GUILayout.Space(5);
EditorGUILayout.BeginHorizontal();
EditorGUIUtility.labelWidth = 194;
_guiC.text = "Ignore Self Collision:"; _guiC.tooltip = "Ignoring collision with start field and with already generated path cells.";
IgnoreSelfCollision = EditorGUILayout.Toggle(_guiC, IgnoreSelfCollision);
GUILayout.Space(4);
GUILayout.FlexibleSpace();
_guiC.text = "Single Step Mode:"; _guiC.tooltip = "Allow for just one step for pathfind. Dedicated for packed-aligned rectangles connection pathfind";
EditorGUIUtility.labelWidth = 154;
SingleStepMode = EditorGUILayout.Toggle(_guiC, SingleStepMode);
GUILayout.Space(4);
EditorGUILayout.EndHorizontal();
if (SingleStepMode)
{
EditorGUILayout.HelpBox("Using Single-Step-Mode which is dedicated for packed-aligned rectangles connection pathfind.", MessageType.None);
}
//_guiC.text = "Try Start Centered:"; _guiC.tooltip = "Finding most centered cell of the path origin grid's edge and starting path search from it";
//TryStartCentered = EditorGUILayout.Toggle(_guiC, TryStartCentered);
GUILayout.Space(5);
EditorGUILayout.BeginHorizontal();
EditorGUIUtility.labelWidth = 194;
_guiC.text = "Spherical Distance Measure:"; _guiC.tooltip = "Measuring distance to drive path finding using Rectangular distance (manhattan) or spherical (sqrt).";
SphericalDistanceMeasuring = EditorGUILayout.Toggle(_guiC, SphericalDistanceMeasuring);
GUILayout.FlexibleSpace();
EditorGUIUtility.labelWidth = 154;
_guiC.text = "Connect On Any Contact:"; _guiC.tooltip = "Skipping all basic rules and connecting to target field on first contact.";
OnAnyContact = EditorGUILayout.Toggle(_guiC, OnAnyContact);
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
//EditorGUIUtility.labelWidth = 160;
_guiC.text = "Prioritize Target Y Level:"; _guiC.tooltip = "Trying to reach target point's y axis value as soon as possible.\nUseful for multi-floor-level path generation.\nUse path steps 'Change Direction Cost' and 'Keep Direction Cost' values to customize path shape logic.";
PrioritizeTargetYLevel = EditorGUILayout.Toggle(_guiC, PrioritizeTargetYLevel);
GUILayout.FlexibleSpace();
EditorGUIUtility.labelWidth = 154;
_guiC.text = "Prioritize Perpendicular:"; _guiC.tooltip = "Trying to redirect path to start straightened and end with defined line towards target.";
PrioritizePerpendicular = EditorGUILayout.Toggle(_guiC, PrioritizePerpendicular);
EditorGUILayout.EndHorizontal();
EditorGUIUtility.labelWidth = 194;
GUILayout.Space(5);
_guiC.text = "Snap to instructions range:"; _guiC.tooltip = "Snapping start/end path point towards already generated cell instruction positions.";
SnapToInstructionsOnDistance = EditorGUILayout.FloatField(_guiC, SnapToInstructionsOnDistance);
GUILayout.Space(5);
LogWarnings = EditorGUILayout.Toggle("Log Warnings:", LogWarnings);
GUILayout.Space(5);
PathFindFocusLevel = (CheckerField3D.EPathFindFocusLevel)EditorGUILayout.EnumPopup(new GUIContent("Focus Level", "Cells level on which 'path start/path end' should find cells for connections"), PathFindFocusLevel);
GUILayout.Space(5);
//EditorGUIUtility.labelWidth = 180;
//_guiC.text = "Allow Change Direction Every:"; _guiC.tooltip = "You can set it higher if you want to prevent single-cell path direction changes (unless there is obstacle in a way)";
//AllowChangeDirectionEvery = EditorGUILayout.IntField(_guiC, AllowChangeDirectionEvery);
//if (AllowChangeDirectionEvery < 1) AllowChangeDirectionEvery = 1;
EditorGUIUtility.labelWidth = 0;
GUI.enabled = false;
EditorGUILayout.IntField("TODO: Spacing on sides", 0);
EditorGUILayout.IntField("TODO: Path Thickness", 0);
GUI.enabled = true;
}
else if (DrawCategory == EPathFindCategory.ExtraConditions)
{
GUILayout.Space(5);
EditorGUILayout.BeginHorizontal();
EditorGUIUtility.labelWidth = 230;
DontAllowFinishId = EditorGUILayout.IntField("Dont allow complete near to command:", DontAllowFinishId, GUILayout.Width(290));
GUILayout.Space(8);
EditorGUIUtility.labelWidth = 59;
DontAllowFinishDist = EditorGUILayout.FloatField("Distance", DontAllowFinishDist);
GUILayout.Space(4);
EditorGUILayout.EndHorizontal();
GUILayout.Space(2);
EditorGUIUtility.labelWidth = 230;
DontAllowStartToo = EditorGUILayout.Toggle("Try Same for start path position:", DontAllowStartToo);
GUILayout.Space(4);
if (DontAllowFinishId <= -1) DontAllowFinishId = -1;
if (DontAllowFinishDist <= 0)
{
DontAllowFinishDist = 0;
EditorGUILayout.HelpBox("Disallowing finishing path near to commands OFF", MessageType.None);
}
else
{
if (DontAllowFinishId <= -1)
{
EditorGUILayout.HelpBox("Disallowing finishing path near to ANY command in distance of " + DontAllowFinishDist + " cells", MessageType.None);
}
else
{
EditorGUILayout.HelpBox("Disallowing finishing path near to command of ID=" + DontAllowFinishId + " in distance of " + DontAllowFinishDist + " cells", MessageType.None);
}
}
FGUI_Inspector.DrawUILineCommon(14, 1, 0.9f);
GUILayout.Space(4);
_guiC.text = "Discard If Targets Aligning:"; _guiC.tooltip = "If fields are just next to each other it will discard path creations in favor custom handling connection";
DiscardIfAligning = EditorGUILayout.Toggle(_guiC, DiscardIfAligning);
GUILayout.Space(4);
ExistingCellsCostMultiplier = EditorGUILayout.FloatField(new GUIContent("Existing Cells Step Cost Multiplier:", "Its cost multiplier. When path search encounters cell which already belongs to the path (during extra search) then it can prioritize choosing this cell for path shape."), ExistingCellsCostMultiplier);
if (ExistingCellsCostMultiplier < 0f) ExistingCellsCostMultiplier = 0f;
//if ( ExistingCellsCostMultiplier != 1f)
//{
// EditorGUI.indentLevel++;
// SelfCellsExtraSearchRange = EditorGUILayout.FloatField("Self Cells Search Range:", SelfCellsExtraSearchRange);
// if (SelfCellsExtraSearchRange < 1f) SelfCellsExtraSearchRange = 1f;
// EditorGUI.indentLevel--;
//}
GUILayout.Space(4);
}
GUILayout.Space(8);
FGUI_Inspector.DrawUILine(0.25f, 0.6f, 1, 10);
GUILayout.Space(-6);
EditorGUILayout.BeginHorizontal(FGUI_Resources.ViewBoxStyle, GUILayout.Height(28));
EditorGUILayout.LabelField("Find Step Directions (" + Directions.Count + "):");
if (GUILayout.Button("+", GUILayout.Width(22))) { Directions.Add(new PathStep()); }
EditorGUILayout.EndHorizontal();
float lastViewWidth = EditorGUIUtility.currentViewWidth;
EditorGUILayout.BeginHorizontal();
float currentWdth = 6f;
GUIContent guiC = new GUIContent();
for (int i = 0; i < Directions.Count; i++)
{
guiC.text = "[" + i + "] " + Directions[i].Name;
Vector2 disp = EditorStyles.miniButton.CalcSize(guiC);
float nextWdth = currentWdth + disp.x;
if (nextWdth > lastViewWidth - 16f)
{
currentWdth = 6f;
nextWdth = currentWdth + disp.x;
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
}
currentWdth = nextWdth;
if (selected == i) GUI.backgroundColor = Color.green;
if (GUILayout.Button(guiC, GUILayout.Width(disp.x))) { if (selected == i) selected = -1; else selected = i; }
if (selected == i) GUI.backgroundColor = Color.white;
}
if (selected >= Directions.Count) selected = Directions.Count - 1;
EditorGUILayout.EndHorizontal();
FGUI_Inspector.DrawUILine(0.15f, 0.6f, 1, 10);
if (Directions.Count == 0)
{
EditorGUILayout.HelpBox("No directions setted - using default flat 2D search then", MessageType.None);
}
else
{
if (selected == -1)
{
EditorGUILayout.HelpBox("No Path-find step selected", MessageType.None);
}
else
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Settings for [" + selected + "] direction");
GUI.backgroundColor = new Color(1f, 0.6f, 0.6f, 1f);
if (GUILayout.Button(FGUI_Resources.GUIC_Remove, FGUI_Resources.ButtonStyle, GUILayout.Height(18), GUILayout.Width(23))) { Directions.RemoveAt(selected); selected -= 1; }
GUI.backgroundColor = Color.white;
EditorGUILayout.EndHorizontal();
GUILayout.Space(4);
if (Directions.Count > 0) Directions[selected] = Directions[selected]._Editor_GUI_Display(this);
}
}
EditorGUIUtility.labelWidth = 0;
GUILayout.Space(4);
GUILayout.FlexibleSpace();
if (Directions.Count < 4) EditorGUILayout.HelpBox("You should provide at least 4 directions for path find!\n(using default 3D search now)", MessageType.Warning);
FGUI_Inspector.DrawUILine(0.25f, 0.6f, 1, 4);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Presets:", GUILayout.Width(50));
if (GUILayout.Button("2D Flat")) { Preset_Apply2DFlat(); }
//if (GUILayout.Button("2D +Diag")) { Preset_Apply2DDiag(); }
if (GUILayout.Button("3D Dirs")) { Preset_Apply3D(false); }
if (GUILayout.Button("3D +Setup")) { Preset_Apply3D(true); }
EditorGUILayout.EndHorizontal();
GUILayout.Space(4);
if (EditorGUI.EndChangeCheck())
{
if (toDirty) EditorUtility.SetDirty(toDirty);
}
}
void Preset_Apply2DFlat()
{
Directions.Clear();
Directions.Add(new PathStep(new Vector3Int(1, 0, 0)));
Directions.Add(new PathStep(new Vector3Int(-1, 0, 0)));
Directions.Add(new PathStep(new Vector3Int(0, 0, 1)));
Directions.Add(new PathStep(new Vector3Int(0, 0, -1)));
}
void Preset_Apply3D(bool settings)
{
Directions.Clear();
Directions.Add(new PathStep(new Vector3Int(1, 0, 0)));
Directions.Add(new PathStep(new Vector3Int(-1, 0, 0)));
Directions.Add(new PathStep(new Vector3Int(0, 0, 1)));
Directions.Add(new PathStep(new Vector3Int(0, 0, -1)));
PathStep step = new PathStep(new Vector3Int(0, 1, 0));
step.ForceChangeDirAfter = 1;
step.DirectionContinuityRequirement = 1;
step.DirectionOriginationRequirement = 1;
step.DisallowFinishOn = true;
step.AllowUseSinceStep = 2;
Directions.Add(step);
step = step.Copy();
step.StepDirection = new Vector3Int(0, -1, 0);
Directions.Add(step);
if (settings)
{
ForceStartPathOnSide = true;
//TryStartCentered = true;
PrioritizeTargetYLevel = true;
SeparateSelfYCells = 1;
SeparateCollisionY = new Vector2(1, 0);
UseLimits = false;
}
}
#endif
public CheckerField3D.PathFindParams ToCheckerFieldPathFindParams()
{
CheckerField3D.PathFindParams pathParams;
if (!Activated || Directions.Count < 2)
{
pathParams = new CheckerField3D.PathFindParams();
pathParams.directions = CheckerField3D.GetDefaultDirections3D;
pathParams.NoLimits = true;
}
else
{
pathParams = new CheckerField3D.PathFindParams();
pathParams.directions = new List<CheckerField3D.LineFindHelper>();
for (int i = 0; i < Directions.Count; i++)
{
PathStep mDir = Directions[i];
CheckerField3D.LineFindHelper dir = new CheckerField3D.LineFindHelper(mDir.StepDirection, mDir.StepCost, mDir.ForceChangeDirAfter, mDir.DisallowFinishOn, mDir.AllowUseSinceStep, mDir.DirectionContinuityRequirement, mDir.DirectionOriginationRequirement);
dir.ChangeDirectionCost = mDir.ChangeDirectionCost;
dir.KeepDirectionCost = mDir.KeepDirectionCost;
pathParams.directions.Add(dir);
}
pathParams.NoLimits = !UseLimits;
if (UseLimits)
{
pathParams.LimitMinX = LimitMinValues.x;
pathParams.LimitMaxX = LimitMaxValues.x;
pathParams.LimitLowestY = LimitMinValues.y;
pathParams.LimitHighestY = LimitMaxValues.y;
pathParams.LimitMinZ = LimitMinValues.z;
pathParams.LimitMaxZ = LimitMaxValues.z;
}
}
pathParams.YLevelSeparation = SeparateSelfYCells;
pathParams.CollisionYMargins = SeparateCollisionY;
pathParams.WorldSpace = WorldSpace;
pathParams.IgnoreSelfCollision = IgnoreSelfCollision;
pathParams.DiscardOnNoPathFound = DiscardOnNoPathFound;
pathParams.SearchStepIterationLimit = SearchStepsLimit;
//pathParams.KeepDirectionFor = AllowChangeDirectionEvery;
pathParams.SphericalDistanceMeasure = SphericalDistanceMeasuring;
pathParams.FindFocusLevel = PathFindFocusLevel;
pathParams.ConnectOnAnyContact = OnAnyContact;
pathParams.PrioritizeTargetedYLevel = PrioritizeTargetYLevel;
pathParams.PrioritizePerpendicular = PrioritizePerpendicular;
pathParams.DontAllowFinishDist = DontAllowFinishDist;
pathParams.DontAllowFinishId = DontAllowFinishId;
pathParams.DontAllowStartToo = DontAllowStartToo;
pathParams.LogWarnings = LogWarnings;
pathParams.ConnectEvenDiscarded = ConnectEvenDiscarded;
pathParams.DiscardIfAligning = DiscardIfAligning;
pathParams.SnapToInstructionsOnDistance = SnapToInstructionsOnDistance;
pathParams.ExistingCellsCostMul = ExistingCellsCostMultiplier;
pathParams.ExistingCellsCheckRange = SelfCellsExtraSearchRange;
if (TryEndCentered)
{
pathParams.End_RequireCellsOnLeftSide = 1;
pathParams.End_RequireCellsOnRightSide = 1;
}
pathParams.TryEndCentered = AdjustEndingCell;
pathParams.SingleStepMode = SingleStepMode;
//pathParams.StartCentered = TryStartCentered;
pathParams.StartOnSide = ForceStartPathOnSide;
//pathParams.AllowNeightbourAlign = AllowAlignJoin;
return pathParams;
}
}
#if UNITY_EDITOR
public class PathSettingsWindow : EditorWindow
{
public static PathSettingsWindow Get;
public static bool OnChange = false;
public static bool GetChanged() { if (!OnChange) return false; OnChange = false; return true; }
static Checker3DPathFindSetup lastSetup = null;
static UnityEngine.Object ToDirty = null;
public static void Init(UnityEngine.Object toDirty, Checker3DPathFindSetup setup)
{
if (FGenerators.CheckIfIsNull(setup))
{
UnityEngine.Debug.Log("Null Setup Reference! ");
return;
}
ToDirty = toDirty;
lastSetup = setup;
PathSettingsWindow window = (PathSettingsWindow)GetWindow(typeof(PathSettingsWindow), true);
window.titleContent = new GUIContent(" Path-find Setup", PGGUtils.TEX_CellInstr);
window.Show();
window.minSize = new Vector2(300, 320);
Get = window;
}
private void OnEnable()
{
Get = this;
}
private void OnGUI()
{
if (lastSetup == null) { Close(); return; }
GUILayout.Space(6);
string spName = "";
EditorGUILayout.LabelField("Prepare Path-Find Setup" + spName, FGUI_Resources.HeaderStyle);
FGUI_Inspector.DrawUILine(0.25f, 0.6f, 2, 8);
if (lastSetup == null)
{
EditorGUILayout.HelpBox("No Data To Display", MessageType.Info);
return;
}
lastSetup._Editor_GUI_DrawPathFindSetup(ToDirty);
}
}
#endif
}