135 lines
5.2 KiB
C#
135 lines
5.2 KiB
C#
using UnityEngine;
|
|
|
|
public class MobShields : MonoBehaviour
|
|
{
|
|
eShieldType shieldType;
|
|
public float rotateSpeed = 180f; // 초당 회전 각도
|
|
|
|
public void Set(MonsterTableData data, bool isBoss)
|
|
{
|
|
transform.localEulerAngles = Vector3.zero;
|
|
shieldType = data.e_ShieldType;
|
|
|
|
switch (data.e_ShieldType)
|
|
{
|
|
case eShieldType.None:
|
|
gameObject.SetActive(false);
|
|
break;
|
|
case eShieldType.Static:
|
|
case eShieldType.Rotation:
|
|
Make_Shield(data, isBoss);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Make_Shield(MonsterTableData data, bool isBoss)
|
|
{
|
|
// 기존 실드 초기화 (비활성화)
|
|
var shields = GetComponentsInChildren<MobShield>(true);
|
|
for (int i = 0; i < shields.Length; i++)
|
|
{
|
|
shields[i].gameObject.SetActive(false);
|
|
}
|
|
|
|
gameObject.SetActive(true);
|
|
|
|
float radius = 2.5f;
|
|
|
|
// 보스 로직: 1 Unbreakable (180도), 4 Breakable (나머지 랜덤)
|
|
if (isBoss)
|
|
{
|
|
// 8방향: 0, 45, 90, 135, 180, 225, 270, 315
|
|
// 180도는 인덱스 4 (4 * 45 = 180)
|
|
int unbreakableIndex = 4;
|
|
System.Collections.Generic.List<int> availableIndices = new System.Collections.Generic.List<int>() { 0, 1, 2, 3, 5, 6, 7 };
|
|
|
|
// 무적 실드 생성 (180도)
|
|
CreateShield(unbreakableIndex, false, radius);
|
|
|
|
// 파괴 가능 실드 4개 생성 (나머지 랜덤)
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
if (availableIndices.Count == 0) break;
|
|
int randIdx = Random.Range(0, availableIndices.Count);
|
|
int angleIndex = availableIndices[randIdx];
|
|
availableIndices.RemoveAt(randIdx);
|
|
|
|
CreateShield(angleIndex, true, radius);
|
|
}
|
|
}
|
|
else // 일반 몬스터 로직
|
|
{
|
|
int crash = data.n_NormalShieldCount;
|
|
int noncrash = data.n_InvinityShieldCount;
|
|
int total = crash + noncrash;
|
|
|
|
// 8방향 인덱스 풀
|
|
System.Collections.Generic.List<int> weightedIndices = new System.Collections.Generic.List<int>();
|
|
// 180도 (인덱스 4) - 80% 확률, 나머지 - 20% 확률 (각 ~2.8%)?
|
|
// 요구사항: 180도 위치가 80% 확률이고, 나머지 방향은 20% 확률
|
|
// 간단하게 구현하기 위해, 180도(인덱스 4)를 많이 넣고 나머지를 적게 넣어서 추첨 풀을 만드는 방식보다는
|
|
// "위치 결정" 로직을 따로 짭니다.
|
|
// 하지만 여러 개의 실드를 배치해야 하므로, "이미 배치된 위치"를 제외하고 뽑아야 합니다.
|
|
|
|
System.Collections.Generic.List<int> availableIndices = new System.Collections.Generic.List<int>() { 0, 1, 2, 3, 4, 5, 6, 7 };
|
|
|
|
for (int i = 0; i < total; i++)
|
|
{
|
|
if (availableIndices.Count == 0) break;
|
|
|
|
int selectedIndex = -1;
|
|
|
|
// 180도(인덱스 4)가 아직 가용하다면 확률 적용
|
|
if (availableIndices.Contains(4))
|
|
{
|
|
// 80% 확률로 180도 선택
|
|
if (Random.value < 0.8f)
|
|
{
|
|
selectedIndex = 4;
|
|
}
|
|
else
|
|
{
|
|
// 나머지 중에서 랜덤
|
|
// 180도를 잠시 제외하고 뽑기
|
|
var others = new System.Collections.Generic.List<int>(availableIndices);
|
|
others.Remove(4);
|
|
if (others.Count > 0)
|
|
{
|
|
selectedIndex = others[Random.Range(0, others.Count)];
|
|
}
|
|
else
|
|
{
|
|
selectedIndex = 4; // 뽑을게 180도 밖에 없으면 그거라도
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 180도가 이미 뽑혔으면 그냥 나머지 중에서 랜덤
|
|
selectedIndex = availableIndices[Random.Range(0, availableIndices.Count)];
|
|
}
|
|
|
|
availableIndices.Remove(selectedIndex);
|
|
|
|
// 파괴 가능 여부: 앞쪽이 crash, 뒤쪽이 noncrash (기존 로직 유지)
|
|
bool isCrashShield = i < crash;
|
|
CreateShield(selectedIndex, isCrashShield, radius);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CreateShield(int angleIndex, bool isCrash, float radius)
|
|
{
|
|
var shield = DSUtil.Get_Clone<MobShield>("Mob/MobShield", transform, Vector3.one * 10000f);
|
|
float angle = (angleIndex * 45f + 90f) * Mathf.Deg2Rad;
|
|
Vector3 pos = new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0f) * radius;
|
|
shield.transform.localPosition = pos;
|
|
shield.Set(isCrash, GetComponentInParent<MobActor>());
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (shieldType == eShieldType.Rotation)
|
|
transform.Rotate(0f, 0f, rotateSpeed * Time.deltaTime);
|
|
}
|
|
} |