Skip to content

Commit

Permalink
Merge pull request #20 from deadlykam/features-v1-placing-limit
Browse files Browse the repository at this point in the history
Placement Limit Mode
  • Loading branch information
deadlykam authored Sep 9, 2021
2 parents 1da671b + 400ecf9 commit 159b16a
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ namespace KamranWali.SimpleInterface.Editor.Layouts
{
public abstract class BaseLayout
{
protected UnityAction repaint;
private Action _hideLayouts; // Layouts that should be hidden when the this layout is shown

/// <summary>
/// This method creates the BaseLayout object
/// </summary>
/// <param name="repaint">For repainting the GUI, of type UnityAction</param>
public BaseLayout(UnityAction repaint) => SetupOnEnable(repaint);
public BaseLayout(UnityAction repaint)
{
this.repaint = repaint;
SetupOnEnable();
}

/// <summary>
/// This method adds the hide method of the layout that should be hidden when the current layout is shown.
Expand Down Expand Up @@ -73,21 +78,30 @@ public abstract class BaseLayout
/// <summary>
/// This method initializes the layout's internal objects and MUST be called in OnEnable method.
/// </summary>
/// <param name="repaint">For repainting the GUI, of type UnityAction</param>
protected abstract void SetupOnEnable(UnityAction repaint);
protected abstract void SetupOnEnable();

#region Creation
protected bool ToggleLeft(string name, string toolTip, AnimBool toggle) => EditorGUILayout.ToggleLeft(new GUIContent(name, toolTip), toggle.target);
protected Transform TransformField(string name, string toolTip, Transform obj, bool isHierarchy) => EditorGUILayout.ObjectField(new GUIContent(name, toolTip), obj, typeof(Transform), isHierarchy) as Transform;
protected int LayerField(string name, string toolTip, LayerMask layerMask) => EditorGUILayout.LayerField(new GUIContent(name, toolTip), layerMask);
protected float FloatField(string name, string toolTip, float obj) => EditorGUILayout.FloatField(new GUIContent(name, toolTip), obj);
protected float FloatField(float obj) => EditorGUILayout.FloatField(obj);
protected int IntField(string name, string toolTip, int obj) => EditorGUILayout.IntField(new GUIContent(name, toolTip), obj);
protected int IntField(int obj) => EditorGUILayout.IntField(obj);
protected void LabelField(string name, string tooltip) => EditorGUILayout.LabelField(new GUIContent(name, tooltip));
protected void LabelField(string name, string tooltip, GUIStyle style) => EditorGUILayout.LabelField(new GUIContent(name, tooltip), style);
protected bool Button(string name, string tooltip) => GUILayout.Button(new GUIContent(name, tooltip));
#endregion

#region Layout
protected bool BeginFadeGroup(float value) => EditorGUILayout.BeginFadeGroup(value);
protected void EndFadeGroup() => EditorGUILayout.EndFadeGroup();
protected void BeginHorizontal() => GUILayout.BeginHorizontal();
protected void EndHorizontal() => GUILayout.EndHorizontal();
protected void BeginVertical() => GUILayout.BeginVertical();
protected void EndVertical() => GUILayout.EndVertical();
protected void Space(float space) => GUILayout.Space(space);
protected void LabelWidth(float width) => EditorGUIUtility.labelWidth = width;
#endregion

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public override Vector3 GetPosition(Vector3 position)
return position;
}

protected override void SetupOnEnable(UnityAction repaint)
protected override void SetupOnEnable()
{
_fixedPosGroup = new AnimBool(false);
_fixedPosGroup.valueChanged.AddListener(repaint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public override Quaternion GetRotation(Quaternion rotation) => rotation = Quater
IsToggleGroupShown(_fixedRotGroupY.faded) ? _fixedRotY : rotation.eulerAngles.y,
IsToggleGroupShown(_fixedRotGroupZ.faded) ? _fixedRotZ : rotation.eulerAngles.z);

protected override void SetupOnEnable(UnityAction repaint)
protected override void SetupOnEnable()
{
_fixedRotGroup = new AnimBool(false);
_fixedRotGroup.valueChanged.AddListener(repaint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public override void Update(Event currentEvent)

public override Vector3 GetScale(Vector3 scale) => _vectorOne * _fixedScale;

protected override void SetupOnEnable(UnityAction repaint)
protected override void SetupOnEnable()
{
_fixedScaleGroup = new AnimBool(false);
_fixedScaleGroup.valueChanged.AddListener(repaint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ public class PlacementLayout : BaseLayout
private Transform _root;
private LayerMask _layerMask;
private AnimBool _placeGroup;
private AnimBool _placeLimitGroup;
private int _maxPlace;
private RaycastHit _hit; // Storing ray hit
private Transform _prefabTemp; // For storing created prefabs
private Func<Vector3, Vector3> _getActualPosition;
private Func<Quaternion, Quaternion> _getActualRotation;
private Func<Vector3, Vector3> _getActualScale;
private int _curPlace;
private readonly int _defaultMinPlace; // The minimum default value for placement limit

/// <summary>
/// This constructor creates the PlacementLayout object.
Expand All @@ -30,6 +34,7 @@ public PlacementLayout(UnityAction repaint, Func<Vector3, Vector3> getActualPosi
_getActualPosition = getActualPosition;
_getActualRotation = getActualRotation;
_getActualScale = getActualScale;
_defaultMinPlace = 1; // Setting the default min placement limit value
}

public override bool IsShown() => _placeGroup.target;
Expand All @@ -39,24 +44,80 @@ public override void SetupOnGUI()
_placeGroup.target = ToggleLeft("Place Prefab (U)", "Toggle to place prefab. Hotkey = 'U'", _placeGroup);
if (BeginFadeGroup(_placeGroup.faded))
{
BeginHorizontal();
Space(20f);
_prefab = TransformField("Prefab", "The prefab to spawn", _prefab, false);
EndHorizontal();

BeginHorizontal();
Space(20f);
_root = TransformField("Root", "The root into which the prefab will be placed. Keeping null means default root will be used.", _root, true);
EndHorizontal();

BeginHorizontal();
Space(20f);
_layerMask = LayerField("Collidable Layer", "The layer on which the prefab will be placed.", _layerMask);
EndHorizontal();

// Limit group layout
BeginHorizontal();
Space(20f);
_placeLimitGroup.target = ToggleLeft("Limit Placement (B)", "Toggle to place a limited number of prefabs. Hotkey = 'B'", _placeLimitGroup);

if (BeginFadeGroup(_placeLimitGroup.faded))
{
// Max Place Int Field
BeginVertical();
Space(20f);
BeginHorizontal();
Space(-180f);
LabelWidth(30f);
_maxPlace = (_maxPlace = IntField("Max", "The total number of placement allowed", _maxPlace)) < _defaultMinPlace ? _defaultMinPlace : _maxPlace;
EndHorizontal();
EndVertical();

// Remain Label
BeginVertical();
BeginHorizontal();
Space(-180f);
LabelWidth(30f);
LabelField($"Placed: {_curPlace.ToString()}, Left: {(_maxPlace - _curPlace).ToString()}", "This shows the number of objects placed and left to place.", EditorStyles.boldLabel);
EndHorizontal();
EndVertical();

// Reset Button
BeginVertical();
BeginHorizontal();
Space(-180f);
LabelWidth(30f);
if (Button("Reset(N)", "Resets placed counter. Hotkey = 'N'")) ResetPlacementCounter();
EndHorizontal();
EndVertical();
}
EndFadeGroup();
EndHorizontal();
}
EndFadeGroup();
HideOtherLayouts(); // Hidding other layouts
}

public override void Update(Event currentEvent)
{
if (IsToggleGroupShown(_placeGroup.faded) && currentEvent.type == EventType.MouseDown && currentEvent.button == 0)
if (IsToggleGroupShown(_placeGroup.faded) && currentEvent.type == EventType.MouseDown && currentEvent.button == 0 && IsPlaceable())
{
if (Physics.Raycast(HandleUtility.GUIPointToWorldRay(currentEvent.mousePosition), out _hit, Mathf.Infinity, 1 << _layerMask)) // Hitting the correct layer
{
_prefabTemp = _root == null ? PrefabUtility.InstantiatePrefab(_prefab) as Transform : PrefabUtility.InstantiatePrefab(_prefab, _root) as Transform; // Creating the prefab
_prefabTemp.position = _getActualPosition(_hit.point); // Placing in hit position
_prefabTemp.rotation = _getActualRotation(_prefabTemp.rotation); // Rotating to the actual rotation
_prefabTemp.localScale = _getActualScale(_prefabTemp.localScale); // Setting the actual scale

if (_placeLimitGroup.target) // Condition to check if limit placement mode activated
{
_curPlace = (_curPlace + 1) > _maxPlace ? _maxPlace : _curPlace + 1;
repaint(); // Repainting to update the UI
}

Undo.RegisterCreatedObjectUndo(_prefabTemp.gameObject, "Prefab Placement");
}
}
Expand All @@ -66,14 +127,33 @@ public override void Update(Event currentEvent)
_placeGroup.target = !_placeGroup.target; // Toggling placement
HideOtherLayouts(); // Hidding other layouts
}
else if (currentEvent.keyCode == KeyCode.B && currentEvent.type == EventType.KeyDown) _placeLimitGroup.target = !_placeLimitGroup.target;
else if (currentEvent.keyCode == KeyCode.N && currentEvent.type == EventType.KeyDown && _placeLimitGroup.target)
{
ResetPlacementCounter();
repaint();
}
}

public override void Hide() { if (IsShown()) _placeGroup.target = false; }

protected override void SetupOnEnable(UnityAction repaint)
protected override void SetupOnEnable()
{
_placeGroup = new AnimBool(true);
_placeGroup.valueChanged.AddListener(repaint);
_placeLimitGroup = new AnimBool(false);
_placeLimitGroup.valueChanged.AddListener(repaint);
}

/// <summary>
/// This method checks if a prefab is placeable.
/// </summary>
/// <returns>True means placeable, false otherwise, of type bool</returns>
private bool IsPlaceable() => _placeLimitGroup.target ? _curPlace < _maxPlace : true;

/// <summary>
/// This method resets the placement counter.
/// </summary>
private void ResetPlacementCounter() => _curPlace = 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public override Quaternion GetRotation(Quaternion rotation) => rotation = Quater
IsToggleGroupShown(_rangeRotGroupY.faded) ? Random.Range(_rangeRotYMin, _rangeRotYMax) : rotation.eulerAngles.y,
IsToggleGroupShown(_rangeRotGroupZ.faded) ? Random.Range(_rangeRotZMin, _rangeRotZMax) : rotation.eulerAngles.z);

protected override void SetupOnEnable(UnityAction repaint)
protected override void SetupOnEnable()
{
_randomRotGroup = new AnimBool(false);
_randomRotGroup.valueChanged.AddListener(repaint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public override void Update(Event currentEvent)

public override Vector3 GetScale(Vector3 scale) => _vectorOne * Random.Range(_randomScaleMin, _randomScaleMax);

protected override void SetupOnEnable(UnityAction repaint)
protected override void SetupOnEnable()
{
_randomScaleGroup = new AnimBool(false);
_randomScaleGroup.valueChanged.AddListener(repaint);
Expand Down

0 comments on commit 159b16a

Please sign in to comment.