MaidPlacementUtility.cs 4.9 KB

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