MaidPlacementUtility.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. namespace MeidoPhotoStudio.Plugin;
  4. public static class MaidPlacementUtility
  5. {
  6. public static readonly string[] PlacementTypes =
  7. {
  8. "horizontalRow", "verticalRow", "diagonalRow", "diagonalRowInverse", "wave", "waveInverse", "v", "vInverse",
  9. "circleInner", "circleOuter", "fanInner", "fanOuter",
  10. };
  11. private const float Pi = Mathf.PI;
  12. private const float Tau = Mathf.PI * 2f;
  13. public static int AlternatingSequence(int x) =>
  14. (int)((x % 2 == 0 ? 1 : -1) * Mathf.Ceil(x / 2f));
  15. public static void ApplyPlacement(string placementType, IList<Meido> list)
  16. {
  17. switch (placementType)
  18. {
  19. case "horizontalRow":
  20. PlacementRow(list, false);
  21. break;
  22. case "verticalRow":
  23. PlacementRow(list, true);
  24. break;
  25. case "diagonalRow":
  26. PlacementDiagonal(list, false);
  27. break;
  28. case "diagonalRowInverse":
  29. PlacementDiagonal(list, true);
  30. break;
  31. case "wave":
  32. PlacementWave(list, false);
  33. break;
  34. case "waveInverse":
  35. PlacementWave(list, true);
  36. break;
  37. case "v":
  38. PlacementV(list, false);
  39. break;
  40. case "vInverse":
  41. PlacementV(list, true);
  42. break;
  43. case "circleOuter":
  44. PlacementCircle(list, false);
  45. break;
  46. case "circleInner":
  47. PlacementCircle(list, true);
  48. break;
  49. case "fanInner":
  50. PlacementFan(list, false);
  51. break;
  52. case "fanOuter":
  53. PlacementFan(list, true);
  54. break;
  55. default:
  56. return;
  57. }
  58. }
  59. public static void PlacementRow(IList<Meido> list, bool vertical = false)
  60. {
  61. for (var i = 0; i < list.Count; i++)
  62. {
  63. var position = Vector3.zero;
  64. var maid = list[i].Maid;
  65. var a = AlternatingSequence(i) * 0.6f;
  66. if (vertical)
  67. position.z = a;
  68. else
  69. position.x = a;
  70. maid.SetPos(position);
  71. maid.SetRot(Vector3.zero);
  72. }
  73. }
  74. public static void PlacementDiagonal(IList<Meido> list, bool inverse = false)
  75. {
  76. for (var i = 0; i < list.Count; i++)
  77. {
  78. var maid = list[i].Maid;
  79. var z = AlternatingSequence(i) * 0.5f;
  80. maid.SetPos(inverse ? new(z, 0, -z) : new(z, 0, z));
  81. maid.SetRot(Vector3.zero);
  82. }
  83. }
  84. public static void PlacementWave(IList<Meido> list, bool inverse = false)
  85. {
  86. for (var i = 0; i < list.Count; i++)
  87. {
  88. var maid = list[i].Maid;
  89. var x = AlternatingSequence(i) * 0.4f;
  90. var z = (inverse ? -1 : 1) * Mathf.Cos(AlternatingSequence(i) * Pi) * 0.35f;
  91. maid.SetPos(new(x, 0, z));
  92. maid.SetRot(Vector3.zero);
  93. }
  94. }
  95. public static void PlacementV(IList<Meido> list, bool inverse = false)
  96. {
  97. for (var i = 0; i < list.Count; i++)
  98. {
  99. var maid = list[i].Maid;
  100. var x = AlternatingSequence(i) * 0.4f;
  101. var z = (inverse ? 1 : -1) * Mathf.Abs(AlternatingSequence(i)) * 0.4f;
  102. maid.SetPos(new(x, 0, z));
  103. maid.SetRot(Vector3.zero);
  104. }
  105. }
  106. public static void PlacementCircle(IList<Meido> list, bool inner = false)
  107. {
  108. var maidCount = list.Count;
  109. var radius = 0.3f + 0.1f * maidCount;
  110. for (var i = 0; i < maidCount; i++)
  111. {
  112. var maid = list[i].Maid;
  113. var angle = Pi / 2f + Tau * AlternatingSequence(i) / maidCount;
  114. var x = Mathf.Cos(angle) * radius;
  115. var z = Mathf.Sin(angle) * radius;
  116. var rotation = Mathf.Atan2(x, z);
  117. if (inner)
  118. rotation += Pi;
  119. maid.SetPos(new(x, 0, z));
  120. maid.SetRot(new(0, rotation * Mathf.Rad2Deg, 0));
  121. }
  122. }
  123. public static void PlacementFan(IList<Meido> list, bool outer = false)
  124. {
  125. var maidCount = list.Count;
  126. var radius = 0.2f + 0.2f * maidCount;
  127. list[0].Maid.SetPos(Vector3.zero);
  128. list[0].Maid.SetRot(Vector3.zero);
  129. for (var i = 1; i < maidCount; i++)
  130. {
  131. var maid = list[i].Maid;
  132. var angle = Pi * AlternatingSequence(i - 1) / maidCount;
  133. var x = Mathf.Sin(angle) * radius;
  134. var z = Mathf.Cos(angle) * radius;
  135. var rotation = Mathf.Atan2(x, z);
  136. if (outer)
  137. rotation += Pi;
  138. maid.SetPos(new(-x, 0, -z));
  139. maid.SetRot(new(0, rotation * Mathf.Rad2Deg, 0));
  140. }
  141. }
  142. }