using System; using System.Collections.Generic; using Sirenix.OdinInspector; using UnityEngine; // ReSharper disable once CheckNamespace namespace BlueWaterProject { [Serializable] public class Unit { [Tooltip("부대의 이름")] public string unitName; [Tooltip("부대의 종류")] public GlobalValue.UnitType unitType; [Tooltip("부대의 병력 수")] public int soliderCount; [Tooltip("부대 병력 리스트")] public List soldierList; public Unit() { unitName = null; unitType = GlobalValue.UnitType.NONE; soliderCount = 0; soldierList = new List(); } public Unit(string unitName, GlobalValue.UnitType unitType, int soliderCount, List soldierList) { this.unitName = unitName; this.unitType = unitType; this.soliderCount = soliderCount; this.soldierList = new List(this.soliderCount); this.soldierList = soldierList; } } public class UnitController : MonoBehaviour { #region Property and variable [PropertyOrder(-11)] [EnableIf("@attackerType == AttackerType.OFFENSE")] [InlineButton("SetIslandInfoTest", "테스트 설정")] [SerializeField] private IslandInfo attackIslandInfo; [PropertyOrder(-10)] public Unit unit; private bool alwaysFalse; [EnableIf("alwaysFalse")] [EnumToggleButtons] [OnValueChanged("OnTypeChanged")] [SerializeField] private AttackerType attackerType; [ShowIf("attackerType", AttackerType.OFFENSE)] [OnValueChanged("OnTypeChanged")] [SerializeField] private OffenseType offenseType; [ShowIf("attackerType", AttackerType.DEFENSE)] [OnValueChanged("OnTypeChanged")] [SerializeField] private DefenseType defenseType; private bool isClickedTypeAllButton; #endregion #region Unity built-in function private void OnDrawGizmosSelected() { if (unit == null || unit.soliderCount <= 0) return; var unitManager = UnitManager.Inst != null ? UnitManager.Inst : FindObjectOfType(); var matrix = unitManager.UnitMatrices.Find(um => um.soldiers == unit.soliderCount); if (matrix == null) return; for (var i = 0; i < unit.soliderCount; i++) { var row = i / matrix.columns; var column = i % matrix.columns; var xOffset = (column - (matrix.columns - 1) / 2.0f) * unitManager.SoldierSpacing; var zOffset = (row - (matrix.rows - 1) / 2.0f) * unitManager.SoldierSpacing; var spawnPosition = transform.position + new Vector3(xOffset, 0, zOffset); var ray = new Ray(spawnPosition, Vector3.down); Gizmos.color = Physics.Raycast(ray, unitManager.MaxGroundDistance, unitManager.GroundLayer) ? Color.blue : Color.red; Gizmos.DrawRay(ray.origin, ray.direction * unitManager.MaxGroundDistance); } } private void Awake() { SetIslandInfoTest(); } #endregion #region Custom function [PropertyOrder(-9)] [HorizontalGroup("Split", 0.5f)] [GUIColor("GetCreateUnitButtonColor")] [Button("유닛 생성")] public void CreateUnit() { if (!Application.isPlaying) { var unitManager = FindObjectOfType(); unitManager.CreateUnit(this); } else { UnitManager.Inst.CreateUnit(this); } } [PropertyOrder(-8)] [HorizontalGroup("Split", 0.5f)] [EnableIf("CanAssignUnit")] [Button("유닛 배치")] private void SetAssignUnitInScene() { if (UnitManager.Inst.CanAssignUnit(this, transform.position)) { UnitManager.Inst.AssignUnit(this, transform.position); } } private bool CanAssignUnit() { return UnitManager.Inst.CanAssignUnit(this, transform.position); } [PropertyOrder(2)] [Button("테스트 배치")] public void SetAssignUnit(Vector3 assignPos) { if (UnitManager.Inst.CanAssignUnit(this, assignPos)) { UnitManager.Inst.AssignUnit(this, assignPos); } else { print("병력이 땅과 맞닿아 있지 않아 배치할 수 없는 위치입니다."); } } [PropertyOrder(-7)] [EnableIf("@unit.soliderCount > 0 && attackerType != AttackerType.NONE")] [GUIColor(1, 0, 0)] [Button("타입 초기화")] private void ResetTypeAll() { attackerType = AttackerType.NONE; offenseType = OffenseType.NONE; defenseType = DefenseType.NONE; foreach (var soldier in unit.soldierList) { soldier.SetAttackerType(attackerType); soldier.SetOffenseType(offenseType); soldier.SetDefenseType(defenseType); } } [PropertyOrder(1)] [GUIColor("GetTypeAllButtonColor")] [ShowIf("ShowTypeAllButton")] [Button("타입 모두 적용")] private void SetTypeAll() { foreach (var soldier in unit.soldierList) { soldier.SetAttackerType(attackerType); soldier.SetOffenseType(offenseType); soldier.SetDefenseType(defenseType); } isClickedTypeAllButton = true; } public void MoveCommand(Vector3 targetPos) { foreach (var soldier in unit.soldierList) { soldier.MoveTarget(targetPos); } } private void SetIslandInfoTest() { if (attackerType != AttackerType.OFFENSE) return; var islandInfo = FindObjectOfType(); attackIslandInfo = islandInfo; foreach (var soldier in unit.soldierList) { soldier.IslandInfo = attackIslandInfo; } } private bool ShowTypeAllButton() { switch (attackerType) { case AttackerType.NONE: return false; case AttackerType.OFFENSE: if (offenseType == OffenseType.NONE) { return false; } break; case AttackerType.DEFENSE: if (defenseType == DefenseType.NONE) { return false; } break; default: throw new ArgumentOutOfRangeException(); } return true; } private Color GetCreateUnitButtonColor() => unit.soldierList.Count > 0 ? Color.white : Color.green; private Color GetAttackerTypeButtonColor() { if (unit.soldierList.Count > 0) { return attackerType == AttackerType.NONE ? Color.green : Color.white; } return Color.white; } private Color GetTypeAllButtonColor() => isClickedTypeAllButton ? Color.white : Color.green; private void OnTypeChanged() => isClickedTypeAllButton = false; public void SetAttackerType(AttackerType value) => attackerType = value; #endregion } }