BITFALL/Assets/GSpawn - Level Designer/Scripts/Prefabs/ModularWallPrefabProfile.cs

1393 lines
62 KiB
C#
Raw Normal View History

2024-01-27 04:09:57 +08:00
#if UNITY_EDITOR
//#define MODULAR_WALL_PREFAB_PROFILE_NO_DUPLICATE_PREFABS
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;
namespace GSpawn
{
public enum ModularWallRuleId
{
StraightWall = 0,
InnerCorner,
OuterCorner,
}
public enum ModularWallAxis
{
X = 0,
Y,
Z
}
public static class ModularWallRuleIdEx
{
private static int _numRuleIds;
private static ModularWallRuleId[] _ruleIdArray;
static ModularWallRuleIdEx()
{
var allIds = Enum.GetValues(typeof(ModularWallRuleId));
_numRuleIds = allIds.Length;
_ruleIdArray = new ModularWallRuleId[_numRuleIds];
foreach (var item in allIds)
{
var ruleId = (ModularWallRuleId)item;
_ruleIdArray[(int)ruleId] = ruleId;
}
}
public static int numRuleIds { get { return _numRuleIds; } }
public static ModularWallRuleId[] ruleIdArray { get { return _ruleIdArray; } }
}
[Serializable]
public class ModularWallProperties
{
[SerializeField]
public ModularWallAxis upAxis = ModularWallAxis.Y;
[SerializeField]
public ModularWallAxis forwardAxis = ModularWallAxis.Z;
[SerializeField]
public bool invertForwardAxis = false;
[SerializeField]
public ModularWallAxis innerAxis = ModularWallAxis.X;
[SerializeField]
public bool invertInnerAxis = false;
[SerializeField]
public float height = 0.0f;
[SerializeField]
public float forwardSize = 0.0f;
}
[Serializable]
public class ModularWallRelativeTransform
{
[SerializeField]
public Vector3 position;
[SerializeField]
public Quaternion rotation;
public void reset()
{
position = Vector3.zero;
rotation = Quaternion.identity;
}
}
public class ModularWallPrefabProfile : Profile
{
private static string _innerCornerName = "innercorner";
private static string _outerCornerName = "outercorner";
private static string _middleStraightName = "middlestraight";
private static string _firstStraightName = "firststraight";
private static string _lastStraightName = "laststraight";
private static string _pillarInnerCornerBeginName = "pillarinnercornerbegin";
private static string _pillarOuterCornerBeginName = "pillaroutercornerbegin";
private static string _pillarInnerCornerEndName = "pillarinnercornerend";
private static string _pillarOuterCornerEndName = "pillaroutercornerend";
private static string _pillarInnerCornerMiddleName = "pillarinnercornermiddle";
private static string _pillarOuterCornerMiddleName = "pillaroutercornermiddle";
[SerializeField]
private GameObject _examplePrefab = null;
[SerializeField]
private GameObject _ep_InnerCorner = null;
[SerializeField]
private GameObject _ep_OuterCorner = null;
[SerializeField]
private GameObject _ep_MidStraight = null;
[SerializeField]
private GameObject _ep_FirstStraight = null;
[SerializeField]
private GameObject _ep_LastStraight = null;
[SerializeField]
private GameObject _ep_PillarInnerCornerBegin = null;
[SerializeField]
private GameObject _ep_PillarInnerCornerEnd = null;
[SerializeField]
private GameObject _ep_PillarOuterCornerBegin = null;
[SerializeField]
private GameObject _ep_PillarOuterCornerEnd = null;
[SerializeField]
private GameObject _ep_PillarInnerCornerMiddle = null;
[SerializeField]
private GameObject _ep_PillarOuterCornerMiddle = null;
[SerializeField]
private ModularWallProperties _wallProperties = new ModularWallProperties();
[SerializeField]
private bool _truncateForwardSize = false;
[SerializeField]
private bool _spawnPillars = false;
[SerializeField]
private string _pillarProfileName = RandomPrefabProfileDb.defaultProfileName;
[SerializeField]
private ModularWallRelativeTransform _innerCornerRT = new ModularWallRelativeTransform();
[SerializeField]
private ModularWallRelativeTransform _outerCornerRT = new ModularWallRelativeTransform();
[SerializeField]
private ModularWallRelativeTransform _straightRT = new ModularWallRelativeTransform();
[SerializeField]
private ModularWallRelativeTransform _pillarMidStraightBeginRT = new ModularWallRelativeTransform();
[SerializeField]
private ModularWallRelativeTransform _pillarMidStraightEndRT = new ModularWallRelativeTransform();
[SerializeField]
private ModularWallRelativeTransform _pillarInnerCornerBeginRT = new ModularWallRelativeTransform();
[SerializeField]
private ModularWallRelativeTransform _pillarInnerCornerEndRT = new ModularWallRelativeTransform();
[SerializeField]
private ModularWallRelativeTransform _pillarOuterCornerBeginRT = new ModularWallRelativeTransform();
[SerializeField]
private ModularWallRelativeTransform _pillarOuterCornerEndRT = new ModularWallRelativeTransform();
[SerializeField]
private ModularWallRelativeTransform _pillarInnerCornerMiddleRT = new ModularWallRelativeTransform();
[SerializeField]
private ModularWallRelativeTransform _pillarOuterCornerMiddleRT = new ModularWallRelativeTransform();
[SerializeField]
private float _straight_ForwardPushDistance_Inner;
[SerializeField]
private float _straight_InnerPushDistance_Inner;
[SerializeField]
private float _straight_ForwardPushDistance_Outer;
[SerializeField]
private float _straight_InnerPushDistance_Outer;
[NonSerialized]
private ObjectBounds.QueryConfig _wallBoundsQConfig = new ObjectBounds.QueryConfig();
[NonSerialized]
private ObjectBounds.QueryConfig _pillarBoundsQConfig = new ObjectBounds.QueryConfig();
private SerializedObject _serializedObject;
[SerializeField]
private List<ModularWallPrefab> _straightWallPrefabs = new List<ModularWallPrefab>();
[SerializeField]
private List<ModularWallPrefab> _innerCornerPrefabs = new List<ModularWallPrefab>();
[SerializeField]
private List<ModularWallPrefab> _outerCornerPrefabs = new List<ModularWallPrefab>();
[NonSerialized]
private List<ModularWallPrefab>[] _prefabListArray = new List<ModularWallPrefab>[Enum.GetValues(typeof(ModularWallRuleId)).Length];
[NonSerialized]
private CumulativeProbabilityTable<ModularWallPrefab> _straightWallTable = new CumulativeProbabilityTable<ModularWallPrefab>();
[NonSerialized]
private CumulativeProbabilityTable<ModularWallPrefab> _innerCornerTable = new CumulativeProbabilityTable<ModularWallPrefab>();
[NonSerialized]
private CumulativeProbabilityTable<ModularWallPrefab> _outerCornerTable = new CumulativeProbabilityTable<ModularWallPrefab>();
[NonSerialized]
private CumulativeProbabilityTable<ModularWallPrefab>[] _tableArray = new CumulativeProbabilityTable<ModularWallPrefab>[Enum.GetValues(typeof(ModularWallRuleId)).Length];
[NonSerialized]
private List<ModularWallPrefab> _mdWallPrefabBuffer = new List<ModularWallPrefab>();
[NonSerialized]
private List<GameObject> _objectBuffer = new List<GameObject>();
public GameObject examplePrefab
{
get { return _examplePrefab; }
set
{
if (value != null && !validateExamplePrefab(value)) return;
UndoEx.record(this);
_examplePrefab = value;
onExamplePrefabChanged();
EditorUtility.SetDirty(this);
}
}
public bool hasInnerOuterCorners { get { return _ep_InnerCorner != null && _ep_OuterCorner != null; } }
public bool hasPillars
{
get
{
return (hasInnerCornerPillarBegin || hasOuterCornerPillarBegin ||
hasInnerCornerPillarEnd || hasOuterCornerPillarEnd ||
hasInnerCornerPillarMiddle || hasOuterCornerPillarMiddle)
&& pillarProfile.getNumUsedPrefabs() != 0;
}
}
public bool hasInnerCornerPillarBegin { get { return _ep_PillarInnerCornerBegin != null; } }
public bool hasOuterCornerPillarBegin { get { return _ep_PillarOuterCornerBegin != null; } }
public bool hasInnerCornerPillarEnd { get { return _ep_PillarInnerCornerEnd != null; } }
public bool hasOuterCornerPillarEnd { get { return _ep_PillarOuterCornerEnd != null; } }
public bool hasInnerCornerPillarMiddle { get { return _ep_PillarInnerCornerMiddle != null; } }
public bool hasOuterCornerPillarMiddle { get { return _ep_PillarOuterCornerMiddle != null; } }
public ModularWallRelativeTransform innerCornerRT { get { return _innerCornerRT; } }
public ModularWallRelativeTransform outerCornerRT { get { return _outerCornerRT; } }
public ModularWallRelativeTransform straightRT { get { return _straightRT; } }
public ModularWallRelativeTransform pillarMidStraightBeginRT { get { return _pillarMidStraightBeginRT; } }
public ModularWallRelativeTransform pillarMidStraightEndRT { get { return _pillarMidStraightEndRT; } }
public ModularWallRelativeTransform pillarInnerCornerBeginRT { get { return _pillarInnerCornerBeginRT; } }
public ModularWallRelativeTransform pillarOuterCornerBeginRT { get { return _pillarOuterCornerBeginRT; } }
public ModularWallRelativeTransform pillarInnerCornerEndRT { get { return _pillarInnerCornerEndRT; } }
public ModularWallRelativeTransform pillarOuterCornerEndRT { get { return _pillarOuterCornerEndRT; } }
public ModularWallRelativeTransform pillarInnerCornerMiddleRT { get { return _pillarInnerCornerMiddleRT; } }
public ModularWallRelativeTransform pillarOuterCornerMiddleRT { get { return _pillarOuterCornerMiddleRT; } }
public float straight_ForwardPushDistance_Inner { get { return _straight_ForwardPushDistance_Inner; } }
public float straight_InnerPushDistance_Inner { get { return _straight_InnerPushDistance_Inner; } }
public float straight_ForwardPushDistance_Outer { get { return _straight_ForwardPushDistance_Outer; } }
public float straight_InnerPushDistance_Outer { get { return _straight_InnerPushDistance_Outer; } }
public ModularWallAxis wallUpAxis
{
get { return _wallProperties.upAxis; }
set
{
if (value == wallForwardAxis) return;
UndoEx.record(this);
_wallProperties.upAxis = value;
updateWallProperties();
updateRelationships();
EditorUtility.SetDirty(this);
}
}
public ModularWallAxis wallForwardAxis { get { return _wallProperties.forwardAxis; } }
public bool invertFowardAxis { get { return _wallProperties.invertForwardAxis; } }
public ModularWallAxis wallInnerAxis { get { return _wallProperties.innerAxis; } }
public float wallHeight { get { return _wallProperties.height; } }
public float wallForwardSize { get { return _wallProperties.forwardSize; } }
public bool truncateForwardSize
{
get { return _truncateForwardSize; }
set
{
if (value == _truncateForwardSize) return;
UndoEx.record(this);
_truncateForwardSize = value;
updateWallProperties();
updateRelationships();
EditorUtility.SetDirty(this);
}
}
public bool spawnPillars { get { return _spawnPillars; } set { UndoEx.record(this); _spawnPillars = value; EditorUtility.SetDirty(this); } }
public string pillarProfileName
{
get { return _pillarProfileName; }
set
{
UndoEx.record(this);
_pillarProfileName = value;
if (string.IsNullOrEmpty(_pillarProfileName)) _pillarProfileName = RandomPrefabProfileDb.defaultProfileName;
EditorUtility.SetDirty(this);
}
}
public RandomPrefabProfile pillarProfile
{
get
{
var profile = RandomPrefabProfileDb.instance.findProfile(_pillarProfileName);
if (profile == null) profile = RandomPrefabProfileDb.instance.defaultProfile;
return profile;
}
}
public int numPrefabs
{
get
{
int num = 0;
foreach (var prefabList in _prefabListArray)
num += prefabList.Count;
return num;
}
}
public SerializedObject serializedObject
{
get
{
if (_serializedObject == null) _serializedObject = new SerializedObject(this);
return _serializedObject;
}
}
public static string pillarInnerCornerMiddleName_LowerCase { get { return _pillarInnerCornerMiddleName; } }
public static string pillarOuterCornerMiddleName_LowerCase { get { return _pillarOuterCornerMiddleName; } }
public void refreshPrefabData()
{
if (_examplePrefab != null && !validateExamplePrefab(_examplePrefab)) return;
onExamplePrefabChanged();
}
public bool isAnyPrefabUsed(ModularWallRuleId ruleId)
{
return isAnyPrefabUsed(_prefabListArray[(int)ruleId]);
}
public Vector3 getModularWallUpAxis(GameObject gameObject)
{
return gameObject.transform.modularWallToLocalAxis(wallUpAxis, false);
}
public Vector3 getModularWallForwardAxis(GameObject gameObject)
{
return gameObject.transform.modularWallToLocalAxis(wallForwardAxis, _wallProperties.invertForwardAxis);
}
public Vector3 getModularWallInnerAxis(GameObject gameObject)
{
return gameObject.transform.modularWallToLocalAxis(wallInnerAxis, _wallProperties.invertInnerAxis);
}
public AxisDescriptor getModularWallUpAxisDesc(GameObject gameObject)
{
return gameObject.transform.modularWallToLocalAxisDesc(wallUpAxis, false);
}
public AxisDescriptor getModularWallForwardAxisDesc(GameObject gameObject)
{
return gameObject.transform.modularWallToLocalAxisDesc(wallForwardAxis, _wallProperties.invertForwardAxis);
}
public ModularWallPrefab getPrefab(ModularWallRuleId ruleId, int prefabIndex)
{
var prefabList = _prefabListArray[(int)ruleId];
return prefabList[prefabIndex];
}
public ModularWallPrefab getFirstUsedPrefab(ModularWallRuleId ruleId)
{
var prefabList = _prefabListArray[(int)ruleId];
foreach (var prefab in prefabList)
{
if (prefab.used) return prefab;
}
return null;
}
public ModularWallPrefab getBestPrefabForSpawnGuide()
{
float minVolume = float.MaxValue;
ModularWallPrefab bestPrefab = null;
var prefabList = _prefabListArray[(int)ModularWallRuleId.StraightWall];
foreach (var prefab in prefabList)
{
if (!prefab.used) continue;
if (bestPrefab == null)
{
bestPrefab = prefab;
minVolume = calcStraightWallOBB(bestPrefab.prefabAsset).volume;
}
else
{
float v = calcStraightWallOBB(prefab.prefabAsset).volume;
if (v < minVolume)
{
bestPrefab = prefab;
minVolume = v;
}
}
}
return bestPrefab != null ? bestPrefab : getFirstUsedPrefab(ModularWallRuleId.StraightWall);
}
public void onPrefabsSpawnChanceChanged()
{
refreshAllPrefabTables();
}
public void onPrefabsUsedStateChanged()
{
refreshAllPrefabTables();
}
public void onPrefabsUseDefaults()
{
refreshAllPrefabTables();
}
public OBB calcStraightWallOBB(GameObject wallObject)
{
OBB obb = ObjectBounds.calcHierarchyWorldOBB(wallObject, _wallBoundsQConfig);
Vector3 obbSize = obb.size;
obbSize[(int)_wallProperties.forwardAxis] = _wallProperties.forwardSize;
obbSize[(int)_wallProperties.upAxis] = _wallProperties.height;
obb.size = obbSize;
return obb;
}
public OBB calcPillarOBB(GameObject pillarObject)
{
OBB obb = ObjectBounds.calcHierarchyWorldOBB(pillarObject, _pillarBoundsQConfig);
return obb;
}
public ObjectBounds.QueryConfig getWallBoundsQConfig()
{
return _wallBoundsQConfig;
}
public ModularWallPrefab pickPrefab(ModularWallRuleId ruleId)
{
var table = _tableArray[(int)ruleId];
return table.pickEntity();
}
public void resetPrefabPreviews()
{
foreach (var prefabList in _prefabListArray)
{
int numPrefabs = prefabList.Count;
PluginProgressDialog.begin("Refreshing Prefab Previews");
for (int prefabIndex = 0; prefabIndex < numPrefabs; ++prefabIndex)
{
var prefab = prefabList[prefabIndex];
PluginProgressDialog.updateItemProgress(prefab.prefabAsset.name, (prefabIndex + 1) / (float)numPrefabs);
prefab.resetPreview();
}
PluginProgressDialog.end();
}
}
public void regeneratePrefabPreviews()
{
foreach (var prefabList in _prefabListArray)
{
int numPrefabs = prefabList.Count;
PluginProgressDialog.begin("Regenerating Prefab Previews");
for (int prefabIndex = 0; prefabIndex < numPrefabs; ++prefabIndex)
{
var prefab = prefabList[prefabIndex];
PluginProgressDialog.updateItemProgress(prefab.prefabAsset.name, (prefabIndex + 1) / (float)numPrefabs);
prefab.regeneratePreview();
}
PluginProgressDialog.end();
}
}
public void onPrefabAssetWillBeDeleted(GameObject prefabAsset)
{
if (prefabAsset == _examplePrefab)
{
clearExamplePrefabs();
foreach (var prefabList in _prefabListArray)
{
foreach (var mdWallPrefab in prefabList)
{
AssetDbEx.removeObjectFromAsset(mdWallPrefab, this);
DestroyImmediate(mdWallPrefab);
}
prefabList.Clear();
}
Debug.LogWarning("ModularWallPrefabProfile: Example prefab asset has been destroyed. All wall prefabs have been removed.");
return;
}
foreach (var prefabList in _prefabListArray)
{
var prefabsToRemove = prefabList.FindAll(item => item.prefabAsset == prefabAsset);
foreach (var mdWallPrefab in prefabsToRemove)
{
prefabList.Remove(mdWallPrefab);
AssetDbEx.removeObjectFromAsset(mdWallPrefab, this);
DestroyImmediate(mdWallPrefab);
}
}
refreshAllPrefabTables();
updateWallProperties();
}
public ModularWallPrefab createPrefab(PluginPrefab pluginPrefab, ModularWallRuleId ruleId)
{
if (_examplePrefab == null)
{
Debug.LogError("ModularWallPrefabProfile: Missing example prefab.");
return null;
}
#if MODULAR_WALL_PREFAB_PROFILE_NO_DUPLICATE_PREFABS
if (!containsPrefab(pluginPrefab))
#endif
{
UndoEx.saveEnabledState();
UndoEx.enabled = false;
UndoEx.record(this);
var mdWallPrefab = UndoEx.createScriptableObject<ModularWallPrefab>();
mdWallPrefab.pluginPrefab = pluginPrefab;
mdWallPrefab.name = mdWallPrefab.pluginPrefab.prefabAsset.name;
_prefabListArray[(int)ruleId].Add(mdWallPrefab);
AssetDbEx.addObjectToAsset(mdWallPrefab, this);
EditorUtility.SetDirty(this);
refreshPrefabTable(_tableArray[(int)ruleId], _prefabListArray[(int)ruleId]);
UndoEx.restoreEnabledState();
UndoEx.record(this);
return mdWallPrefab;
}
#if MODULAR_WALL_PREFAB_PROFILE_NO_DUPLICATE_PREFABS
return null;
#endif
}
public void createPrefabs(List<PluginPrefab> pluginPrefabs, ModularWallRuleId ruleId, List<ModularWallPrefab> createdPrefabs, bool appendCreated, string progressTitle)
{
_mdWallPrefabBuffer.Clear();
if (_examplePrefab == null)
{
Debug.LogError("ModularWallPrefabProfile: Missing example prefab.");
return;
}
PluginProgressDialog.begin(progressTitle);
if (!appendCreated) createdPrefabs.Clear();
UndoEx.saveEnabledState();
UndoEx.enabled = false;
for (int prefabIndex = 0; prefabIndex < pluginPrefabs.Count; ++prefabIndex)
{
var pluginPrefab = pluginPrefabs[prefabIndex];
PluginProgressDialog.updateItemProgress(pluginPrefab.prefabAsset.name, (prefabIndex + 1) / (float)pluginPrefabs.Count);
#if MODULAR_WALL_PREFAB_PROFILE_NO_DUPLICATE_PREFABS
if (!containsPrefab(pluginPrefab))
#endif
{
var mdWallPrefab = UndoEx.createScriptableObject<ModularWallPrefab>();
mdWallPrefab.pluginPrefab = pluginPrefab;
mdWallPrefab.name = mdWallPrefab.pluginPrefab.prefabAsset.name;
AssetDbEx.addObjectToAsset(mdWallPrefab, this);
createdPrefabs.Add(mdWallPrefab);
_mdWallPrefabBuffer.Add(mdWallPrefab);
}
}
UndoEx.record(this);
var prefabList = _prefabListArray[(int)ruleId];
foreach (var mdWallPrefab in _mdWallPrefabBuffer)
prefabList.Add(mdWallPrefab);
EditorUtility.SetDirty(this);
refreshPrefabTable(_tableArray[(int)ruleId], prefabList);
PluginProgressDialog.end();
UndoEx.restoreEnabledState();
UndoEx.record(this);
}
public void deletePrefab(ModularWallPrefab prefab)
{
if (prefab != null)
{
int numRules = _prefabListArray.Length;
for (int i = 0; i < numRules; ++i)
{
var prefabList = _prefabListArray[i];
if (prefabList.Contains(prefab))
{
UndoEx.record(this);
prefabList.Remove(prefab);
UndoEx.destroyObjectImmediate(prefab);
EditorUtility.SetDirty(this);
refreshPrefabTable(_tableArray[i], prefabList);
break;
}
}
}
}
public void deletePrefabs(List<ModularWallPrefab> prefabs)
{
if (prefabs.Count != 0)
{
UndoEx.record(this);
_mdWallPrefabBuffer.Clear();
int numRules = _prefabListArray.Length;
for (int i = 0; i < numRules; ++i)
{
var prefabList = _prefabListArray[i];
foreach (var mdWallPrefab in prefabs)
{
if (prefabList.Contains(mdWallPrefab))
{
prefabList.Remove(mdWallPrefab);
_mdWallPrefabBuffer.Add(mdWallPrefab);
}
}
}
foreach (var prefab in _mdWallPrefabBuffer)
UndoEx.destroyObjectImmediate(prefab);
EditorUtility.SetDirty(this);
refreshAllPrefabTables();
}
}
public void deletePrefabs(List<PluginPrefab> pluginPrefabs)
{
if (pluginPrefabs.Count != 0)
{
UndoEx.record(this);
_mdWallPrefabBuffer.Clear();
int numRules = _prefabListArray.Length;
for (int i = 0; i < numRules; ++i)
{
var prefabList = _prefabListArray[i];
foreach (var pluginPrefab in pluginPrefabs)
{
for (int mdPrefabIndex = 0; mdPrefabIndex < prefabList.Count;)
{
var mdPrefab = prefabList[mdPrefabIndex];
if (pluginPrefabs.Contains(mdPrefab.pluginPrefab))
{
prefabList.RemoveAt(mdPrefabIndex);
_mdWallPrefabBuffer.Add(mdPrefab);
}
else ++mdPrefabIndex;
}
}
}
foreach (var prefab in _mdWallPrefabBuffer)
UndoEx.destroyObjectImmediate(prefab);
EditorUtility.SetDirty(this);
refreshAllPrefabTables();
}
}
public void deleteAllPrefabs()
{
if (numPrefabs != 0)
{
UndoEx.record(this);
_mdWallPrefabBuffer.Clear();
foreach (var prefabList in _prefabListArray)
{
_mdWallPrefabBuffer.AddRange(prefabList);
prefabList.Clear();
}
foreach (var prefab in _mdWallPrefabBuffer)
UndoEx.destroyObjectImmediate(prefab);
EditorUtility.SetDirty(this);
refreshAllPrefabTables();
}
}
public bool containsPrefab(ModularWallPrefab prefab)
{
foreach (var prefabList in _prefabListArray)
{
if (prefabList.Contains(prefab)) return true;
}
return false;
}
public bool containsWallPiecePrefabAsset(GameObject prefabAsset)
{
foreach (var prefabList in _prefabListArray)
{
foreach (var prefab in prefabList)
{
if (prefab.prefabAsset == prefabAsset) return true;
}
}
return false;
}
public bool containsPillarPrefabAsset(GameObject prefabAsset)
{
var prefabProfile = pillarProfile;
return prefabProfile.containsPrefabAsset(prefabAsset);
}
public void getPrefabs(ModularWallRuleId ruleId, List<ModularWallPrefab> prefabs)
{
prefabs.Clear();
prefabs.AddRange(_prefabListArray[(int)ruleId]);
}
private bool isAnyPrefabUsed(List<ModularWallPrefab> prefabs)
{
foreach (var prefab in prefabs)
{
if (prefab.used) return true;
}
return false;
}
private void refreshAllPrefabTables()
{
int numTables = _tableArray.Length;
for (int i = 0; i < numTables; ++i)
refreshPrefabTable(_tableArray[i], _prefabListArray[i]);
}
private void refreshPrefabTable(CumulativeProbabilityTable<ModularWallPrefab> prefabTable, List<ModularWallPrefab> prefabs)
{
prefabTable.clear();
foreach (var prefab in prefabs)
{
if (prefab.used) prefabTable.addEntity(prefab, prefab.spawnChance);
}
prefabTable.refresh();
}
private void initializeTableArray()
{
_tableArray[(int)ModularWallRuleId.StraightWall] = _straightWallTable;
_tableArray[(int)ModularWallRuleId.InnerCorner] = _innerCornerTable;
_tableArray[(int)ModularWallRuleId.OuterCorner] = _outerCornerTable;
}
private void initializeRulePrefabListArray()
{
_prefabListArray[(int)ModularWallRuleId.StraightWall] = _straightWallPrefabs;
_prefabListArray[(int)ModularWallRuleId.InnerCorner] = _innerCornerPrefabs;
_prefabListArray[(int)ModularWallRuleId.OuterCorner] = _outerCornerPrefabs;
}
private void onExamplePrefabChanged()
{
clearExamplePrefabs();
if (_examplePrefab != null)
{
_examplePrefab.getAllChildren(false, false, _objectBuffer);
foreach (var child in _objectBuffer)
{
string childName = child.name.ToLower();
if (childName == _innerCornerName) _ep_InnerCorner = child;
else if (childName == _outerCornerName) _ep_OuterCorner = child;
else if (childName == _middleStraightName) _ep_MidStraight = child;
else if (childName == _firstStraightName) _ep_FirstStraight = child;
else if (childName == _lastStraightName) _ep_LastStraight = child;
else if (childName == _pillarInnerCornerBeginName) _ep_PillarInnerCornerBegin = child;
else if (childName == _pillarOuterCornerBeginName) _ep_PillarOuterCornerBegin = child;
else if (childName == _pillarInnerCornerEndName) _ep_PillarInnerCornerEnd = child;
else if (childName == _pillarOuterCornerEndName) _ep_PillarOuterCornerEnd = child;
else if (childName == _pillarInnerCornerMiddleName) _ep_PillarInnerCornerMiddle = child;
else if (childName == _pillarOuterCornerMiddleName) _ep_PillarOuterCornerMiddle = child;
}
}
updateWallProperties();
updateRelationships();
}
private GameObject getWallPieceByName(string name, List<GameObject> wallPieces)
{
string lowerName = name.ToLower();
foreach (var child in wallPieces)
{
string childName = child.name.ToLower();
if (childName == lowerName) return child;
}
return null;
}
private bool isWallPiecePillar(GameObject wallPiece)
{
string name = wallPiece.name.ToLower();
return name == _pillarInnerCornerBeginName || name == _pillarInnerCornerEndName ||
name == _pillarOuterCornerBeginName || name == _pillarOuterCornerEndName ||
name == _pillarInnerCornerMiddleName || name == _pillarOuterCornerMiddleName;
}
private bool isWallPieceStraight(GameObject wallPiece)
{
string name = wallPiece.name.ToLower();
return name == _middleStraightName || name == _firstStraightName ||
name == _lastStraightName;
}
private void clearExamplePrefabs()
{
_ep_InnerCorner = null;
_ep_OuterCorner = null;
_ep_MidStraight = null;
_ep_FirstStraight = null;
_ep_LastStraight = null;
_ep_PillarInnerCornerBegin = null;
_ep_PillarInnerCornerEnd = null;
_ep_PillarOuterCornerBegin = null;
_ep_PillarOuterCornerEnd = null;
_ep_PillarInnerCornerMiddle = null;
_ep_PillarOuterCornerMiddle = null;
}
private bool validateExamplePrefab(GameObject examplePrefab)
{
if (examplePrefab.isSceneObject())
{
Debug.LogError("ModularWallPrefabProfile: Scene objects are not allowed.");
return false;
}
bool foundInnerChild = false;
bool foundOuterChild = false;
bool foundMiddleStraightChild = false;
bool foundFirstStraightChild = false;
bool foundLastStraightChild = false;
examplePrefab.getAllChildren(false, false, _objectBuffer);
foreach (var child in _objectBuffer)
{
string childName = child.name.ToLower();
if (!foundInnerChild)
{
if (childName == _innerCornerName)
{
foundInnerChild = true;
if (!child.hierarchyHasMesh(false, false))
{
showHierarchyNoMeshMessage(child.name);
return false;
}
continue;
}
}
if (!foundOuterChild)
{
if (childName == _outerCornerName)
{
foundOuterChild = true;
if (!child.hierarchyHasMesh(false, false))
{
showHierarchyNoMeshMessage(child.name);
return false;
}
continue;
}
}
if (!foundMiddleStraightChild)
{
if (childName == _middleStraightName)
{
foundMiddleStraightChild = true;
if (!child.hierarchyHasMesh(false, false))
{
showHierarchyNoMeshMessage(child.name);
return false;
}
// Note: Must have 0 rotation along all axes.
Vector3 rotation = child.transform.rotation.eulerAngles;
if (rotation != Vector3.zero)
{
Debug.LogError("ModularWallPrefabProfile: Middle Straight piece requires 0 rotation around all axes.");
return false;
}
continue;
}
}
if (!foundFirstStraightChild)
{
if (childName == _firstStraightName)
{
foundFirstStraightChild = true;
if (!child.hierarchyHasMesh(false, false))
{
showHierarchyNoMeshMessage(child.name);
return false;
}
continue;
}
}
if (!foundLastStraightChild)
{
if (childName == _lastStraightName)
{
foundLastStraightChild = true;
if (!child.hierarchyHasMesh(false, false))
{
showHierarchyNoMeshMessage(child.name);
return false;
}
continue;
}
}
}
if (!foundMiddleStraightChild)
{
Debug.LogError("ModularWallPrefabProfile: Middle Straight piece is missing from example prefab.");
return false;
}
if (!foundFirstStraightChild)
{
Debug.LogError("ModularWallPrefabProfile: First Straight piece is missing from example prefab.");
return false;
}
if (!foundLastStraightChild)
{
Debug.LogError("ModularWallPrefabProfile: Last Straight piece is missing from example prefab.");
return false;
}
return true;
}
private void showHierarchyNoMeshMessage(string hierarchyName)
{
Debug.LogError("ModularWallPrefabProfile: Invalid hierarchy '" + hierarchyName + "'. The hierarchy doesn't contain a mesh.");
}
private void updateRelationships()
{
if (_examplePrefab == null)
{
_innerCornerRT.reset();
_outerCornerRT.reset();
_straightRT.reset();
_pillarMidStraightBeginRT.reset();
_pillarMidStraightEndRT.reset();
_pillarInnerCornerBeginRT.reset();
_pillarInnerCornerEndRT.reset();
_pillarOuterCornerBeginRT.reset();
_pillarOuterCornerEndRT.reset();
_pillarInnerCornerMiddleRT.reset();
_pillarOuterCornerMiddleRT.reset();
_straight_ForwardPushDistance_Inner = 0.0f;
_straight_InnerPushDistance_Inner = 0.0f;
_straight_ForwardPushDistance_Outer = 0.0f;
_straight_InnerPushDistance_Outer = 0.0f;
return;
}
OBB midStraightOBB = calcStraightWallOBB(_ep_MidStraight);
Quaternion inverseRotation = Quaternion.Inverse(midStraightOBB.rotation);
_straightRT.position = inverseRotation * (_ep_MidStraight.transform.position - midStraightOBB.center);
_straightRT.rotation = inverseRotation * _ep_MidStraight.transform.rotation;
if (hasInnerOuterCorners)
{
calcInnerCornerRelationships();
calcOuterCornerRelationships();
}
if (hasPillars) calcPillarRelationships();
Vector3 middleStraightFwAxis = getModularWallForwardAxis(_ep_MidStraight);
OBB lastStraightOBB = calcStraightWallOBB(_ep_LastStraight);
_straight_ForwardPushDistance_Inner = Vector3Ex.absDot((lastStraightOBB.center - midStraightOBB.center), middleStraightFwAxis);
_straight_ForwardPushDistance_Inner -= _wallProperties.forwardSize;
_straight_ForwardPushDistance_Inner = MathEx.roundCorrectError(_straight_ForwardPushDistance_Inner, 1e-5f);
Vector3 pushAxis = -getModularWallInnerAxis(_ep_MidStraight);
Vector3 pushedCenter = lastStraightOBB.center + pushAxis * _wallProperties.forwardSize;
_straight_InnerPushDistance_Inner = Vector3Ex.absDot((pushedCenter - midStraightOBB.center), pushAxis);
_straight_InnerPushDistance_Inner = MathEx.roundCorrectError(_straight_InnerPushDistance_Inner, 1e-5f);
OBB firstStraightOBB = calcStraightWallOBB(_ep_FirstStraight);
_straight_ForwardPushDistance_Outer = Vector3Ex.absDot((firstStraightOBB.center - midStraightOBB.center), middleStraightFwAxis);
_straight_ForwardPushDistance_Outer -= _wallProperties.forwardSize;
_straight_ForwardPushDistance_Outer = MathEx.roundCorrectError(_straight_ForwardPushDistance_Outer, 1e-5f);
pushAxis = getModularWallInnerAxis(_ep_MidStraight);
pushedCenter = firstStraightOBB.center + pushAxis * _wallProperties.forwardSize;
_straight_InnerPushDistance_Outer = Vector3Ex.absDot((pushedCenter - midStraightOBB.center), pushAxis);
_straight_InnerPushDistance_Outer = MathEx.roundCorrectError(_straight_InnerPushDistance_Outer, 1e-5f);
}
private void calcInnerCornerRelationships()
{
OBB lastStraightOBB = calcStraightWallOBB(_ep_LastStraight);
Vector3 lastFWAxis = getModularWallForwardAxis(_ep_LastStraight);
OBB midStraightOBB = calcStraightWallOBB(_ep_MidStraight);
Vector3 midFWAxis = getModularWallForwardAxis(_ep_MidStraight);
// Note: Average inner axes (forward axes transposed).
Vector3 avgAxis = (lastFWAxis - midFWAxis).normalized;
lastStraightOBB.center -= lastFWAxis * _wallProperties.forwardSize;
midStraightOBB.center += midFWAxis * _wallProperties.forwardSize;
Vector3 avgCenter = (lastStraightOBB.center + midStraightOBB.center) / 2.0f;
Quaternion inverseRotation = Quaternion.Inverse(Quaternion.LookRotation(avgAxis, getModularWallUpAxis(_ep_MidStraight)));
_innerCornerRT.position = inverseRotation * (_ep_InnerCorner.transform.position - avgCenter);
_innerCornerRT.rotation = inverseRotation * _ep_InnerCorner.transform.rotation;
}
private void calcOuterCornerRelationships()
{
OBB firstStraightOBB = calcStraightWallOBB(_ep_FirstStraight);
Vector3 firstFWAxis = getModularWallForwardAxis(_ep_FirstStraight);
OBB midStraightOBB = calcStraightWallOBB(_ep_MidStraight);
Vector3 midFWAxis = getModularWallForwardAxis(_ep_MidStraight);
// Note: Average inner axes (forward axes transposed).
Vector3 avgAxis = (firstFWAxis - midFWAxis).normalized;
firstStraightOBB.center += firstFWAxis * _wallProperties.forwardSize;
midStraightOBB.center -= midFWAxis * _wallProperties.forwardSize;
Vector3 avgCenter = (firstStraightOBB.center + midStraightOBB.center) / 2.0f;
Quaternion inverseRotation = Quaternion.Inverse(Quaternion.LookRotation(avgAxis, getModularWallUpAxis(_ep_MidStraight)));
_outerCornerRT.position = inverseRotation * (_ep_OuterCorner.transform.position - avgCenter);
_outerCornerRT.rotation = inverseRotation * _ep_OuterCorner.transform.rotation;
}
private void calcPillarRelationships()
{
if (_ep_PillarInnerCornerBegin != null)
{
Quaternion inverseRotation = Quaternion.Inverse(_ep_MidStraight.transform.rotation);
_pillarMidStraightEndRT.position = inverseRotation * (_ep_PillarInnerCornerBegin.transform.position - _ep_MidStraight.transform.position);
_pillarMidStraightEndRT.rotation = inverseRotation * _ep_PillarInnerCornerBegin.transform.rotation;
}
else _pillarMidStraightEndRT.reset();
if (_ep_PillarOuterCornerEnd != null)
{
Quaternion inverseRotation = Quaternion.Inverse(_ep_MidStraight.transform.rotation);
_pillarMidStraightBeginRT.position = inverseRotation * (_ep_PillarOuterCornerEnd.transform.position - _ep_MidStraight.transform.position);
_pillarMidStraightBeginRT.rotation = inverseRotation * _ep_PillarOuterCornerEnd.transform.rotation;
}
else _pillarMidStraightBeginRT.reset();
if (_ep_PillarInnerCornerBegin != null)
{
if (_ep_InnerCorner != null)
{
Quaternion inverseRotation = Quaternion.Inverse(_ep_InnerCorner.transform.rotation);
_pillarInnerCornerBeginRT.position = inverseRotation * (_ep_PillarInnerCornerBegin.transform.position - _ep_InnerCorner.transform.position);
_pillarInnerCornerBeginRT.rotation = inverseRotation * _ep_PillarInnerCornerBegin.transform.rotation;
}
else
{
// When no inner corner prefab is available, calculate the transform relative to the first imaginary corner part.
GameObject firstPart, secondPart;
getImaginaryInnerCornerParts(out firstPart, out secondPart);
Quaternion inverseRotation = Quaternion.Inverse(firstPart.transform.rotation);
_pillarInnerCornerBeginRT.position = inverseRotation * (_ep_PillarInnerCornerBegin.transform.position - calcStraightWallOBB(firstPart).center);
_pillarInnerCornerBeginRT.rotation = inverseRotation * _ep_PillarInnerCornerBegin.transform.rotation;
}
}
else _pillarInnerCornerBeginRT.reset();
if (_ep_PillarInnerCornerEnd != null)
{
if (_ep_InnerCorner != null)
{
Quaternion inverseRotation = Quaternion.Inverse(_ep_InnerCorner.transform.rotation);
_pillarInnerCornerEndRT.position = inverseRotation * (_ep_PillarInnerCornerEnd.transform.position - _ep_InnerCorner.transform.position);
_pillarInnerCornerEndRT.rotation = inverseRotation * _ep_PillarInnerCornerEnd.transform.rotation;
}
else
{
// When no inner corner prefab is available, calculate the transform relative to the second imaginary corner part.
GameObject firstPart, secondPart;
getImaginaryInnerCornerParts(out firstPart, out secondPart);
Quaternion inverseRotation = Quaternion.Inverse(secondPart.transform.rotation);
_pillarInnerCornerEndRT.position = inverseRotation * (_ep_PillarInnerCornerEnd.transform.position - calcStraightWallOBB(secondPart).center);
_pillarInnerCornerEndRT.rotation = inverseRotation * _ep_PillarInnerCornerEnd.transform.rotation;
}
}
else _pillarInnerCornerEndRT.reset();
if (_ep_PillarOuterCornerBegin != null)
{
if (_ep_OuterCorner != null)
{
Quaternion inverseRotation = Quaternion.Inverse(_ep_OuterCorner.transform.rotation);
_pillarOuterCornerBeginRT.position = inverseRotation * (_ep_PillarOuterCornerBegin.transform.position - _ep_OuterCorner.transform.position);
_pillarOuterCornerBeginRT.rotation = inverseRotation * _ep_PillarOuterCornerBegin.transform.rotation;
}
else
{
GameObject firstPart, secondPart;
getImaginaryOuterCornerParts(out firstPart, out secondPart);
Quaternion inverseRotation = Quaternion.Inverse(firstPart.transform.rotation);
_pillarOuterCornerBeginRT.position = inverseRotation * (_ep_PillarOuterCornerBegin.transform.position - calcStraightWallOBB(firstPart).center);
_pillarOuterCornerBeginRT.rotation = inverseRotation * _ep_PillarOuterCornerBegin.transform.rotation;
}
}
else _pillarOuterCornerBeginRT.reset();
if (_ep_PillarOuterCornerEnd != null)
{
if (_ep_OuterCorner != null)
{
Quaternion inverseRotation = Quaternion.Inverse(_ep_OuterCorner.transform.rotation);
_pillarOuterCornerEndRT.position = inverseRotation * (_ep_PillarOuterCornerEnd.transform.position - _ep_OuterCorner.transform.position);
_pillarOuterCornerEndRT.rotation = inverseRotation * _ep_PillarOuterCornerEnd.transform.rotation;
}
else
{
GameObject firstPart, secondPart;
getImaginaryOuterCornerParts(out firstPart, out secondPart);
Quaternion inverseRotation = Quaternion.Inverse(secondPart.transform.rotation);
_pillarOuterCornerEndRT.position = inverseRotation * (_ep_PillarOuterCornerEnd.transform.position - calcStraightWallOBB(secondPart).center);
_pillarOuterCornerEndRT.rotation = inverseRotation * _ep_PillarOuterCornerEnd.transform.rotation;
}
}
else _pillarOuterCornerEndRT.reset();
if (_ep_PillarInnerCornerMiddle != null)
{
if (_ep_InnerCorner != null)
{
Quaternion inverseRotation = Quaternion.Inverse(_ep_InnerCorner.transform.rotation);
_pillarInnerCornerMiddleRT.position = inverseRotation * (_ep_PillarInnerCornerMiddle.transform.position - _ep_InnerCorner.transform.position);
_pillarInnerCornerMiddleRT.rotation = inverseRotation * _ep_PillarInnerCornerMiddle.transform.rotation;
}
else
{
GameObject firstPart, secondPart;
getImaginaryInnerCornerParts(out firstPart, out secondPart);
OBB lastStraightOBB = calcStraightWallOBB(_ep_LastStraight);
OBB middleStraightOBB = calcStraightWallOBB(_ep_MidStraight);
OBB firstPartOBB = calcStraightWallOBB(firstPart);
OBB secondPartOBB = calcStraightWallOBB(secondPart);
Vector3 parentPosition = (firstPartOBB.center + secondPartOBB.center) * 0.5f;
Vector3 look = (lastStraightOBB.center - secondPartOBB.center).normalized;
Vector3 right = (middleStraightOBB.center - firstPartOBB.center).normalized;
Vector3 up = Vector3.Cross(look, right).normalized;
Quaternion inverseRotation = Quaternion.Inverse(Quaternion.LookRotation(look, up));
_pillarInnerCornerMiddleRT.position = inverseRotation * (_ep_PillarInnerCornerMiddle.transform.position - parentPosition);
_pillarInnerCornerMiddleRT.rotation = inverseRotation * _ep_PillarInnerCornerMiddle.transform.rotation;
}
}
else _pillarInnerCornerMiddleRT.reset();
if (_ep_PillarOuterCornerMiddle != null)
{
if (_ep_OuterCorner != null)
{
Quaternion inverseRotation = Quaternion.Inverse(_ep_OuterCorner.transform.rotation);
_pillarOuterCornerMiddleRT.position = inverseRotation * (_ep_PillarOuterCornerMiddle.transform.position - _ep_OuterCorner.transform.position);
_pillarOuterCornerMiddleRT.rotation = inverseRotation * _ep_PillarOuterCornerMiddle.transform.rotation;
}
else
{
GameObject firstPart, secondPart;
getImaginaryOuterCornerParts(out firstPart, out secondPart);
OBB firstStraightOBB = calcStraightWallOBB(_ep_FirstStraight);
OBB middleStraightOBB = calcStraightWallOBB(_ep_MidStraight);
OBB firstPartOBB = calcStraightWallOBB(firstPart);
OBB secondPartOBB = calcStraightWallOBB(secondPart);
Vector3 parentPosition = (firstPartOBB.center + secondPartOBB.center) * 0.5f;
Vector3 look = (firstStraightOBB.center - firstPartOBB.center).normalized;
Vector3 right = (middleStraightOBB.center - secondPartOBB.center).normalized;
Vector3 up = Vector3.Cross(look, right).normalized;
Quaternion inverseRotation = Quaternion.Inverse(Quaternion.LookRotation(look, up));
_pillarOuterCornerMiddleRT.position = inverseRotation * (_ep_PillarOuterCornerMiddle.transform.position - parentPosition);
_pillarOuterCornerMiddleRT.rotation = inverseRotation * _ep_PillarOuterCornerMiddle.transform.rotation;
}
}
else _pillarOuterCornerMiddleRT.reset();
}
private void getImaginaryInnerCornerParts(out GameObject firstPart, out GameObject secondPart)
{
firstPart = null;
secondPart = null;
if (hasInnerOuterCorners) return;
_examplePrefab.getAllChildren(false, false, _objectBuffer);
var lastStraight = getWallPieceByName(_lastStraightName, _objectBuffer);
var lastStraightOBB = calcStraightWallOBB(lastStraight);
lastStraightOBB.inflate(1e-2f);
foreach (var piece in _objectBuffer)
{
if (isWallPiecePillar(piece) || isWallPieceStraight(piece)) continue;
OBB pieceOBB = ObjectBounds.calcHierarchyWorldOBB(piece, getWallBoundsQConfig());
if (!pieceOBB.isValid) continue;
if (pieceOBB.intersectsOBB(lastStraightOBB))
{
secondPart = piece;
break;
}
}
if (secondPart == null) return;
var secondPartOBB = ObjectBounds.calcHierarchyWorldOBB(secondPart, getWallBoundsQConfig());
foreach (var piece in _objectBuffer)
{
if (isWallPiecePillar(piece) || isWallPieceStraight(piece) || piece == secondPart) continue;
OBB pieceOBB = ObjectBounds.calcHierarchyWorldOBB(piece, getWallBoundsQConfig());
if (!pieceOBB.isValid) continue;
if (pieceOBB.intersectsOBB(secondPartOBB))
{
firstPart = piece;
break;
}
}
}
private void getImaginaryOuterCornerParts(out GameObject firstPart, out GameObject secondPart)
{
firstPart = null;
secondPart = null;
if (hasInnerOuterCorners) return;
_examplePrefab.getAllChildren(false, false, _objectBuffer);
var firstStraight = getWallPieceByName(_firstStraightName, _objectBuffer);
var firstStraightOBB = calcStraightWallOBB(firstStraight);
firstStraightOBB.inflate(1e-2f);
foreach (var piece in _objectBuffer)
{
if (isWallPiecePillar(piece) || isWallPieceStraight(piece)) continue;
OBB pieceOBB = ObjectBounds.calcHierarchyWorldOBB(piece, getWallBoundsQConfig());
if (!pieceOBB.isValid) continue;
if (pieceOBB.intersectsOBB(firstStraightOBB))
{
firstPart = piece;
break;
}
}
if (firstPart == null) return;
var firstPartOBB = ObjectBounds.calcHierarchyWorldOBB(firstPart, getWallBoundsQConfig());
foreach (var piece in _objectBuffer)
{
if (isWallPiecePillar(piece) || isWallPieceStraight(piece) || piece == firstPart) continue;
OBB pieceOBB = ObjectBounds.calcHierarchyWorldOBB(piece, getWallBoundsQConfig());
if (!pieceOBB.isValid) continue;
if (pieceOBB.intersectsOBB(firstPartOBB))
{
secondPart = piece;
break;
}
}
}
private void detectForwardAxis()
{
// Note: Requires wall pieces which have the forward size larger then the inner size.
// Note: Don't use 'calcStraightWallOBB' here because it uses info which is not yet available.
OBB middleStraightOBB = ObjectBounds.calcHierarchyWorldOBB(_ep_MidStraight, getWallBoundsQConfig());
Vector3 obbSize = middleStraightOBB.size;
int a0 = ((int)_wallProperties.upAxis + 1) % 3;
int a1 = ((int)_wallProperties.upAxis + 2) % 3;
int fwAxisIndex = obbSize[a0] < obbSize[a1] ? a1 : a0;
_wallProperties.forwardAxis = (ModularWallAxis)fwAxisIndex;
_wallProperties.invertForwardAxis = false;
Vector3 fwAxis = _ep_MidStraight.transform.getLocalAxis(fwAxisIndex);
Vector3 vec = _ep_LastStraight.transform.position - _ep_MidStraight.transform.position;
if (Vector3.Dot(vec, fwAxis) < 0.0f) _wallProperties.invertForwardAxis = true;
}
private void detectInnerAxis()
{
int fwAxisIndex = (int)wallForwardAxis;
int upAxisIndex = (int)wallUpAxis;
if (Mathf.Abs(fwAxisIndex - upAxisIndex) == 2) _wallProperties.innerAxis = ModularWallAxis.Y;
else
{
if (fwAxisIndex > upAxisIndex) _wallProperties.innerAxis = (ModularWallAxis)((fwAxisIndex + 1) % 3);
else _wallProperties.innerAxis = (ModularWallAxis)((upAxisIndex + 1) % 3);
}
_wallProperties.invertInnerAxis = false;
Vector3 vec = _ep_LastStraight.transform.position - _ep_MidStraight.transform.position;
if (Vector3.Dot(vec, getModularWallInnerAxis(_ep_MidStraight)) < 0.0f) _wallProperties.invertInnerAxis = !_wallProperties.invertInnerAxis;
}
private void updateWallProperties()
{
if (_examplePrefab == null)
{
_wallProperties.height = 0.0f;
_wallProperties.forwardSize = 0.0f;
return;
}
detectForwardAxis();
detectInnerAxis();
GameObject straightPrefab = _ep_MidStraight;
Vector3 modelSize = PrefabDataDb.instance.getData(straightPrefab).modelSize;
_wallProperties.height = modelSize[(int)_wallProperties.upAxis];
if (_truncateForwardSize) _wallProperties.forwardSize = (int)modelSize[(int)_wallProperties.forwardAxis];
else _wallProperties.forwardSize = modelSize[(int)_wallProperties.forwardAxis];
}
private void OnEnable()
{
initializeTableArray();
initializeRulePrefabListArray();
refreshAllPrefabTables();
_wallBoundsQConfig.includeInactive = false;
_wallBoundsQConfig.includeInvisible = false;
_wallBoundsQConfig.objectTypes = GameObjectType.Mesh;
_pillarBoundsQConfig.includeInvisible = false;
_pillarBoundsQConfig.includeInactive = false;
_pillarBoundsQConfig.objectTypes = GameObjectType.Mesh;
Undo.undoRedoPerformed += onUndoRedo;
}
private void OnDisable()
{
Undo.undoRedoPerformed -= onUndoRedo;
}
private void onUndoRedo()
{
refreshAllPrefabTables();
}
private void OnDestroy()
{
deleteAllPrefabs();
}
}
}
#endif