using System.Collections.Generic; using UnityEngine; namespace COM3D2.MeidoPhotoStudio.Plugin { public static class MaidPlacementUtility { private const float pi = Mathf.PI; private const float tau = Mathf.PI * 2f; public static readonly string[] placementTypes = { "horizontalRow", "verticalRow", "diagonalRow", "diagonalRowInverse", "wave", "waveInverse", "v", "vInverse", "circleInner", "circleOuter", "fanInner", "fanOuter" }; public static int AlternatingSequence(int x) => (int)((x % 2 == 0 ? 1 : -1) * Mathf.Ceil(x / 2f)); public static void ApplyPlacement(string placementType, IList list) { switch (placementType) { case "horizontalRow": PlacementRow(list, false); break; case "verticalRow": PlacementRow(list, true); break; case "diagonalRow": PlacementDiagonal(list, false); break; case "diagonalRowInverse": PlacementDiagonal(list, true); break; case "wave": PlacementWave(list, false); break; case "waveInverse": PlacementWave(list, true); break; case "v": PlacementV(list, false); break; case "vInverse": PlacementV(list, true); break; case "circleOuter": PlacementCircle(list, false); break; case "circleInner": PlacementCircle(list, true); break; case "fanInner": PlacementFan(list, false); break; case "fanOuter": PlacementFan(list, true); break; default: return; } } public static void PlacementRow(IList list, bool vertical = false) { for (int i = 0; i < list.Count; i++) { Vector3 position = Vector3.zero; Maid maid = list[i].Maid; float a = AlternatingSequence(i) * 0.6f; if (vertical) position.z = a; else position.x = a; maid.SetPos(position); maid.SetRot(Vector3.zero); } } public static void PlacementDiagonal(IList list, bool inverse = false) { for (int i = 0; i < list.Count; i++) { Maid maid = list[i].Maid; float z = AlternatingSequence(i) * 0.5f; maid.SetPos(inverse ? new Vector3(z, 0, -z) : new Vector3(z, 0, z)); maid.SetRot(Vector3.zero); } } public static void PlacementWave(IList list, bool inverse = false) { for (int i = 0; i < list.Count; i++) { Maid maid = list[i].Maid; float x = AlternatingSequence(i) * 0.4f; float z = (inverse ? -1 : 1) * Mathf.Cos(AlternatingSequence(i) * pi) * 0.35f; maid.SetPos(new Vector3(x, 0, z)); maid.SetRot(Vector3.zero); } } public static void PlacementV(IList list, bool inverse = false) { for (int i = 0; i < list.Count; i++) { Maid maid = list[i].Maid; float x = AlternatingSequence(i) * 0.4f; float z = (inverse ? 1 : -1) * Mathf.Abs(AlternatingSequence(i)) * 0.4f; maid.SetPos(new Vector3(x, 0, z)); maid.SetRot(Vector3.zero); } } public static void PlacementCircle(IList list, bool inner = false) { int maidCount = list.Count; float radius = 0.3f + (0.1f * maidCount); for (int i = 0; i < maidCount; i++) { Maid maid = list[i].Maid; float angle = (pi / 2f) + (tau * AlternatingSequence(i) / maidCount); float x = Mathf.Cos(angle) * radius; float z = Mathf.Sin(angle) * radius; float rotation = Mathf.Atan2(x, z); if (inner) rotation += pi; maid.SetPos(new Vector3(x, 0, z)); maid.SetRot(new Vector3(0, rotation * Mathf.Rad2Deg, 0)); } } public static void PlacementFan(IList list, bool outer = false) { int maidCount = list.Count; float radius = 0.2f + (0.2f * maidCount); list[0].Maid.SetPos(Vector3.zero); list[0].Maid.SetRot(Vector3.zero); for (int i = 1; i < maidCount; i++) { Maid maid = list[i].Maid; float angle = pi * AlternatingSequence(i - 1) / maidCount; float x = Mathf.Sin(angle) * radius; float z = Mathf.Cos(angle) * radius; float rotation = Mathf.Atan2(x, z); if (outer) rotation += pi; maid.SetPos(new Vector3(-x, 0, -z)); maid.SetRot(new Vector3(0, rotation * Mathf.Rad2Deg, 0)); } } } }