/// <summary> /// Places a worldobject at a position with a direction /// </summary> /// <param name="worldObject">worldobject</param> /// <param name="position">position</param> /// <param name="wallNormal">direction</param> public void Place(WorldObject worldObject, Vector3 position, Vector3 wallNormal) { BootStrapper.EnvironmentManager.CurrentEnvironment.Place(worldObject, position); worldObject.InitialWallNormal = wallNormal; worldObject.LookTowardsNormal(wallNormal); BarPlacement.RecalcBars(); StagePlacement.RecalcStages(); }
/// <summary> /// Sees if the cursor is over a wall and if a worldobject is placeable on it /// </summary> /// <param name="normal">normal</param> /// <param name="position">position</param> /// <param name="cursor">object to place</param> /// <returns>true if placement possible</returns> public bool WallPlacement(out Vector3 normal, out Vector3 position, WorldObject cursor) { //is the cursor over a wall RaycastHit hit; GameObject gameObject; if (UserWorldBuilder.Raycast(out hit, out gameObject)) { if (gameObject.name.Contains(Wall.IdentifierStatic)) { Vector3 firstWallPosition = hit.transform.position; normal = hit.normal; if (normal.y == 0) { //only wall sides, not the tops //perpendicular vector to normal (right vector from point of view of normal) Vector3 crossRight = Vector3.Cross(Vector3.up, normal).normalized; cursor.LookTowardsNormal(normal); float requiredWidth = cursor.Size.x; Vector3 leftMostWall = firstWallPosition; Vector3 rightMostWall = firstWallPosition; //Scans and checks existance of walls left and right of the selected wall int count = 1; Vector3 scanPosition = firstWallPosition; for (int i = 0; i < requiredWidth - 1; i++) { if (count >= requiredWidth) break; scanPosition += crossRight; if ( BootStrapper.EnvironmentManager.CurrentEnvironment.World.PointAlreadyOccupied( scanPosition)) { count++; rightMostWall = scanPosition; } else { scanPosition = firstWallPosition; for (int j = 0; j < requiredWidth - 1; j++) { if (count >= requiredWidth) break; scanPosition -= crossRight; if ( BootStrapper.EnvironmentManager.CurrentEnvironment.World .PointAlreadyOccupied(scanPosition)) { count++; leftMostWall = scanPosition; } else { break; } } break; } } //if walls are sufficiently wide, then calculate position of wall placed world object if (count >= requiredWidth) { Vector3 centerWall = (leftMostWall + rightMostWall) / 2; Vector3 requiredDepth = normal * (cursor.Size.z / 2); Vector3 wallOffset = normal * (Wall.SizeStatic.z / 2); position = centerWall + requiredDepth + wallOffset; return true; } } } } position = Vector3.zero; normal = Vector3.zero; return false; }
/// <summary> /// updates ghost cursor /// </summary> /// <param name="groundPosition">current ground position</param> public void UpdateSecondaryCursor(Vector3 groundPosition) { //secondary cursor for drag to place secondCursor = NewCursor(WorldObject.DetermineObject(currentItem), groundPosition); Vector3 mousePosition = groundPosition; Vector3 secondCursorPosition; var xDiff = startPlacement.x - mousePosition.x; var zDiff = startPlacement.z - mousePosition.z; if (Mathf.Abs(xDiff) > Mathf.Abs(zDiff)) { secondCursorPosition = startPlacement + new Vector3(-xDiff, 0, 0); } else { secondCursorPosition = startPlacement + new Vector3(0, 0, -zDiff); } secondCursor.GameObject.transform.position = Environment.Environment.PositionToLocation(secondCursorPosition, primaryCursor.Size); SetCursorHeight(secondCursor); secondCursor.GameObject.transform.rotation = primaryCursor.GameObject.transform.rotation; if (!primaryCursor.GridPlaceable) { // wall placement Vector3 position; Vector3 normal; if (worldBuilderPlacement.WallPlacement(out normal, out position, primaryCursor)) { secondCursor.LookTowardsNormal(normal); SetCursorValid(secondCursor); } else { SetCursorInvalid(secondCursor); } } }