From 0b49549afd62d1eca996935816b11fac38ae05cd Mon Sep 17 00:00:00 2001 From: Ino Date: Fri, 16 Jan 2026 12:49:39 +0900 Subject: [PATCH] =?UTF-8?q?"=EB=AA=AC=EC=8A=A4=ED=84=B0=EC=9D=98=20?= =?UTF-8?q?=EC=8B=A4=EB=93=9C=20=EC=9C=84=EC=B9=98=EB=8A=94=20360=EB=8F=84?= =?UTF-8?q?=20=EB=B0=A9=ED=96=A5=20=EC=A4=91=209=20=EB=B0=A9=ED=96=A5?= =?UTF-8?q?=EC=9D=84=20=EC=A7=80=EC=A0=95=ED=95=B4=20=EB=9E=9C=EB=8D=A4?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=82=98=EC=98=A4=EA=B2=8C=20=ED=95=98?= =?UTF-8?q?=EB=A9=B4=20=EC=A2=8B=EA=B2=A0=EC=8A=B5=EB=8B=88=EB=8B=A4.=200?= =?UTF-8?q?=2045=2090=20135=20180=20225=20270=20315=20360?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit → 이중 180도 방향 몬스터 하단 방향(180도 위치)가 80% 확률이고, 나머지 방향은 20% 확률로 나오면 좋을거 같습니다." 보스 몬스터 주위를 도는 쉴드는 안깨지는 실드 1개(180도 방향)와 깨지는 실드 4개를 랜덤위치로 배치해 빙글빙글 돌아가게 하면 좋겠습니다 (180도 방향을 제외한 랜덤 방향) --- Assets/OneShotOneKill.txt | 3 - Assets/Script/InGame/Actor/MobActor.cs | 2 +- Assets/Script/InGame/Actor/MobShield.cs | 4 +- Assets/Script/InGame/Actor/MobShields.cs | 114 ++++++++++++++++--- Assets/Script/InGame/Actor/SupporterActor.cs | 9 +- 5 files changed, 107 insertions(+), 25 deletions(-) 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); + } } }