private static void EnsureGuideUsesBeginTileConnectionPrefab() { ObjectPlacementPathTileConnectionSettings tileConnectionSettings = ObjectPlacement.Get().PathObjectPlacement.PathSettings.TileConnectionSettings; ObjectPlacementPathTileConnectionTypeSettings beginTileConnectionSettings = tileConnectionSettings.GetSettingsForTileConnectionType(ObjectPlacementPathTileConnectionType.Begin); if (CanRefreshGuideToUseBeginTileConnectionPrefab(beginTileConnectionSettings)) { PrefabCategory categoryWhichContainsBeginPrefab = PrefabCategoryDatabase.Get().GetPrefabCategoryWhichContainsPrefab(beginTileConnectionSettings.Prefab); if (categoryWhichContainsBeginPrefab == null) { return; } PrefabCategoryDatabase.Get().SetActivePrefabCategory(categoryWhichContainsBeginPrefab); categoryWhichContainsBeginPrefab.SetActivePrefab(beginTileConnectionSettings.Prefab); ObjectPlacement.Get().DestroyPlacementGuide(); ObjectPlacementGuide.CreateFromActivePrefabIfNotExists(); } // Note: When using tile connections, we will always use the original prefab scale if (ObjectPlacementGuide.ExistsInScene) { ObjectPlacementGuide.Instance.WorldScale = beginTileConnectionSettings.Prefab.InitialWorldScale; } }
private void RenderPathUnderManualConstruction(ObjectPlacementPath path) { ObjectPlacementPathTileConnectionSettings tileConnectionSettings = path.Settings.TileConnectionSettings; if (tileConnectionSettings.UseTileConnections) { RenderPathUnderManualConstructionWhenUsingTileConnections(path, tileConnectionSettings); } else { RenderPathUnderManualConstructionWhenNotUsingTileConnections(path); } }
private List <Vector3> CalculateOffsetsForAllTileConnectionsExceptAutofill() { var offsets = new List <Vector3>(ObjectPlacementPathTileConnectionTypes.Count); ObjectPlacementPathTileConnectionSettings tileConnectionSettings = _path.Settings.TileConnectionSettings; var tileConnectionYOffsetVectorCalculator = new ObjectPlacementPathTileConnectionYOffsetVectorCalculator(); List <ObjectPlacementPathTileConnectionType> allTileConnectionTypes = ObjectPlacementPathTileConnectionTypes.GetAllExceptAutofill(); foreach (ObjectPlacementPathTileConnectionType tileConnectionType in allTileConnectionTypes) { offsets.Add(tileConnectionYOffsetVectorCalculator.Calculate(tileConnectionSettings.GetSettingsForTileConnectionType(tileConnectionType), _path)); } return(offsets); }
public void ApplyConfigurationDataToSettings(ObjectPlacementPathTileConnectionSettings tileConnectionSettings) { List <ObjectPlacementPathTileConnectionType> allTileConnectionTypes = ObjectPlacementPathTileConnectionTypes.GetAll(); foreach (ObjectPlacementPathTileConnectionType tileConnectionType in allTileConnectionTypes) { int tileConnectionIndex = (int)tileConnectionType; ObjectPlacementPathTileConnectionTypeSettings tileConnectionTypeSettings = tileConnectionSettings.GetSettingsForTileConnectionType(tileConnectionType); tileConnectionTypeSettings.YAxisRotation = _tileConnectionYAxisRotations[tileConnectionIndex]; tileConnectionTypeSettings.YOffset = _tileConnectionYOffsets[tileConnectionIndex]; tileConnectionTypeSettings.UpwardsExtrusionAmount = _tileConnectionUpwardsExtrusionAmount[tileConnectionIndex]; tileConnectionTypeSettings.DownwardsExtrusionAmount = _tileConnectionDownwardsExtrusionAmount[tileConnectionIndex]; tileConnectionTypeSettings.Prefab = _tileConnectionPrefabs[tileConnectionIndex]; } }
private bool ValidatePlacementDataCalculationConditions() { if (_path == null || _path.NumberOfSegments == 0 || !ObjectPlacementGuide.ExistsInScene || _tileConnectionXZSize == 0.0f) { return(false); } ObjectPlacementPathTileConnectionSettings tileConnectionSettings = PathObjectPlacement.Get().PathSettings.TileConnectionSettings; if (!tileConnectionSettings.DoAllTileConnectionsHavePrefabAssociated(true)) { Debug.LogWarning("Not all tile connections have an associated prefab. Path placement was cancelled."); return(false); } return(true); }
public void SetData(ObjectPlacementPathManualConstructionSessionData sessionData) { if (!_isActive) { _path = sessionData.Path; _pathSegments = sessionData.PathSegments; _pathExtensionPlane = sessionData.PathExtensionPlane; _tileConnectionGridCells = sessionData.TileConnectionGridCells; _startObject = sessionData.StartObject; _startObjectHierarchyWorldOrientedBox = _startObject.GetHierarchyWorldOrientedBox(); _pathSettings = _path.Settings; _tileConnectionSettings = _pathSettings.TileConnectionSettings; _manualConstructionSettings = _pathSettings.ManualConstructionSettings; _heightAdjustmentSettings = _manualConstructionSettings.HeightAdjustmentSettings; _paddingSettings = _manualConstructionSettings.PaddingSettings; _borderSettings = _manualConstructionSettings.BorderSettings; _pathNoTileConnectionsObjectPlacementDataCalculator.Path = _path; _pathWithTileConnectionsObjectPlacementDataCalculator.Path = _path; } }
public ObjectPlacementPathTileConnectionSettingsView(ObjectPlacementPathTileConnectionSettings settings) { _settings = settings; }
public Quaternion Calculate(ObjectPlacementPathTileConnectionGridCell tileConnectionGridCell) { ObjectPlacementPath path = tileConnectionGridCell.TileConnectionPath; ObjectPlacementPathTileConnectionSettings tileConnectionSettings = path.Settings.TileConnectionSettings; Plane extensionPlane = path.ExtensionPlane; ObjectPlacementBoxStackSegment tileConnectionSegment = tileConnectionGridCell.TileConnectionSegment; ObjectPlacementBoxStack tileConnectionStack = tileConnectionGridCell.TileConnectionStack; bool usingSprites = tileConnectionSettings.UsesSprites(); float yAxisRotationInDegrees = ObjectPlacementPathTileConnectionYAxisRotations.GetAngleInDegrees(tileConnectionSettings.GetSettingsForTileConnectionType(tileConnectionGridCell.TileConnectionType).YAxisRotation); Quaternion yAxisRotation = Quaternion.AngleAxis(yAxisRotationInDegrees, extensionPlane.normal); Quaternion defaultRotation = Quaternion.LookRotation(path.ExtensionPlaneLookAxis, extensionPlane.normal); if (usingSprites) { defaultRotation = Quaternion.LookRotation(extensionPlane.normal, path.ExtensionPlaneLookAxis); } ObjectPlacementPathTileConnectionType tileConnectionType = tileConnectionGridCell.TileConnectionType; if (tileConnectionType == ObjectPlacementPathTileConnectionType.Autofill) { return(yAxisRotation * defaultRotation); } else if (tileConnectionType == ObjectPlacementPathTileConnectionType.Begin) { if (tileConnectionGridCell.NumberOfNeighbours == 0) { return(yAxisRotation * defaultRotation); } else { ObjectPlacementBoxStack neighbour = tileConnectionGridCell.GetFirstNeighbour().TileConnectionStack; Vector3 toNeighbour = tileConnectionStack.GetNormalizedBasePositionConnectionVectorTo(neighbour); if (usingSprites) { return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toNeighbour)); } return(yAxisRotation * Quaternion.LookRotation(toNeighbour, extensionPlane.normal)); } } else if (tileConnectionType == ObjectPlacementPathTileConnectionType.End) { ObjectPlacementBoxStack neighbour = tileConnectionGridCell.GetFirstNeighbour().TileConnectionStack; Vector3 toEndTile = neighbour.GetNormalizedBasePositionConnectionVectorTo(tileConnectionStack); if (usingSprites) { return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toEndTile)); } return(yAxisRotation * Quaternion.LookRotation(toEndTile, extensionPlane.normal)); } else if (tileConnectionType == ObjectPlacementPathTileConnectionType.Cross) { return(yAxisRotation * defaultRotation); } else if (tileConnectionType == ObjectPlacementPathTileConnectionType.TJunction) { ObjectPlacementBoxStack baseOfTJunction = null; if (tileConnectionGridCell.RightNeighbour != null && tileConnectionGridCell.LeftNeighbour != null) { baseOfTJunction = tileConnectionGridCell.ForwardNeighbour != null ? tileConnectionGridCell.ForwardNeighbour.TileConnectionStack : tileConnectionGridCell.BackNeighbour.TileConnectionStack; } else { baseOfTJunction = tileConnectionGridCell.RightNeighbour != null ? tileConnectionGridCell.RightNeighbour.TileConnectionStack : tileConnectionGridCell.LeftNeighbour.TileConnectionStack; } Vector3 toTJunction = baseOfTJunction.GetNormalizedBasePositionConnectionVectorTo(tileConnectionStack); if (usingSprites) { return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toTJunction)); } return(yAxisRotation * Quaternion.LookRotation(toTJunction, extensionPlane.normal)); } else if (tileConnectionType == ObjectPlacementPathTileConnectionType.Forward) { if (tileConnectionSegment.NumberOfStacks == 1) { if (tileConnectionGridCell.HasForwardAndBackNeightbours()) { ObjectPlacementBoxStack forwardNeighbour = tileConnectionGridCell.ForwardNeighbour.TileConnectionStack; ObjectPlacementBoxStack backNeighbour = tileConnectionGridCell.BackNeighbour.TileConnectionStack; Vector3 toForwardNeighbour = backNeighbour.GetNormalizedBasePositionConnectionVectorTo(forwardNeighbour); if (usingSprites) { return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toForwardNeighbour)); } return(yAxisRotation * Quaternion.LookRotation(toForwardNeighbour, extensionPlane.normal)); } else { ObjectPlacementBoxStack leftNeighbour = tileConnectionGridCell.LeftNeighbour.TileConnectionStack; ObjectPlacementBoxStack rightNeighbour = tileConnectionGridCell.RightNeighbour.TileConnectionStack; Vector3 toRightNeighbour = leftNeighbour.GetNormalizedBasePositionConnectionVectorTo(rightNeighbour); if (usingSprites) { return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, toRightNeighbour)); } return(yAxisRotation * Quaternion.LookRotation(toRightNeighbour, extensionPlane.normal)); } } else { if (usingSprites) { return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, tileConnectionSegment.ExtensionDirection)); } return(yAxisRotation * Quaternion.LookRotation(tileConnectionSegment.ExtensionDirection, extensionPlane.normal)); } } else { ObjectPlacementBoxStack firstNeighbour, secondNeighbour; if (tileConnectionGridCell.RightNeighbour != null) { firstNeighbour = tileConnectionGridCell.RightNeighbour.TileConnectionStack; secondNeighbour = tileConnectionGridCell.ForwardNeighbour != null ? tileConnectionGridCell.ForwardNeighbour.TileConnectionStack : tileConnectionGridCell.BackNeighbour.TileConnectionStack; } else if (tileConnectionGridCell.LeftNeighbour != null) { firstNeighbour = tileConnectionGridCell.LeftNeighbour.TileConnectionStack; secondNeighbour = tileConnectionGridCell.ForwardNeighbour != null ? tileConnectionGridCell.ForwardNeighbour.TileConnectionStack : tileConnectionGridCell.BackNeighbour.TileConnectionStack; } else if (tileConnectionGridCell.ForwardNeighbour != null) { firstNeighbour = tileConnectionGridCell.ForwardNeighbour.TileConnectionStack; secondNeighbour = tileConnectionGridCell.RightNeighbour != null ? tileConnectionGridCell.RightNeighbour.TileConnectionStack : tileConnectionGridCell.LeftNeighbour.TileConnectionStack; } else { firstNeighbour = tileConnectionGridCell.BackNeighbour.TileConnectionStack; secondNeighbour = tileConnectionGridCell.RightNeighbour != null ? tileConnectionGridCell.RightNeighbour.TileConnectionStack : tileConnectionGridCell.LeftNeighbour.TileConnectionStack; } Vector3 tileLook, tileRight; tileLook = firstNeighbour.GetNormalizedBasePositionConnectionVectorTo(tileConnectionStack); tileRight = tileConnectionStack.GetNormalizedBasePositionConnectionVectorTo(secondNeighbour); Vector3 tileUp = Vector3.Cross(tileLook, tileRight); if (Vector3.Dot(tileUp, extensionPlane.normal) < 0.0f) { tileLook = -tileRight; } if (usingSprites) { return(yAxisRotation * Quaternion.LookRotation(extensionPlane.normal, tileLook)); } return(yAxisRotation * Quaternion.LookRotation(tileLook, extensionPlane.normal)); } }
private void RenderPathUnderManualConstructionWhenUsingTileConnections(ObjectPlacementPath path, ObjectPlacementPathTileConnectionSettings tileConnectionSettings) { List <ObjectPlacementPathTileConnectionGridCell> tileConnectionGridCells = path.TileConnectionGridCells; ObjectPlacementPathManualConstructionRenderSettings renderSettings = path.RenderSettings.ManualConstructionRenderSettings; var tileConnectionYOffsetVectorCalculator = new ObjectPlacementPathTileConnectionYOffsetVectorCalculator(); // Loop through all tile connection grid cells. Each cell will give us access to all the information // that we need to perform the rendering operation. foreach (ObjectPlacementPathTileConnectionGridCell tileConnectionGridCell in tileConnectionGridCells) { // Use the cell to access the tile connection stack. If the stack is overlapped by another stack // or if no boxes exist in the stack, we can move on to the next cell. ObjectPlacementBoxStack tileConnectionStack = tileConnectionGridCell.TileConnectionStack; if (tileConnectionStack.IsOverlappedByAnotherStack || tileConnectionStack.NumberOfBoxes == 0) { continue; } // Calculate the Y offset vector which applies to all tiles in the current stack and then render each // box which resides inside the stack. Vector3 tileConnectionYOffsetVector = tileConnectionYOffsetVectorCalculator.Calculate(tileConnectionSettings.GetSettingsForTileConnectionType(tileConnectionGridCell.TileConnectionType), path); for (int boxIndex = 0; boxIndex < tileConnectionStack.NumberOfBoxes; ++boxIndex) { // If the box is hidden, we can move on to the next box ObjectPlacementBox placementBox = tileConnectionStack.GetBoxByIndex(boxIndex); if (placementBox.IsHidden) { continue; } // Retrieve the box and apply the Y offset vector. The render the box. OrientedBox orientedBox = placementBox.OrientedBox; orientedBox.Center += tileConnectionYOffsetVector; GizmosEx.RenderOrientedBoxEdges(orientedBox, renderSettings.BoxBorderLineColor); } // We have to take tile connection extrusion into account, so we will need to retrieve the extrusion // boxes and render those too. List <OrientedBox> extrusionOrientedBoxes = ObjectPlacementPathTileConnectionExtrusion.GetTileConnectionExtrusionOrientedBoxes(tileConnectionGridCell); foreach (OrientedBox extrusionBox in extrusionOrientedBoxes) { GizmosEx.RenderOrientedBoxEdges(extrusionBox, renderSettings.BoxBorderLineColor); } } }
public List <ObjectPlacementData> Calculate() { if (!ValidatePlacementDataCalculationConditions()) { return(new List <ObjectPlacementData>()); } _allowObjectIntersection = ObjectPlacementSettings.Get().ObjectIntersectionSettings.AllowIntersectionForPathPlacement; List <ObjectPlacementBoxStackSegment> allPathSegments = _path.GetAllSegments(); float objectMissChance = _path.Settings.ManualConstructionSettings.ObjectMissChance; bool usingSprites = _path.Settings.TileConnectionSettings.UsesSprites(); var tileConnectionDetector = new ObjectPlacementPathTileConnectionDetector(); var tileConnectionRotationCalculator = new ObjectPlacementPathTileConnectionRotationCalculator(); List <ObjectPlacementPathTileConnectionGridCell> tileConnectionGridCells = tileConnectionDetector.Detect(_path, _tileConnectionXZSize); if (tileConnectionGridCells.Count == 0) { return(new List <ObjectPlacementData>()); } List <Prefab> tileConnectionPrefabsExceptAutofill = PathObjectPlacement.Get().PathSettings.TileConnectionSettings.GetAllTileConnectionPrefabs(true); List <Vector3> tileConnectionWorldScaleValuesExceptAutofill = CalculateWorldScaleForAllTileConnectionPrefabsExceptAutofill(PrefabQueries.GetTransformsForAllPrefabs(tileConnectionPrefabsExceptAutofill), PrefabQueries.GetHierarchyWorldOrientedBoxesForAllPrefabs(tileConnectionPrefabsExceptAutofill)); List <Vector3> tileConnectionOffsetsExceptAutofill = CalculateOffsetsForAllTileConnectionsExceptAutofill(); var objectPlacementDataInstances = new List <ObjectPlacementData>(allPathSegments.Count * 10); foreach (ObjectPlacementPathTileConnectionGridCell tileConnectionGridCell in tileConnectionGridCells) { ObjectPlacementPathTileConnectionType tileConnectionType = tileConnectionGridCell.TileConnectionType; ObjectPlacementBoxStack tileConnectionStack = tileConnectionGridCell.TileConnectionStack; if (tileConnectionStack.IsOverlappedByAnotherStack) { continue; } Prefab tileConnectionPrefab = tileConnectionPrefabsExceptAutofill[(int)tileConnectionType]; Quaternion tileConnectionRotation = tileConnectionRotationCalculator.Calculate(tileConnectionGridCell); Vector3 tileConnectionWorldScale = tileConnectionWorldScaleValuesExceptAutofill[(int)tileConnectionType]; Vector3 tileConnectionOffset = tileConnectionOffsetsExceptAutofill[(int)tileConnectionType]; for (int stackBoxIndex = 0; stackBoxIndex < tileConnectionStack.NumberOfBoxes; ++stackBoxIndex) { ObjectPlacementBox box = tileConnectionStack.GetBoxByIndex(stackBoxIndex); if (box.IsHidden) { continue; } if (ObjectPlacementMissChance.Missed(objectMissChance, ObjectPlacementPathManualConstructionSettings.MinObjectMissChance, ObjectPlacementPathManualConstructionSettings.MaxObjectMissChance)) { continue; } if (!_allowObjectIntersection && ObjectQueries.IntersectsAnyObjectsInScene(box.OrientedBox, true)) { continue; } var objectPlacementData = new ObjectPlacementData(); objectPlacementData.WorldPosition = ObjectPositionCalculator.CalculateObjectHierarchyPosition(tileConnectionPrefab, box.Center, tileConnectionWorldScale, tileConnectionRotation); objectPlacementData.WorldPosition += tileConnectionOffset; objectPlacementData.WorldScale = tileConnectionWorldScale; objectPlacementData.WorldRotation = tileConnectionRotation; objectPlacementData.Prefab = tileConnectionPrefab; objectPlacementDataInstances.Add(objectPlacementData); } // Apply extrusion if necessary if (!usingSprites) { List <OrientedBox> extrusionOrientedBoxes = ObjectPlacementPathTileConnectionExtrusion.GetTileConnectionExtrusionOrientedBoxes(tileConnectionGridCell); foreach (OrientedBox extrusionBox in extrusionOrientedBoxes) { if (ObjectPlacementMissChance.Missed(objectMissChance, ObjectPlacementPathManualConstructionSettings.MinObjectMissChance, ObjectPlacementPathManualConstructionSettings.MaxObjectMissChance)) { continue; } if (!_allowObjectIntersection && ObjectQueries.IntersectsAnyObjectsInScene(extrusionBox, true)) { continue; } var objectPlacementData = new ObjectPlacementData(); objectPlacementData.WorldPosition = ObjectPositionCalculator.CalculateObjectHierarchyPosition(tileConnectionPrefab, extrusionBox.Center, tileConnectionWorldScale, tileConnectionRotation); objectPlacementData.WorldScale = tileConnectionWorldScale; objectPlacementData.WorldRotation = tileConnectionRotation; objectPlacementData.Prefab = tileConnectionPrefab; objectPlacementDataInstances.Add(objectPlacementData); } } } ObjectPlacementPathTileConnectionSettings tileConnectionSettings = _path.Settings.TileConnectionSettings; if (tileConnectionSettings.DoesAutofillTileConnectionHavePrefabAssociated()) { objectPlacementDataInstances.AddRange(GetPlacementDataForAutofillTiles(tileConnectionGridCells[0].ParentGrid)); } return(objectPlacementDataInstances); }
public List <ObjectPlacementPathTileConnectionGridCell> CreateAndReturnAutofillTileConnectionCells() { ObjectPlacementPathTileConnectionSettings tileConnectionSettings = _path.Settings.TileConnectionSettings; if (!tileConnectionSettings.DoesAutofillTileConnectionHavePrefabAssociated()) { return(new List <ObjectPlacementPathTileConnectionGridCell>()); } Plane pathExtensionPlane = _path.ExtensionPlane; OrientedBox autofillPrefabOrientedBox = tileConnectionSettings.GetSettingsForTileConnectionType(ObjectPlacementPathTileConnectionType.Autofill).Prefab.UnityPrefab.GetHierarchyWorldOrientedBox(); Vector3 autofillStackBoxSize = new Vector3(_cellXZSize, autofillPrefabOrientedBox.ScaledSize.y, _cellXZSize); Quaternion autofillStackRotation = Quaternion.LookRotation(_path.ExtensionPlaneLookAxis, pathExtensionPlane.normal); bool[,] cellAutofillFlags = new bool[NumberOfCellsOnX, NumberOfCellsOnZ]; // We will first set all occupied cells to true foreach (var pair in _occupiedCells) { cellAutofillFlags[pair.Key.XIndex - MinCellIndexX, pair.Key.ZIndex - MinCellIndexZ] = true; } var autofillGridCells = new List <ObjectPlacementPathTileConnectionGridCell>(NumberOfCellsOnX * NumberOfCellsOnZ); for (int z = MinCellIndexZ; z <= MaxCellIndexZ; ++z) { for (int x = MinCellIndexX; x <= MaxCellIndexX; ++x) { if (cellAutofillFlags[x - MinCellIndexX, z - MinCellIndexZ]) { continue; } var traversedIndices = new HashSet <ObjectPlacementPathTileConnectionGridCellIndices>(); if (DetectCellsWhichLeadOutsideOfGridRecurse(cellAutofillFlags, x, z, traversedIndices)) { foreach (ObjectPlacementPathTileConnectionGridCellIndices indices in traversedIndices) { cellAutofillFlags[indices.XIndex - MinCellIndexX, indices.ZIndex - MinCellIndexZ] = true; } } if (!cellAutofillFlags[x - MinCellIndexX, z - MinCellIndexZ]) { var autofillGridCell = new ObjectPlacementPathTileConnectionGridCell(new ObjectPlacementPathTileConnectionGridCellIndices(x, z), this); autofillGridCells.Add(autofillGridCell); AddCell(autofillGridCell); var tileConnectionStack = new ObjectPlacementBoxStack(); tileConnectionStack.SetBoxSize(autofillStackBoxSize); tileConnectionStack.SetRotation(autofillStackRotation); tileConnectionStack.SetBasePosition(CalculateCellPosition(x, z)); tileConnectionStack.PlaceOnPlane(pathExtensionPlane); tileConnectionStack.GrowUpwards(1); autofillGridCell.TileConnectionStack = tileConnectionStack; autofillGridCell.TileConnectionPath = _path; autofillGridCell.TileConnectionType = ObjectPlacementPathTileConnectionType.Autofill; } } } return(autofillGridCells); }