diff --git a/Assets/OneShotOneKill.txt b/Assets/OneShotOneKill.txt index 5fd364a..0dfcd1b 100644 --- a/Assets/OneShotOneKill.txt +++ b/Assets/OneShotOneKill.txt @@ -1,6 +1,3 @@ -액티브 스킬 1종 -서포터 - 빌드 및 테스트 스킬 카드에 별 표시 diff --git a/Assets/Script/InGame/Actor/MobActor.cs b/Assets/Script/InGame/Actor/MobActor.cs index e9b2729..848a9ea 100644 --- a/Assets/Script/InGame/Actor/MobActor.cs +++ b/Assets/Script/InGame/Actor/MobActor.cs @@ -113,7 +113,7 @@ public class MobActor : MonoBehaviour m_HP = m_Data.n_DefaultHp + (bBoss ? curstagedata.n_DefaultBossHp : curstagedata.n_DefaultEnemyHp); (m_HUD_HP.transform as RectTransform).anchoredPosition = Vector2.one * 10000f; m_HUD_HP.Set(transform, m_HP); - m_MobShields.Set(data); + m_MobShields.Set(data, bBoss); } void Move() diff --git a/Assets/Script/InGame/Actor/MobShield.cs b/Assets/Script/InGame/Actor/MobShield.cs index 698894a..37406de 100644 --- a/Assets/Script/InGame/Actor/MobShield.cs +++ b/Assets/Script/InGame/Actor/MobShield.cs @@ -12,12 +12,12 @@ public class MobShield : MonoBehaviour { m_CrashShield = crashshield; m_Mob = mob; - m_SR.sprite = sprites[m_CrashShield ? 1 : 0]; + m_SR.sprite = sprites[m_CrashShield ? 0 : 1]; } public void Get_Dmg() { - gameObject.SetActive(m_CrashShield); + gameObject.SetActive(!m_CrashShield); var ImpactArrow = (int)IngameMgr.Ins.Get_SkillValue(eSkillType.ImpactArrow); if (ImpactArrow > 0) { diff --git a/Assets/Script/InGame/Actor/MobShields.cs b/Assets/Script/InGame/Actor/MobShields.cs index a649567..5680261 100644 --- a/Assets/Script/InGame/Actor/MobShields.cs +++ b/Assets/Script/InGame/Actor/MobShields.cs @@ -5,7 +5,7 @@ public class MobShields : MonoBehaviour eShieldType shieldType; public float rotateSpeed = 180f; // 초당 회전 각도 - public void Set(MonsterTableData data) + public void Set(MonsterTableData data, bool isBoss) { transform.localEulerAngles = Vector3.zero; shieldType = data.e_ShieldType; @@ -17,32 +17,114 @@ public class MobShields : MonoBehaviour break; case eShieldType.Static: case eShieldType.Rotation: - Make_Shield(data); + Make_Shield(data, isBoss); break; } } - void Make_Shield(MonsterTableData data) + void Make_Shield(MonsterTableData data, bool isBoss) { + // 기존 실드 초기화 (비활성화) + var shields = GetComponentsInChildren(true); + for (int i = 0; i < shields.Length; i++) + { + shields[i].gameObject.SetActive(false); + } + gameObject.SetActive(true); - int crash = data.n_NormalShieldCount; - int noncrash = data.n_InvinityShieldCount; + float radius = 2.5f; - int index = 0; - while (index < crash + noncrash) + // 보스 로직: 1 Unbreakable (180도), 4 Breakable (나머지 랜덤) + if (isBoss) { - var shield = DSUtil.Get_Clone("Mob/MobShield", transform, Vector3.one * 10000f); - switch (index) - { - case 0: shield.transform.localPosition = Vector3.down * 2.5f; break; - case 1: shield.transform.localPosition = Vector3.up * 2.5f; break; - case 2: shield.transform.localPosition = Vector3.right * 2.5f; break; - case 3: shield.transform.localPosition = Vector3.left * 2.5f; break; - } + // 8방향: 0, 45, 90, 135, 180, 225, 270, 315 + // 180도는 인덱스 4 (4 * 45 = 180) + int unbreakableIndex = 4; + System.Collections.Generic.List availableIndices = new System.Collections.Generic.List() { 0, 1, 2, 3, 5, 6, 7 }; + + // 무적 실드 생성 (180도) + CreateShield(unbreakableIndex, false, radius); - shield.Set(index++ < crash, GetComponentInParent()); + // 파괴 가능 실드 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 weightedIndices = new System.Collections.Generic.List(); + // 180도 (인덱스 4) - 80% 확률, 나머지 - 20% 확률 (각 ~2.8%)? + // 요구사항: 180도 위치가 80% 확률이고, 나머지 방향은 20% 확률 + // 간단하게 구현하기 위해, 180도(인덱스 4)를 많이 넣고 나머지를 적게 넣어서 추첨 풀을 만드는 방식보다는 + // "위치 결정" 로직을 따로 짭니다. + // 하지만 여러 개의 실드를 배치해야 하므로, "이미 배치된 위치"를 제외하고 뽑아야 합니다. + + System.Collections.Generic.List availableIndices = new System.Collections.Generic.List() { 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(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("Mob/MobShield", transform, Vector3.one * 10000f); + float angle = angleIndex * 45f * Mathf.Deg2Rad; + Vector3 pos = new Vector3(Mathf.Cos(angle), Mathf.Sin(angle), 0f) * radius; + shield.transform.localPosition = pos; + shield.Set(isCrash, GetComponentInParent()); } private void Update() diff --git a/Assets/Script/InGame/Actor/SupporterActor.cs b/Assets/Script/InGame/Actor/SupporterActor.cs index dd94c1d..f5d3695 100644 --- a/Assets/Script/InGame/Actor/SupporterActor.cs +++ b/Assets/Script/InGame/Actor/SupporterActor.cs @@ -23,9 +23,12 @@ public class SupporterActor : MonoBehaviour { attackCoolTime = MaxAttackCoolTime; var mob = IngameMgr.Ins.FindNearestMob(transform.position, null); - UpdateAngle(mob.transform.position); - m_PD.tf_Start = transform; - ProjectileMgr.Ins.Shoot_Projectile(m_PD); + if (mob != null) + { + UpdateAngle(mob.transform.position); + m_PD.tf_Start = transform; + ProjectileMgr.Ins.Shoot_Projectile(m_PD); + } } }