2023-08-15 20:36:04 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
2023-08-21 18:08:11 +00:00
|
|
|
using Sirenix.OdinInspector;
|
2023-08-15 20:36:04 +00:00
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
// ReSharper disable once CheckNamespace
|
|
|
|
namespace BlueWaterProject
|
|
|
|
{
|
|
|
|
[Serializable]
|
|
|
|
public class Unit
|
|
|
|
{
|
|
|
|
[Tooltip("부대의 이름")]
|
|
|
|
public string unitName;
|
|
|
|
|
|
|
|
[Tooltip("부대의 종류")]
|
2023-08-16 05:40:33 +00:00
|
|
|
public GlobalValue.UnitType unitType;
|
2023-08-15 20:36:04 +00:00
|
|
|
|
|
|
|
[Tooltip("부대의 병력 수")]
|
|
|
|
public int soliderCount;
|
|
|
|
|
|
|
|
[Tooltip("부대 병력 리스트")]
|
|
|
|
public List<AiController> soldierList;
|
2023-08-22 06:48:37 +00:00
|
|
|
|
2023-08-15 20:36:04 +00:00
|
|
|
public Unit()
|
|
|
|
{
|
|
|
|
unitName = null;
|
2023-08-16 05:40:33 +00:00
|
|
|
unitType = GlobalValue.UnitType.NONE;
|
2023-08-15 20:36:04 +00:00
|
|
|
soliderCount = 0;
|
|
|
|
soldierList = new List<AiController>();
|
|
|
|
}
|
|
|
|
|
2023-08-16 05:40:33 +00:00
|
|
|
public Unit(string unitName, GlobalValue.UnitType unitType, int soliderCount, List<AiController> soldierList)
|
2023-08-15 20:36:04 +00:00
|
|
|
{
|
|
|
|
this.unitName = unitName;
|
|
|
|
this.unitType = unitType;
|
|
|
|
this.soliderCount = soliderCount;
|
|
|
|
|
|
|
|
this.soldierList = new List<AiController>(this.soliderCount);
|
|
|
|
this.soldierList = soldierList;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public class UnitController : MonoBehaviour
|
|
|
|
{
|
2023-08-21 18:08:11 +00:00
|
|
|
#region Property and variable
|
2023-08-17 07:57:46 +00:00
|
|
|
|
2023-08-21 18:08:11 +00:00
|
|
|
[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
|
|
|
|
|
2023-08-15 20:36:04 +00:00
|
|
|
private void OnDrawGizmosSelected()
|
|
|
|
{
|
|
|
|
if (unit == null || unit.soliderCount <= 0) return;
|
|
|
|
|
2023-08-17 07:57:46 +00:00
|
|
|
var unitManager = UnitManager.Inst != null ? UnitManager.Inst : FindObjectOfType<UnitManager>();
|
|
|
|
var matrix = unitManager.UnitMatrices.Find(um => um.soldiers == unit.soliderCount);
|
2023-08-15 20:36:04 +00:00
|
|
|
if (matrix == null) return;
|
|
|
|
|
|
|
|
for (var i = 0; i < unit.soliderCount; i++)
|
|
|
|
{
|
|
|
|
var row = i / matrix.columns;
|
|
|
|
var column = i % matrix.columns;
|
|
|
|
|
2023-08-21 18:08:11 +00:00
|
|
|
var xOffset = (column - (matrix.columns - 1) / 2.0f) * unitManager.SoldierSpacing;
|
|
|
|
var zOffset = (row - (matrix.rows - 1) / 2.0f) * unitManager.SoldierSpacing;
|
2023-08-15 20:36:04 +00:00
|
|
|
var spawnPosition = transform.position + new Vector3(xOffset, 0, zOffset);
|
|
|
|
|
|
|
|
var ray = new Ray(spawnPosition, Vector3.down);
|
2023-08-17 07:57:46 +00:00
|
|
|
Gizmos.color = Physics.Raycast(ray, unitManager.MaxGroundDistance, unitManager.GroundLayer) ? Color.blue : Color.red;
|
|
|
|
Gizmos.DrawRay(ray.origin, ray.direction * unitManager.MaxGroundDistance);
|
2023-08-15 20:36:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-21 18:08:11 +00:00
|
|
|
private void Awake()
|
|
|
|
{
|
|
|
|
SetIslandInfoTest();
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Custom function
|
|
|
|
|
|
|
|
[PropertyOrder(-9)]
|
|
|
|
[HorizontalGroup("Split", 0.5f)]
|
|
|
|
[GUIColor("GetCreateUnitButtonColor")]
|
|
|
|
[Button("유닛 생성")]
|
2023-08-15 20:36:04 +00:00
|
|
|
public void CreateUnit()
|
|
|
|
{
|
|
|
|
if (!Application.isPlaying)
|
|
|
|
{
|
|
|
|
var unitManager = FindObjectOfType<UnitManager>();
|
2023-08-17 07:57:46 +00:00
|
|
|
unitManager.CreateUnit(this);
|
2023-08-22 06:48:37 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
UnitManager.Inst.CreateUnit(this);
|
2023-08-15 20:36:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2023-08-22 06:48:37 +00:00
|
|
|
|
2023-08-21 18:08:11 +00:00
|
|
|
[PropertyOrder(-8)]
|
|
|
|
[HorizontalGroup("Split", 0.5f)]
|
2023-08-22 06:48:37 +00:00
|
|
|
[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)
|
2023-08-21 18:08:11 +00:00
|
|
|
{
|
2023-08-22 06:48:37 +00:00
|
|
|
if (UnitManager.Inst.CanAssignUnit(this, assignPos))
|
2023-08-21 18:08:11 +00:00
|
|
|
{
|
2023-08-22 06:48:37 +00:00
|
|
|
UnitManager.Inst.AssignUnit(this, assignPos);
|
2023-08-21 18:08:11 +00:00
|
|
|
}
|
2023-08-22 06:48:37 +00:00
|
|
|
else
|
2023-08-21 18:08:11 +00:00
|
|
|
{
|
2023-08-22 06:48:37 +00:00
|
|
|
print("병력이 땅과 맞닿아 있지 않아 배치할 수 없는 위치입니다.");
|
2023-08-21 18:08:11 +00:00
|
|
|
}
|
|
|
|
}
|
2023-08-22 06:48:37 +00:00
|
|
|
|
2023-08-21 18:08:11 +00:00
|
|
|
[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;
|
|
|
|
}
|
2023-08-15 20:36:04 +00:00
|
|
|
|
|
|
|
public void MoveCommand(Vector3 targetPos)
|
|
|
|
{
|
|
|
|
foreach (var soldier in unit.soldierList)
|
|
|
|
{
|
2023-08-17 07:57:46 +00:00
|
|
|
soldier.MoveTarget(targetPos);
|
2023-08-15 20:36:04 +00:00
|
|
|
}
|
|
|
|
}
|
2023-08-21 18:08:11 +00:00
|
|
|
|
|
|
|
private void SetIslandInfoTest()
|
|
|
|
{
|
|
|
|
if (attackerType != AttackerType.OFFENSE) return;
|
|
|
|
|
|
|
|
var islandInfo = FindObjectOfType<IslandInfo>();
|
|
|
|
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;
|
2023-08-22 06:48:37 +00:00
|
|
|
public void SetAttackerType(AttackerType value) => attackerType = value;
|
2023-08-21 18:08:11 +00:00
|
|
|
|
|
|
|
#endregion
|
2023-08-15 20:36:04 +00:00
|
|
|
}
|
|
|
|
}
|