#23 디펜스 AI 추가 작업 중

This commit is contained in:
NTG_Lenovo 2023-09-04 16:31:04 +09:00
parent 2f56d399c0
commit 024db4dbd6
24 changed files with 222266 additions and 221518 deletions

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 78c2fa30a3fdda34d8b1ebc3a4dd168b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e7c7d6f5a0b2b8747b46ea19b5b42628
guid: f038612263b8cf24f839928e24e962eb
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 23800000

View File

@ -12,7 +12,7 @@ using Random = UnityEngine.Random;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public enum AiType
public enum EAiType
{
NONE = -1,
PLAYER,
@ -20,24 +20,27 @@ namespace BlueWaterProject
ENEMY
}
public enum AttackerType
public enum EAttackerType
{
NONE = -1,
OFFENSE,
DEFENSE
}
public enum OffenseType
public enum EOffenseType
{
NONE = -1,
NORMAL,
ONLY_HOUSE
}
public enum DefenseType
public enum EDefenseType
{
NONE = -1,
NORMAL
STRIKER,
MIDFIELDER,
DEFENDER,
KEEPER
}
[Serializable]
@ -45,20 +48,6 @@ namespace BlueWaterProject
{
#region Property and variable
[Title("AiType")]
[EnableIf("alwaysFalse")]
[EnumToggleButtons]
[SerializeField] protected AttackerType attackerType;
private bool alwaysFalse;
[EnableIf("alwaysFalse")]
[ShowIf("attackerType", AttackerType.OFFENSE)]
[SerializeField] private OffenseType offenseType;
[EnableIf("alwaysFalse")]
[ShowIf("attackerType", AttackerType.DEFENSE)]
[SerializeField] private DefenseType defenseType;
[Title("Skin")]
[Tooltip("SkinnedMeshRenderer, MeshRenderer의 Material을 모두 담고 있는 리스트")]
[SerializeField] protected List<Material> skinMaterialList = new(10);
@ -76,6 +65,7 @@ namespace BlueWaterProject
[SerializeField] private IslandInfo islandInfo;
protected bool isAttacking;
private Vector3 defensePos;
protected Transform backpackContainer;
protected Transform leftWeaponContainer;
@ -147,7 +137,7 @@ namespace BlueWaterProject
private void OnMouseEnter()
{
if (AiStat.AiType == AiType.ENEMY) return;
if (AiStat.AiType == EAiType.ENEMY) return;
mouseEnterUnitController = gameObject.GetComponentInParent<UnitController>();
@ -161,7 +151,7 @@ namespace BlueWaterProject
private void OnMouseExit()
{
if (AiStat.AiType == AiType.ENEMY ||
if (AiStat.AiType == EAiType.ENEMY ||
!mouseEnterUnitController || mouseEnterUnitController == unitSelection.SelectedUnitController) return;
foreach (var unit in mouseEnterUnitController.unit.UnitList)
@ -187,9 +177,9 @@ namespace BlueWaterProject
public void TakeDamage(float attackerPower, float attackerShieldPenetrationRate, Vector3? attackPos = null)
{
if (!TargetTransform && attackPos != null)
if (attackPos != null && AiStat.AttackerType == EAttackerType.DEFENSE && !TargetTransform)
{
//BeAttackedMovement((Vector3)attackPos);
BeAttackedMovement((Vector3)attackPos);
}
// 회피 성공 체크
@ -243,12 +233,8 @@ namespace BlueWaterProject
[field: SerializeField] public LayerMask TargetLayer { get; set; }
[field: SerializeField] public float ViewRadius { get; set; }
[field: SerializeField] public Collider[] ColliderWithinRange { get; set; } = new Collider[TARGET_MAX_SIZE];
[field: SerializeField] public IAiStat IaiStat { get; set; }
[field: SerializeField] public Transform TargetTransform { get; set; }
@ -261,28 +247,138 @@ namespace BlueWaterProject
var myPos = transform.position;
Gizmos.color = Color.green;
Gizmos.DrawWireSphere(myPos, ViewRadius);
Gizmos.DrawWireSphere(myPos, AiStat.ViewRange);
Gizmos.color = Color.blue;
Gizmos.DrawWireSphere(myPos, AiStat.DefenseRange);
if (!TargetTransform) return;
Debug.DrawLine(myPos, TargetTransform.position, Color.red);
}
public IEnumerator FindTarget()
public IEnumerator FindTargetInOffense()
{
while (true)
{
switch (AiStat.OffenseType)
{
case EOffenseType.NONE:
print("AiStat.OffenseType == NONE Error");
break;
case EOffenseType.NORMAL:
if (islandInfo.EnemyList.Count > 0)
{
SetNearestTargetInOffense(islandInfo.EnemyList);
}
else if (islandInfo.HouseList.Count > 0)
{
SetNearestTargetInOffense(islandInfo.HouseList);
}
break;
case EOffenseType.ONLY_HOUSE:
if (navMeshAgent.pathStatus == NavMeshPathStatus.PathPartial)
{
SetNearestTargetInOffense(islandInfo.TargetAllList);
}
else
{
if (islandInfo.HouseList.Count > 0)
{
SetNearestTargetInOffense(islandInfo.HouseList);
}
else if (islandInfo.EnemyList.Count > 0)
{
SetNearestTargetInOffense(islandInfo.EnemyList);
}
}
break;
default:
throw new ArgumentOutOfRangeException();
}
yield return FindTargetWaitTime;
}
}
public IEnumerator FindTargetInDefense()
{
while (true)
{
switch (AiStat.DefenseType)
{
case EDefenseType.NONE:
print("AiStat.DefenseType == NONE Error");
break;
case EDefenseType.STRIKER:
SetNearestTargetInDefense(transform.position, AiStat.ViewRange);
if (TargetTransform)
{
Utils.SetCloseDestination(navMeshAgent, TargetTransform.position, AiStat.AtkRange - 0.5f, AiStat.AtkRange);
}
break;
case EDefenseType.MIDFIELDER:
SetNearestTargetInDefense(transform.position, AiStat.ViewRange);
if (TargetTransform)
{
Utils.SetCloseDestination(navMeshAgent, TargetTransform.position, AiStat.AtkRange - 0.5f, AiStat.AtkRange);
}
break;
case EDefenseType.DEFENDER:
SetNearestTargetInDefense(defensePos, AiStat.DefenseRange);
if (TargetTransform)
{
Utils.SetCloseDestination(navMeshAgent, TargetTransform.position, AiStat.AtkRange - 0.5f, AiStat.AtkRange);
}
break;
case EDefenseType.KEEPER:
SetNearestTargetInDefense(transform.position, AiStat.ViewRange);
break;
default:
throw new ArgumentOutOfRangeException();
}
yield return FindTargetWaitTime;
}
}
public void SetNearestTargetInOffense<T>(List<T> targetList)
{
if (targetList.Count <= 0) return;
var nearestTarget = targetList.OrderBy(t =>
{
var myPos = transform.position;
var targetTransform = (Transform)(object)t;
var targetCollider = targetTransform.GetComponent<Collider>();
if (!targetCollider)
{
return float.MaxValue;
}
var closestPoint = targetCollider.ClosestPoint(myPos);
return Vector3.Distance(myPos, closestPoint);
})
.FirstOrDefault();
if (nearestTarget == null) return;
TargetTransform = (Transform)(object)nearestTarget;
Utils.SetCloseDestination(navMeshAgent, TargetTransform.position, AiStat.AtkRange - 0.5f, AiStat.AtkRange);
}
public void SetNearestTargetInDefense(Vector3 centerPos, float range)
{
Array.Clear(ColliderWithinRange, 0, TARGET_MAX_SIZE);
var myPos = transform.position;
var maxColliderCount = Physics.OverlapSphereNonAlloc(myPos, ViewRadius, ColliderWithinRange,
var maxColliderCount = Physics.OverlapSphereNonAlloc(centerPos, range, ColliderWithinRange,
TargetLayer, QueryTriggerInteraction.Collide);
if (maxColliderCount <= 0)
{
TargetTransform = null;
yield return FindTargetWaitTime;
continue;
return;
}
var nearestDistance = Mathf.Infinity;
@ -299,83 +395,6 @@ namespace BlueWaterProject
}
TargetTransform = nearestTargetTransform;
yield return FindTargetWaitTime;
}
}
public IEnumerator FindTargetInOffense()
{
while (true)
{
if (CanAttack())
{
yield return FindTargetWaitTime;
continue;
}
switch (offenseType)
{
case OffenseType.NONE:
break;
case OffenseType.NORMAL:
if (islandInfo.EnemyList.Count > 0)
{
SetNearestTargetDestination(islandInfo.EnemyList);
}
else if (islandInfo.HouseList.Count > 0)
{
SetNearestTargetDestination(islandInfo.HouseList);
}
break;
case OffenseType.ONLY_HOUSE:
if (navMeshAgent.pathStatus == NavMeshPathStatus.PathPartial)
{
SetNearestTargetDestination(islandInfo.TargetAllList);
}
else
{
if (islandInfo.HouseList.Count > 0)
{
SetNearestTargetDestination(islandInfo.HouseList);
}
else if (islandInfo.EnemyList.Count > 0)
{
SetNearestTargetDestination(islandInfo.EnemyList);
}
}
break;
default:
throw new ArgumentOutOfRangeException();
}
yield return FindTargetWaitTime;
}
}
public void SetNearestTargetDestination<T>(List<T> targetList)
{
if (targetList.Count <= 0) return;
var nearestTarget = targetList.OrderBy(t =>
{
var targetTransform = (Transform)(object)t;
var targetCollider = targetTransform.GetComponent<Collider>();
if (!targetCollider)
{
return float.MaxValue;
}
var closestPoint = targetCollider.ClosestPoint(transform.position);
return Vector3.Distance(transform.position, closestPoint);
})
.FirstOrDefault();
if (nearestTarget == null) return;
TargetTransform = (Transform)(object)nearestTarget;
navMeshAgent.SetDestination(TargetTransform.position);
}
public virtual void UpdateLookAtTarget()
@ -400,28 +419,29 @@ namespace BlueWaterProject
[field: Space(10f)]
[field: Title("AiMover")]
[field: SerializeField] public MoveType AttackMoveType { get; set; }
[field: SerializeField] public MoveType BeAttackedMoveType { get; set; }
[field: SerializeField] public bool IsCommanded { get; set; }
public void BeAttackedMovement(Vector3 attackPos)
{
if (TargetTransform) return;
switch (BeAttackedMoveType)
switch (AiStat.DefenseType)
{
case MoveType.NONE:
case EDefenseType.NONE:
print("AiStat.DefenseType == NONE Error");
break;
case MoveType.FIXED:
case EDefenseType.STRIKER:
Utils.SetCloseDestination(navMeshAgent, TargetTransform.position, AiStat.AtkRange - 0.5f, AiStat.AtkRange);
break;
case MoveType.MOVE:
if (Vector3.Distance(transform.position, attackPos) > AiStat.AtkRange)
case EDefenseType.MIDFIELDER:
Utils.SetCloseDestination(navMeshAgent, TargetTransform.position, AiStat.AtkRange - 0.5f, AiStat.AtkRange);
break;
case EDefenseType.DEFENDER:
if (Vector3.Distance(transform.position, attackPos) <= AiStat.DefenseRange)
{
myUnitController.MoveCommand(attackPos);
Utils.SetCloseDestination(navMeshAgent, TargetTransform.position, AiStat.AtkRange - 0.5f, AiStat.AtkRange);
}
break;
case EDefenseType.KEEPER:
break;
default:
throw new ArgumentOutOfRangeException();
}
@ -481,12 +501,18 @@ namespace BlueWaterProject
myCollider = Utils.GetComponentAndAssert<CapsuleCollider>(transform);
lookAtConstraint = Utils.GetComponentAndAssert<LookAtConstraint>(flagContainer);
hitBoxCollider = Utils.GetComponentAndAssert<CapsuleCollider>(transform.Find("HitBox"));
unitSelection = FindObjectOfType<UnitSelection>();
unitSelection = Utils.GetComponentAndAssert<UnitSelection>(UnitManager.Inst.transform);
var source = new ConstraintSource();
source.sourceTransform = Camera.main.transform;
source.weight = 1f;
if (Camera.main != null)
{
var source = new ConstraintSource
{
sourceTransform = Camera.main.transform,
weight = 1f
};
lookAtConstraint.AddSource(source);
}
lookAtConstraint.constraintActive = true;
}
@ -497,6 +523,8 @@ namespace BlueWaterProject
SetLayer();
SetCurrentHp(AiStat.MaxHp);
SetMoveSpeed(AiStat.MoveSpd);
defensePos = transform.position;
}
private void InitViewModel()
@ -513,7 +541,7 @@ namespace BlueWaterProject
closeWeapon = rightWeaponContainer.GetChild(DataManager.Inst.GetAiViewDictionaryKey(AiStat.ViewIdx).RightWeapon).AddComponent<CloseWeapon>();
closeWeapon.gameObject.layer = LayerMask.NameToLayer("Weapon");
closeWeapon.SetAttackerType(attackerType);
closeWeapon.SetAttackerType(AiStat.AttackerType);
}
#if UNITY_EDITOR
@ -540,21 +568,22 @@ namespace BlueWaterProject
closeWeapon = rightWeaponContainer.GetChild(DataManager.Inst.GetAiViewSoKey(AiStat.ViewIdx).RightWeapon).AddComponent<CloseWeapon>();
closeWeapon.gameObject.layer = LayerMask.NameToLayer("Weapon");
closeWeapon.SetAttackerType(attackerType);
closeWeapon.SetAttackerType(AiStat.AttackerType);
}
#endif
public void ExecuteFindTarget()
{
switch (attackerType)
switch (AiStat.AttackerType)
{
case AttackerType.NONE:
case EAttackerType.NONE:
print("AiStat.AttackerType == NONE Error");
break;
case AttackerType.OFFENSE:
case EAttackerType.OFFENSE:
StartCoroutine(nameof(FindTargetInOffense));
break;
case AttackerType.DEFENSE:
StartCoroutine(nameof(FindTarget));
case EAttackerType.DEFENSE:
StartCoroutine(nameof(FindTargetInDefense));
break;
default:
throw new ArgumentOutOfRangeException();
@ -604,11 +633,25 @@ namespace BlueWaterProject
yield return new WaitForSeconds(AiStat.AtkCooldown);
}
// ReSharper disable once IteratorNeverReturns
}
protected virtual bool CanAttack()
{
switch (AiStat.AttackerType)
{
case EAttackerType.NONE:
print("AiStat.AttackerType == NONE Error");
return false;
case EAttackerType.OFFENSE:
if (!TargetTransform || !islandInfo.TargetAllList.Contains(TargetTransform)) return false;
break;
case EAttackerType.DEFENSE:
if (!TargetTransform) return false;
break;
default:
throw new ArgumentOutOfRangeException();
}
var targetInAttackRange = Vector3.Distance(transform.position, TargetTransform.position) <=
AiStat.AtkRange;
@ -670,32 +713,41 @@ namespace BlueWaterProject
{
switch (AiStat.AiType)
{
case AiType.NONE:
case EAiType.NONE:
print("AiStat.AiType == NONE Error");
break;
case AiType.PLAYER:
case EAiType.PLAYER:
gameObject.layer = LayerMask.NameToLayer("Player");
hitBoxCollider.gameObject.layer = LayerMask.NameToLayer("Player");
hitBoxCollider.gameObject.tag = "Player";
TargetLayer = LayerMask.GetMask("Enemy");
break;
case AiType.PIRATE:
case EAiType.PIRATE:
gameObject.layer = LayerMask.NameToLayer("Pirate");
hitBoxCollider.gameObject.layer = LayerMask.NameToLayer("Pirate");
hitBoxCollider.gameObject.tag = "Pirate";
TargetLayer = LayerMask.GetMask("Enemy");
break;
case AiType.ENEMY:
case EAiType.ENEMY:
gameObject.layer = LayerMask.NameToLayer("Enemy");
hitBoxCollider.gameObject.layer = LayerMask.NameToLayer("Enemy");
TargetLayer = LayerMask.GetMask("Player") | LayerMask.GetMask("Pirate") | LayerMask.GetMask("Props");
hitBoxCollider.gameObject.tag = "Enemy";
TargetLayer = LayerMask.GetMask("Player") | LayerMask.GetMask("Pirate");
break;
default:
throw new ArgumentOutOfRangeException();
}
if (AiStat.AttackerType == EAttackerType.OFFENSE)
{
TargetLayer |= LayerMask.GetMask("Props");
}
}
public void SetIslandInfo(IslandInfo info) => islandInfo = info;
public void SetAttackerType(AttackerType type) => attackerType = type;
public void SetOffenseType(OffenseType type) => offenseType = type;
public void SetDefenseType(DefenseType type) => defenseType = type;
public void SetAttackerType(EAttackerType type) => AiStat.AttackerType = type;
public void SetOffenseType(EOffenseType type) => AiStat.OffenseType = type;
public void SetDefenseType(EDefenseType type) => AiStat.DefenseType = type;
public void ResetHighlight() => SetOutlineColor(defaultSkinColor);
public void MouseEnterHighlight() => SetOutlineColor(mouseEnterHighlightSkinColor);
public void SelectedHighlight() => SetOutlineColor(selectedSkinColor);

View File

@ -16,9 +16,24 @@ namespace BlueWaterProject
[field: Tooltip("캐릭터 모델 인덱스")]
[field: SerializeField] public string ViewIdx { get; set; }
[field: Tooltip("Ai 종류")]
[field: SerializeField] public GlobalValue.UnitType UnitType { get; set; }
[field: Tooltip("Ai 종류")]
[field: EnumToggleButtons]
[field: SerializeField] public AiType AiType { get; set; }
[field: SerializeField] public EAiType AiType { get; set; }
[field: Tooltip("공격방식 종류")]
[field: DisableIf("@true")]
[field: SerializeField] public EAttackerType AttackerType { get; set; }
[field: Tooltip("공격 종류")]
[field: DisableIf("@true")]
[field: SerializeField] public EOffenseType OffenseType { get; set; }
[field: Tooltip("방어 종류")]
[field: DisableIf("@true")]
[field: SerializeField] public EDefenseType DefenseType { get; set; }
[field: Tooltip("캐릭터 최대 체력")]
[field: SerializeField] public float MaxHp { get; set; }
@ -38,9 +53,15 @@ namespace BlueWaterProject
[field: Tooltip("공격속도(다음 공격 주기)")]
[field: SerializeField] public float AtkCooldown { get; set; }
[field: Tooltip("시야 사거리")]
[field: SerializeField] public float ViewRange { get; set; }
[field: Tooltip("공격 사거리")]
[field: SerializeField] public float AtkRange { get; set; }
[field: Tooltip("수비 사거리")]
[field: SerializeField] public float DefenseRange { get; set; }
[field: Tooltip("방패 캐릭터를 공격했을 때, 방패 관통률")]
[field: Range(0, 100)]
[field: SerializeField] public int ShieldPenetrationRate { get; set; }
@ -76,14 +97,20 @@ namespace BlueWaterProject
{
Idx = null;
ViewIdx = null;
AiType = AiType.NONE;
UnitType = GlobalValue.UnitType.NONE;
AiType = EAiType.NONE;
AttackerType = EAttackerType.NONE;
OffenseType = EOffenseType.NONE;
DefenseType = EDefenseType.NONE;
MaxHp = 0f;
CurrentHp = 0f;
Atk = 0f;
Def = 0f;
MoveSpd = 0f;
AtkCooldown = 0f;
ViewRange = 0f;
AtkRange = 0f;
DefenseRange = 0f;
ShieldPenetrationRate = 0;
AvoidanceRate = 0;
UsingShield = false;
@ -95,12 +122,13 @@ namespace BlueWaterProject
/// <summary>
/// 일반 생성자
/// </summary>
public AiStat(string idx, string viewIdx, AiType aiType, float maxHp, float currentHp, float atk, float def,
float moveSpd, float atkCooldown, float atkRange, int shieldPenetrationRate, int avoidanceRate,
public AiStat(string idx, string viewIdx, GlobalValue.UnitType unitType, EAiType aiType, float maxHp, float currentHp, float atk, float def,
float moveSpd, float atkCooldown, float viewRange, float atkRange, float defenseRange, int shieldPenetrationRate, int avoidanceRate,
bool usingShield, int penetrationResistivity, bool usingBow, float inaccuracy)
{
Idx = idx;
ViewIdx = viewIdx;
UnitType = unitType;
AiType = aiType;
MaxHp = maxHp;
CurrentHp = currentHp;
@ -108,7 +136,9 @@ namespace BlueWaterProject
Def = def;
MoveSpd = moveSpd;
AtkCooldown = atkCooldown;
ViewRange = viewRange;
AtkRange = atkRange;
DefenseRange = defenseRange;
ShieldPenetrationRate = shieldPenetrationRate;
AvoidanceRate = avoidanceRate;
UsingShield = usingShield;
@ -124,14 +154,20 @@ namespace BlueWaterProject
{
Idx = aiStat.Idx;
ViewIdx = aiStat.ViewIdx;
UnitType = aiStat.UnitType;
AiType = aiStat.AiType;
AttackerType = aiStat.AttackerType;
OffenseType = aiStat.OffenseType;
DefenseType = aiStat.DefenseType;
MaxHp = aiStat.MaxHp;
CurrentHp = aiStat.CurrentHp;
Atk = aiStat.Atk;
Def = aiStat.Def;
MoveSpd = aiStat.MoveSpd;
AtkCooldown = aiStat.AtkCooldown;
ViewRange = aiStat.ViewRange;
AtkRange = aiStat.AtkRange;
DefenseRange = aiStat.DefenseRange;
ShieldPenetrationRate = aiStat.ShieldPenetrationRate;
AvoidanceRate = aiStat.AvoidanceRate;
UsingShield = aiStat.UsingShield;

View File

@ -17,10 +17,6 @@ namespace BlueWaterProject
[Tooltip("화살 발사 후 오브젝트 저장될 위치")]
[SerializeField] private Transform arrowsPoolLocation;
[Tooltip("화살이 타겟에 도달하는 오차 범위(부정확함)")]
[Range(0f, 2f)]
[SerializeField] private float inaccuracy;
[SerializeField] private LayerMask archerLayer;
private IEnumerator shootArrowCoroutine;
@ -37,9 +33,12 @@ namespace BlueWaterProject
{
if (!IsDrawGizmosInFieldOfView) return;
var myPos = transform.position;
Gizmos.color = Color.green;
Gizmos.DrawWireSphere(myPos, AiStat.ViewRange);
if (!CanAttack()) return;
var myPos = transform.position;
var targetPos = TargetTransform.position;
var direction = ((targetPos + rayOffset) - (myPos + rayOffset)).normalized;
@ -77,32 +76,40 @@ namespace BlueWaterProject
{
switch (AiStat.AiType)
{
case AiType.NONE:
case EAiType.NONE:
break;
case AiType.PLAYER:
case EAiType.PLAYER:
gameObject.layer = LayerMask.NameToLayer("Player");
hitBoxCollider.gameObject.layer = LayerMask.NameToLayer("Player");
hitBoxCollider.gameObject.tag = "Player";
TargetLayer = LayerMask.GetMask("Enemy");
archerLayer = LayerMask.GetMask("Ground") | LayerMask.GetMask("Water") |
LayerMask.GetMask("Enemy") | LayerMask.GetMask("Props");
LayerMask.GetMask("Enemy");
break;
case AiType.PIRATE:
case EAiType.PIRATE:
gameObject.layer = LayerMask.NameToLayer("Pirate");
hitBoxCollider.gameObject.layer = LayerMask.NameToLayer("Pirate");
hitBoxCollider.gameObject.tag = "Pirate";
TargetLayer = LayerMask.GetMask("Enemy");
archerLayer = LayerMask.GetMask("Ground") | LayerMask.GetMask("Water") |
LayerMask.GetMask("Enemy") | LayerMask.GetMask("Props");
LayerMask.GetMask("Enemy");
break;
case AiType.ENEMY:
case EAiType.ENEMY:
gameObject.layer = LayerMask.NameToLayer("Enemy");
hitBoxCollider.gameObject.layer = LayerMask.NameToLayer("Enemy");
TargetLayer = LayerMask.GetMask("Player") | LayerMask.GetMask("Pirate") | LayerMask.GetMask("Props");
hitBoxCollider.gameObject.tag = "Enemy";
TargetLayer = LayerMask.GetMask("Player") | LayerMask.GetMask("Pirate");
archerLayer = LayerMask.GetMask("Ground") | LayerMask.GetMask("Water") |
LayerMask.GetMask("Player") | LayerMask.GetMask("Pirate") | LayerMask.GetMask("Props");
LayerMask.GetMask("Player") | LayerMask.GetMask("Pirate");
break;
default:
throw new ArgumentOutOfRangeException();
}
if (AiStat.AttackerType == EAttackerType.OFFENSE)
{
TargetLayer |= LayerMask.GetMask("Props");
}
}
public override void UpdateLookAtTarget()
@ -169,8 +176,9 @@ namespace BlueWaterProject
public void OnShootArrow()
{
var arrow = arrowPool.Get();
var isOffense = AiStat.AttackerType == EAttackerType.OFFENSE;
arrow.SetShootingArrow(leftWeaponContainer.position, transform.position,
TargetTransform.position + rayOffset, AiStat, attackerType, inaccuracy);
TargetTransform.position + rayOffset, AiStat, AiStat.AiType, AiStat.Inaccuracy, isOffense);
arrow.ShootArrowCoroutine();
}
@ -179,19 +187,7 @@ namespace BlueWaterProject
/// </summary>
public void OnStoppedMove(int boolValue)
{
switch (AttackMoveType)
{
case MoveType.NONE:
break;
case MoveType.FIXED:
navMeshAgent.isStopped = true;
break;
case MoveType.MOVE:
navMeshAgent.isStopped = boolValue == 1;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
#endregion

View File

@ -24,17 +24,22 @@ namespace BlueWaterProject
[field: SerializeField] public string UnitName { get; set; }
[field: Tooltip("부대의 종류")]
[field: DisableIf("@true")]
[field: SerializeField] public GlobalValue.UnitType UnitType { get; set; }
[field: Tooltip("선원의 수")]
[field: Range(0, GlobalValue.ONE_UNIT_CAPACITY - 1)]
[field: SerializeField] public int SailorCount { get; set; }
[field: SerializeField] public AttackerType AttackerType { get; set; }
[field: EnumToggleButtons]
[field: DisableIf("@UnitType.ToString().Contains(\"_P\")")]
[field: SerializeField] public EAttackerType AttackerType { get; set; }
[field: SerializeField] public OffenseType OffenseType { get; set; }
[field: EnumToggleButtons]
[field: SerializeField] public EOffenseType OffenseType { get; set; }
[field: SerializeField] public DefenseType DefenseType { get; set; }
[field: EnumToggleButtons]
[field: SerializeField] public EDefenseType DefenseType { get; set; }
[field: Tooltip("부대 병력 리스트")]
[field: SerializeField] public List<AiController> UnitList { get; set; }
@ -51,27 +56,30 @@ namespace BlueWaterProject
UnitName = null;
UnitType = GlobalValue.UnitType.NONE;
SailorCount = 0;
AttackerType = AttackerType.NONE;
OffenseType = OffenseType.NONE;
DefenseType = DefenseType.NONE;
AttackerType = EAttackerType.NONE;
OffenseType = EOffenseType.NONE;
DefenseType = EDefenseType.NONE;
UnitList = new List<AiController>(GlobalValue.ONE_UNIT_CAPACITY);
}
public Unit(string idx, string captainIdx, string sailorIdx, string unitName, GlobalValue.UnitType unitType,
int sailorCount, AttackerType attackerType, OffenseType offenseType, DefenseType defenseType, List<AiController> unitList)
public Unit(string idx, string captainIdx, string sailorIdx, string unitName,
int sailorCount, EAttackerType attackerType, EOffenseType offenseType, EDefenseType defenseType, List<AiController> unitList)
{
Idx = idx;
CaptainStatIdx = captainIdx;
SailorStatIdx = sailorIdx;
UnitName = unitName;
UnitType = unitType;
SailorCount = sailorCount;
AttackerType = attackerType;
OffenseType = offenseType;
DefenseType = defenseType;
UnitList = unitList;
//SetAttackerTypeUnitAll();
UnitType = Application.isPlaying ? DataManager.Inst.GetAiStatDictionaryKey(CaptainStatIdx).UnitType :
DataManager.Inst.GetAiStatSoKey(CaptainStatIdx).UnitType;
if (AttackerType == EAttackerType.NONE) return;
AttackerType = attackerType;
}
public Unit(Unit unit)
@ -80,31 +88,16 @@ namespace BlueWaterProject
CaptainStatIdx = unit.CaptainStatIdx;
SailorStatIdx = unit.SailorStatIdx;
UnitName = unit.UnitName;
UnitType = unit.UnitType;
SailorCount = unit.SailorCount;
AttackerType = unit.AttackerType;
OffenseType = unit.OffenseType;
DefenseType = unit.DefenseType;
UnitList = unit.UnitList;
//SetAttackerTypeUnitAll();
UnitType = Application.isPlaying ? DataManager.Inst.GetAiStatDictionaryKey(CaptainStatIdx).UnitType :
DataManager.Inst.GetAiStatSoKey(CaptainStatIdx).UnitType;
}
#endregion
#region Custrom method
// private void SetAttackerTypeUnitAll()
// {
// foreach (var item in UnitList)
// {
// item.SetAttackerType(AttackerType);
// }
// }
public void SetOffenseType(OffenseType type) => OffenseType = type;
public void SetDefenseType(DefenseType type) => DefenseType = type;
#endregion
}
}

View File

@ -89,7 +89,7 @@ namespace BlueWaterProject
{
if (UnitManager.Inst.CanAssignUnit(this, transform.position))
{
UnitManager.Inst.AssignUnit(this, transform.position);
UnitManager.Inst.AssignUnit(this, transform.position, false);
}
}
@ -104,7 +104,7 @@ namespace BlueWaterProject
{
if (UnitManager.Inst.CanAssignUnit(this, assignPos))
{
UnitManager.Inst.AssignUnit(this, assignPos);
UnitManager.Inst.AssignUnit(this, assignPos, false);
}
else
{

View File

@ -218,14 +218,14 @@ namespace BlueWaterProject
public void CreateAndAssign(string cardIdx, Vector3 assignPos)
{
var newUnitController = CreateUnit(cardIdx, AttackerType.OFFENSE);
AssignUnit(newUnitController, assignPos);
var newUnitController = CreateUnit(cardIdx, EAttackerType.OFFENSE);
AssignUnit(newUnitController, assignPos, true);
}
/// <summary>
/// 동적 생성용 부대 생성 함수
/// </summary>
public UnitController CreateUnit(string cardIdx, AttackerType attackerType)
public UnitController CreateUnit(string cardIdx, EAttackerType attackerType)
{
var card = DataManager.Inst.GetCardDictionaryFromKey(cardIdx);
var unit = DataManager.Inst.GetUnitDictionaryKey(card.UnitIdx);
@ -294,6 +294,8 @@ namespace BlueWaterProject
var aiController = GetAiController(baseObj, newUnitController.unit.UnitType, currentPos == heroPosition ? captainStat : sailorStat);
aiController.SetAttackerType(attackerType);
aiController.SetOffenseType(newUnitController.unit.OffenseType);
aiController.SetDefenseType(newUnitController.unit.DefenseType);
newUnitController.unit.UnitList.Add(aiController);
}
}
@ -373,6 +375,8 @@ namespace BlueWaterProject
var aiController = GetAiController(baseObj, unitController.unit.UnitType, currentPos == heroPosition ? captainStat : sailorStat);
aiController.SetAttackerType(unitController.unit.AttackerType);
aiController.SetOffenseType(unitController.unit.OffenseType);
aiController.SetDefenseType(unitController.unit.DefenseType);
aiController.InitStartInEditor();
unitController.unit.UnitList.Add(aiController);
}
@ -453,21 +457,33 @@ namespace BlueWaterProject
return true;
}
public void AssignUnit(UnitController unitController, Vector3 assignPos)
public void AssignUnit(UnitController unitController, Vector3 assignPos, bool isOffense)
{
unitController.transform.position = assignPos;
foreach (var item in unitController.unit.UnitList)
IslandInfo hitIslandInfo = null;
foreach (var unit in unitController.unit.UnitList)
{
var myPos = item.transform.position;
var myPos = unit.transform.position;
var ray = new Ray(myPos + Vector3.up, Vector3.down);
if (Physics.Raycast(ray, out var hit, MaxGroundDistance, GroundLayer))
{
item.transform.position = new Vector3(myPos.x, hit.point.y, myPos.z);
var hitIslandInfo = hit.transform.root.GetComponent<IslandInfo>();
item.SetIslandInfo(hitIslandInfo);
unit.transform.position = new Vector3(myPos.x, hit.point.y, myPos.z);
if (isOffense && hitIslandInfo == null)
{
hitIslandInfo = hit.transform.root.GetComponent<IslandInfo>();
}
item.SetAttackerType(unitController.unit.AttackerType);
item.gameObject.SetActive(true);
}
}
foreach (var unit in unitController.unit.UnitList)
{
if (isOffense)
{
unit.SetIslandInfo(hitIslandInfo);
}
unit.gameObject.SetActive(true);
}
}

View File

@ -39,7 +39,8 @@ namespace BlueWaterProject
public void CardInit()
{
var cardInfo = DataManager.Inst.GetUnitDictionaryKey(card.UnitIdx);
typeImage.sprite = DataManager.Inst.cardType[(int)cardInfo.UnitType];
var captainStat = DataManager.Inst.GetAiStatDictionaryKey(cardInfo.CaptainStatIdx);
typeImage.sprite = DataManager.Inst.cardType[(int)captainStat.UnitType];
}
public void OnPointerDown(PointerEventData eventData)

View File

@ -15,30 +15,42 @@ MonoBehaviour:
aiStatDataList:
- <Idx>k__BackingField: ai_stat_sailor_e_001
<ViewIdx>k__BackingField: ai_view_sailor_e_001
<UnitType>k__BackingField: 0
<AiType>k__BackingField: 2
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 30
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 50
<Def>k__BackingField: 0
<MoveSpd>k__BackingField: 5
<AtkCooldown>k__BackingField: 3
<AtkRange>k__BackingField: 15
<ViewRange>k__BackingField: 40
<AtkRange>k__BackingField: 40
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 25
<AvoidanceRate>k__BackingField: 20
<UsingShield>k__BackingField: 0
<PenetrationResistivity>k__BackingField: 0
<UsingBow>k__BackingField: 1
<Inaccuracy>k__BackingField: 0.5
<Inaccuracy>k__BackingField: 1
- <Idx>k__BackingField: ai_stat_sailor_e_002
<ViewIdx>k__BackingField: ai_view_sailor_e_002
<UnitType>k__BackingField: 1
<AiType>k__BackingField: 2
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 60
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 40
<Def>k__BackingField: 10
<MoveSpd>k__BackingField: 4.5
<AtkCooldown>k__BackingField: 2
<AtkRange>k__BackingField: 1.5
<ViewRange>k__BackingField: 10
<AtkRange>k__BackingField: 2
<DefenseRange>k__BackingField: 10
<ShieldPenetrationRate>k__BackingField: 75
<AvoidanceRate>k__BackingField: 10
<UsingShield>k__BackingField: 1
@ -47,14 +59,20 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_sailor_e_003
<ViewIdx>k__BackingField: ai_view_sailor_e_003
<UnitType>k__BackingField: 2
<AiType>k__BackingField: 2
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 40
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 50
<Def>k__BackingField: 5
<MoveSpd>k__BackingField: 5.5
<AtkCooldown>k__BackingField: 2
<AtkRange>k__BackingField: 1.5
<ViewRange>k__BackingField: 15
<AtkRange>k__BackingField: 2
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 75
<AvoidanceRate>k__BackingField: 20
<UsingShield>k__BackingField: 0
@ -63,14 +81,20 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_sailor_e_004
<ViewIdx>k__BackingField: ai_view_sailor_e_004
<UnitType>k__BackingField: 3
<AiType>k__BackingField: 2
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 60
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 30
<Def>k__BackingField: 10
<MoveSpd>k__BackingField: 5
<AtkCooldown>k__BackingField: 1.5
<AtkRange>k__BackingField: 1
<ViewRange>k__BackingField: 10
<AtkRange>k__BackingField: 1.5
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 50
<AvoidanceRate>k__BackingField: 10
<UsingShield>k__BackingField: 1
@ -79,14 +103,20 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_sailor_e_005
<ViewIdx>k__BackingField: ai_view_sailor_e_005
<UnitType>k__BackingField: 4
<AiType>k__BackingField: 2
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 45
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 35
<Def>k__BackingField: 5
<MoveSpd>k__BackingField: 6
<AtkCooldown>k__BackingField: 1.5
<AtkRange>k__BackingField: 1
<ViewRange>k__BackingField: 15
<AtkRange>k__BackingField: 1.5
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 50
<AvoidanceRate>k__BackingField: 30
<UsingShield>k__BackingField: 0
@ -95,30 +125,42 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_sailor_p_001
<ViewIdx>k__BackingField: ai_view_sailor_p_001
<UnitType>k__BackingField: 5
<AiType>k__BackingField: 1
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 30
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 50
<Def>k__BackingField: 0
<MoveSpd>k__BackingField: 5
<AtkCooldown>k__BackingField: 3
<AtkRange>k__BackingField: 15
<ViewRange>k__BackingField: 40
<AtkRange>k__BackingField: 40
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 25
<AvoidanceRate>k__BackingField: 20
<UsingShield>k__BackingField: 0
<PenetrationResistivity>k__BackingField: 0
<UsingBow>k__BackingField: 1
<Inaccuracy>k__BackingField: 0.5
<Inaccuracy>k__BackingField: 1
- <Idx>k__BackingField: ai_stat_sailor_p_002
<ViewIdx>k__BackingField: ai_view_sailor_p_002
<UnitType>k__BackingField: 6
<AiType>k__BackingField: 1
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 50
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 50
<Def>k__BackingField: 0
<MoveSpd>k__BackingField: 5
<AtkCooldown>k__BackingField: 2.5
<AtkRange>k__BackingField: 1.5
<ViewRange>k__BackingField: 15
<AtkRange>k__BackingField: 2
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 100
<AvoidanceRate>k__BackingField: 10
<UsingShield>k__BackingField: 0
@ -127,14 +169,20 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_sailor_p_003
<ViewIdx>k__BackingField: ai_view_sailor_p_003
<UnitType>k__BackingField: 7
<AiType>k__BackingField: 1
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 40
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 50
<Def>k__BackingField: 5
<MoveSpd>k__BackingField: 5.5
<AtkCooldown>k__BackingField: 2
<AtkRange>k__BackingField: 1.5
<ViewRange>k__BackingField: 15
<AtkRange>k__BackingField: 2
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 75
<AvoidanceRate>k__BackingField: 20
<UsingShield>k__BackingField: 0
@ -143,14 +191,20 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_sailor_p_004
<ViewIdx>k__BackingField: ai_view_sailor_p_004
<UnitType>k__BackingField: 8
<AiType>k__BackingField: 1
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 60
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 30
<Def>k__BackingField: 10
<MoveSpd>k__BackingField: 5
<AtkCooldown>k__BackingField: 1.5
<AtkRange>k__BackingField: 1
<ViewRange>k__BackingField: 10
<AtkRange>k__BackingField: 1.5
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 50
<AvoidanceRate>k__BackingField: 10
<UsingShield>k__BackingField: 1
@ -159,14 +213,20 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_sailor_p_005
<ViewIdx>k__BackingField: ai_view_sailor_p_005
<UnitType>k__BackingField: 9
<AiType>k__BackingField: 1
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 45
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 35
<Def>k__BackingField: 5
<MoveSpd>k__BackingField: 6
<AtkCooldown>k__BackingField: 1.5
<AtkRange>k__BackingField: 1
<ViewRange>k__BackingField: 15
<AtkRange>k__BackingField: 1.5
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 50
<AvoidanceRate>k__BackingField: 30
<UsingShield>k__BackingField: 0
@ -175,30 +235,42 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_captain_e_001
<ViewIdx>k__BackingField: ai_view_captain_e_001
<UnitType>k__BackingField: 0
<AiType>k__BackingField: 2
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 150
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 50
<Def>k__BackingField: 0
<MoveSpd>k__BackingField: 5
<AtkCooldown>k__BackingField: 3
<AtkRange>k__BackingField: 15
<ViewRange>k__BackingField: 40
<AtkRange>k__BackingField: 40
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 25
<AvoidanceRate>k__BackingField: 20
<UsingShield>k__BackingField: 0
<PenetrationResistivity>k__BackingField: 0
<UsingBow>k__BackingField: 1
<Inaccuracy>k__BackingField: 0.5
<Inaccuracy>k__BackingField: 1
- <Idx>k__BackingField: ai_stat_captain_e_002
<ViewIdx>k__BackingField: ai_view_captain_e_002
<UnitType>k__BackingField: 1
<AiType>k__BackingField: 2
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 300
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 40
<Def>k__BackingField: 10
<MoveSpd>k__BackingField: 4.5
<AtkCooldown>k__BackingField: 2
<AtkRange>k__BackingField: 1.5
<ViewRange>k__BackingField: 10
<AtkRange>k__BackingField: 2
<DefenseRange>k__BackingField: 10
<ShieldPenetrationRate>k__BackingField: 75
<AvoidanceRate>k__BackingField: 10
<UsingShield>k__BackingField: 1
@ -207,14 +279,20 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_captain_e_003
<ViewIdx>k__BackingField: ai_view_captain_e_003
<UnitType>k__BackingField: 2
<AiType>k__BackingField: 2
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 200
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 50
<Def>k__BackingField: 5
<MoveSpd>k__BackingField: 5.5
<AtkCooldown>k__BackingField: 2
<AtkRange>k__BackingField: 1.5
<ViewRange>k__BackingField: 15
<AtkRange>k__BackingField: 2
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 75
<AvoidanceRate>k__BackingField: 20
<UsingShield>k__BackingField: 0
@ -223,14 +301,20 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_captain_e_004
<ViewIdx>k__BackingField: ai_view_captain_e_004
<UnitType>k__BackingField: 3
<AiType>k__BackingField: 2
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 300
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 30
<Def>k__BackingField: 10
<MoveSpd>k__BackingField: 5
<AtkCooldown>k__BackingField: 1.5
<AtkRange>k__BackingField: 1
<ViewRange>k__BackingField: 10
<AtkRange>k__BackingField: 1.5
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 50
<AvoidanceRate>k__BackingField: 10
<UsingShield>k__BackingField: 1
@ -239,14 +323,20 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_captain_e_005
<ViewIdx>k__BackingField: ai_view_captain_e_005
<UnitType>k__BackingField: 4
<AiType>k__BackingField: 2
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 225
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 35
<Def>k__BackingField: 5
<MoveSpd>k__BackingField: 6
<AtkCooldown>k__BackingField: 1.5
<AtkRange>k__BackingField: 1
<ViewRange>k__BackingField: 15
<AtkRange>k__BackingField: 1.5
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 50
<AvoidanceRate>k__BackingField: 30
<UsingShield>k__BackingField: 0
@ -255,30 +345,42 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_captain_p_001
<ViewIdx>k__BackingField: ai_view_captain_p_001
<UnitType>k__BackingField: 5
<AiType>k__BackingField: 1
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 150
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 50
<Def>k__BackingField: 0
<MoveSpd>k__BackingField: 5
<AtkCooldown>k__BackingField: 3
<AtkRange>k__BackingField: 15
<ViewRange>k__BackingField: 40
<AtkRange>k__BackingField: 40
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 25
<AvoidanceRate>k__BackingField: 20
<UsingShield>k__BackingField: 0
<PenetrationResistivity>k__BackingField: 0
<UsingBow>k__BackingField: 1
<Inaccuracy>k__BackingField: 0.5
<Inaccuracy>k__BackingField: 1
- <Idx>k__BackingField: ai_stat_captain_p_002
<ViewIdx>k__BackingField: ai_view_captain_p_002
<UnitType>k__BackingField: 6
<AiType>k__BackingField: 1
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 250
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 50
<Def>k__BackingField: 0
<MoveSpd>k__BackingField: 5
<AtkCooldown>k__BackingField: 2.5
<AtkRange>k__BackingField: 1.5
<ViewRange>k__BackingField: 15
<AtkRange>k__BackingField: 2
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 100
<AvoidanceRate>k__BackingField: 10
<UsingShield>k__BackingField: 0
@ -287,14 +389,20 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_captain_p_003
<ViewIdx>k__BackingField: ai_view_captain_p_003
<UnitType>k__BackingField: 7
<AiType>k__BackingField: 1
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 200
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 50
<Def>k__BackingField: 5
<MoveSpd>k__BackingField: 5.5
<AtkCooldown>k__BackingField: 2
<AtkRange>k__BackingField: 1.5
<ViewRange>k__BackingField: 15
<AtkRange>k__BackingField: 2
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 75
<AvoidanceRate>k__BackingField: 20
<UsingShield>k__BackingField: 0
@ -303,14 +411,20 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_captain_p_004
<ViewIdx>k__BackingField: ai_view_captain_p_004
<UnitType>k__BackingField: 8
<AiType>k__BackingField: 1
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 300
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 30
<Def>k__BackingField: 10
<MoveSpd>k__BackingField: 5
<AtkCooldown>k__BackingField: 1.5
<AtkRange>k__BackingField: 1
<ViewRange>k__BackingField: 10
<AtkRange>k__BackingField: 1.5
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 50
<AvoidanceRate>k__BackingField: 10
<UsingShield>k__BackingField: 1
@ -319,14 +433,20 @@ MonoBehaviour:
<Inaccuracy>k__BackingField: 0
- <Idx>k__BackingField: ai_stat_captain_p_005
<ViewIdx>k__BackingField: ai_view_captain_p_005
<UnitType>k__BackingField: 9
<AiType>k__BackingField: 1
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<MaxHp>k__BackingField: 225
<CurrentHp>k__BackingField: 0
<Atk>k__BackingField: 35
<Def>k__BackingField: 5
<MoveSpd>k__BackingField: 6
<AtkCooldown>k__BackingField: 1.5
<AtkRange>k__BackingField: 1
<ViewRange>k__BackingField: 15
<AtkRange>k__BackingField: 1.5
<DefenseRange>k__BackingField: 0
<ShieldPenetrationRate>k__BackingField: 50
<AvoidanceRate>k__BackingField: 30
<UsingShield>k__BackingField: 0

View File

@ -100,7 +100,7 @@ MonoBehaviour:
<Head>k__BackingField: 16
<RightWeapon>k__BackingField: -1
<Body>k__BackingField: 11
<Flag>k__BackingField: 0
<Flag>k__BackingField: 1
- <Idx>k__BackingField: ai_view_captain_e_002
<Backpack>k__BackingField: -1
<LeftWeapon>k__BackingField: -1
@ -108,7 +108,7 @@ MonoBehaviour:
<Head>k__BackingField: 46
<RightWeapon>k__BackingField: 27
<Body>k__BackingField: 18
<Flag>k__BackingField: 0
<Flag>k__BackingField: 1
- <Idx>k__BackingField: ai_view_captain_e_003
<Backpack>k__BackingField: -1
<LeftWeapon>k__BackingField: -1
@ -116,7 +116,7 @@ MonoBehaviour:
<Head>k__BackingField: 35
<RightWeapon>k__BackingField: 27
<Body>k__BackingField: 17
<Flag>k__BackingField: 0
<Flag>k__BackingField: 1
- <Idx>k__BackingField: ai_view_captain_e_004
<Backpack>k__BackingField: -1
<LeftWeapon>k__BackingField: -1
@ -124,7 +124,7 @@ MonoBehaviour:
<Head>k__BackingField: 33
<RightWeapon>k__BackingField: 6
<Body>k__BackingField: 39
<Flag>k__BackingField: 0
<Flag>k__BackingField: 1
- <Idx>k__BackingField: ai_view_captain_e_005
<Backpack>k__BackingField: -1
<LeftWeapon>k__BackingField: -1
@ -132,7 +132,7 @@ MonoBehaviour:
<Head>k__BackingField: 25
<RightWeapon>k__BackingField: 28
<Body>k__BackingField: 29
<Flag>k__BackingField: 0
<Flag>k__BackingField: 1
- <Idx>k__BackingField: ai_view_captain_p_001
<Backpack>k__BackingField: 0
<LeftWeapon>k__BackingField: 1
@ -140,7 +140,7 @@ MonoBehaviour:
<Head>k__BackingField: 11
<RightWeapon>k__BackingField: -1
<Body>k__BackingField: 1
<Flag>k__BackingField: 0
<Flag>k__BackingField: 9
- <Idx>k__BackingField: ai_view_captain_p_002
<Backpack>k__BackingField: -1
<LeftWeapon>k__BackingField: -1
@ -148,7 +148,7 @@ MonoBehaviour:
<Head>k__BackingField: 50
<RightWeapon>k__BackingField: 31
<Body>k__BackingField: 58
<Flag>k__BackingField: 0
<Flag>k__BackingField: 9
- <Idx>k__BackingField: ai_view_captain_p_003
<Backpack>k__BackingField: -1
<LeftWeapon>k__BackingField: -1
@ -156,7 +156,7 @@ MonoBehaviour:
<Head>k__BackingField: 36
<RightWeapon>k__BackingField: 27
<Body>k__BackingField: 60
<Flag>k__BackingField: 0
<Flag>k__BackingField: 9
- <Idx>k__BackingField: ai_view_captain_p_004
<Backpack>k__BackingField: -1
<LeftWeapon>k__BackingField: -1
@ -164,7 +164,7 @@ MonoBehaviour:
<Head>k__BackingField: 22
<RightWeapon>k__BackingField: 24
<Body>k__BackingField: 58
<Flag>k__BackingField: 0
<Flag>k__BackingField: 9
- <Idx>k__BackingField: ai_view_captain_p_005
<Backpack>k__BackingField: -1
<LeftWeapon>k__BackingField: -1
@ -172,4 +172,4 @@ MonoBehaviour:
<Head>k__BackingField: 5
<RightWeapon>k__BackingField: 12
<Body>k__BackingField: 0
<Flag>k__BackingField: 0
<Flag>k__BackingField: 9

View File

@ -17,19 +17,19 @@ MonoBehaviour:
<CaptainStatIdx>k__BackingField: ai_stat_captain_e_001
<SailorStatIdx>k__BackingField: ai_stat_sailor_e_001
<UnitName>k__BackingField: EnemyArcher001
<UnitType>k__BackingField: 0
<UnitType>k__BackingField: -1
<SailorCount>k__BackingField: 5
<AttackerType>k__BackingField: -1
<AttackerType>k__BackingField: 1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<DefenseType>k__BackingField: 3
<UnitList>k__BackingField: []
- <Idx>k__BackingField: unit_sword_knight_e_001
<CaptainStatIdx>k__BackingField: ai_stat_captain_e_004
<SailorStatIdx>k__BackingField: ai_stat_sailor_e_004
<UnitName>k__BackingField: EnemySwordKnight001
<UnitType>k__BackingField: 3
<UnitType>k__BackingField: -1
<SailorCount>k__BackingField: 3
<AttackerType>k__BackingField: -1
<AttackerType>k__BackingField: 1
<OffenseType>k__BackingField: -1
<DefenseType>k__BackingField: -1
<DefenseType>k__BackingField: 2
<UnitList>k__BackingField: []

View File

@ -17,7 +17,7 @@ MonoBehaviour:
<CaptainStatIdx>k__BackingField: ai_stat_captain_p_001
<SailorStatIdx>k__BackingField: ai_stat_sailor_p_001
<UnitName>k__BackingField: Legolas
<UnitType>k__BackingField: 5
<UnitType>k__BackingField: -1
<SailorCount>k__BackingField: 8
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: 0
@ -27,7 +27,7 @@ MonoBehaviour:
<CaptainStatIdx>k__BackingField: ai_stat_captain_p_001
<SailorStatIdx>k__BackingField: ai_stat_sailor_p_001
<UnitName>k__BackingField: Robin Hood
<UnitType>k__BackingField: 5
<UnitType>k__BackingField: -1
<SailorCount>k__BackingField: 5
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: 0
@ -37,7 +37,7 @@ MonoBehaviour:
<CaptainStatIdx>k__BackingField: ai_stat_captain_p_002
<SailorStatIdx>k__BackingField: ai_stat_sailor_p_002
<UnitName>k__BackingField: Olaf
<UnitType>k__BackingField: 6
<UnitType>k__BackingField: -1
<SailorCount>k__BackingField: 5
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: 0
@ -47,7 +47,7 @@ MonoBehaviour:
<CaptainStatIdx>k__BackingField: ai_stat_captain_p_003
<SailorStatIdx>k__BackingField: ai_stat_sailor_p_003
<UnitName>k__BackingField: Lancer
<UnitType>k__BackingField: 7
<UnitType>k__BackingField: -1
<SailorCount>k__BackingField: 7
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: 1
@ -57,7 +57,7 @@ MonoBehaviour:
<CaptainStatIdx>k__BackingField: ai_stat_captain_p_004
<SailorStatIdx>k__BackingField: ai_stat_sailor_p_004
<UnitName>k__BackingField: Achilles
<UnitType>k__BackingField: 8
<UnitType>k__BackingField: -1
<SailorCount>k__BackingField: 3
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: 0
@ -67,17 +67,17 @@ MonoBehaviour:
<CaptainStatIdx>k__BackingField: ai_stat_captain_p_005
<SailorStatIdx>k__BackingField: ai_stat_sailor_p_005
<UnitName>k__BackingField: Aragorn
<UnitType>k__BackingField: 9
<UnitType>k__BackingField: -1
<SailorCount>k__BackingField: 5
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: 1
<OffenseType>k__BackingField: 0
<DefenseType>k__BackingField: -1
<UnitList>k__BackingField: []
- <Idx>k__BackingField: unit_swordman_p_002
<CaptainStatIdx>k__BackingField: ai_stat_captain_p_005
<SailorStatIdx>k__BackingField: ai_stat_sailor_p_005
<UnitName>k__BackingField: King Arthur
<UnitType>k__BackingField: 9
<UnitType>k__BackingField: -1
<SailorCount>k__BackingField: 11
<AttackerType>k__BackingField: -1
<OffenseType>k__BackingField: 0

View File

@ -1,4 +1,4 @@
using System;
using Sirenix.OdinInspector;
using UnityEngine;
// ReSharper disable once CheckNamespace
@ -8,7 +8,12 @@ namespace BlueWaterProject
{
#region Property and variable
public IslandInfo IslandInfo { get; set; }
[SerializeField] private IslandInfo islandInfo;
[SerializeField] private float maxHp = 500f;
[DisableIf("@true")]
[SerializeField] private float currentHp;
#endregion
@ -16,7 +21,7 @@ namespace BlueWaterProject
private void Awake()
{
SetCurrentHp(AiStat.MaxHp);
SetCurrentHp(maxHp);
}
private void OnDisable()
@ -28,15 +33,9 @@ namespace BlueWaterProject
#region Interface property and function
[field: SerializeField] public AiStat AiStat { get; set; }
public float GetCurrentHp() => AiStat.CurrentHp;
public void SetCurrentHp(float value) => AiStat.CurrentHp = value;
public void TakeDamage(float attackerPower, float attackerShieldPenetrationRate = default, Vector3? attackPos = null)
{
var changeHp = Mathf.Max(AiStat.CurrentHp - attackerPower, 0);
var changeHp = Mathf.Max(currentHp - attackerPower, 0);
SetCurrentHp(changeHp);
// 건물 파괴
@ -52,11 +51,15 @@ namespace BlueWaterProject
private void RemoveIslandInfo()
{
if (!IslandInfo) return;
if (!islandInfo) return;
IslandInfo.RemoveListElement(IslandInfo.HouseList, transform);
islandInfo.RemoveListElement(islandInfo.HouseList, transform);
}
public float GetCurrentHp() => currentHp;
public void SetCurrentHp(float value) => currentHp = value;
public void SetIslandInfo(IslandInfo island) => islandInfo = island;
#endregion
}
}

View File

@ -4,20 +4,9 @@ using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public enum MoveType
{
NONE, // 미설정
FIXED, // 자리를 지키는 AI
MOVE // 자리를 움직이는 AI
}
public interface IAiMover : IAiBase
{
// Properties
MoveType AttackMoveType { get; set; }
MoveType BeAttackedMoveType { get; set; }
bool IsCommanded { get; set; }
// Functions

View File

@ -11,21 +11,17 @@ namespace BlueWaterProject
LayerMask TargetLayer { get; set; }
float ViewRadius { get; set; }
Collider[] ColliderWithinRange { get; set; }
IAiStat IaiStat { get; set; }
Transform TargetTransform { get; set; }
// Functions
void DrawGizmosInFieldOfView();
IEnumerator FindTarget();
IEnumerator FindTargetInOffense();
IEnumerator FindTargetInDefense();
void UpdateLookAtTarget();
}
}

View File

@ -47,7 +47,7 @@ namespace BlueWaterProject
if (!house.CompareTag("House") || !house.gameObject.activeSelf) continue;
var houseInfo = house.GetComponent<HouseInfo>();
houseInfo.IslandInfo = this;
houseInfo.SetIslandInfo(this);
HouseList.Add(houseInfo.transform);
}
}

View File

@ -18,11 +18,12 @@ namespace BlueWaterProject
[SerializeField] private float arrowSpeed = 10f;
private bool isAttacked;
private bool isOffense;
private float g = Mathf.Abs(Physics.gravity.y);
private float inaccuracy;
private Vector3? attackerPos;
private Vector3 targetPos;
private AttackerType attackerType;
private EAiType attackerAiType;
public Coroutine shootCoroutine;
private Transform attackerTransform;
@ -57,24 +58,33 @@ namespace BlueWaterProject
isAttacked = true;
DestroyObject();
}
else if (other.gameObject.layer == LayerMask.NameToLayer("Props"))
{
if (!isOffense) return;
isAttacked = true;
DestroyObject();
}
else if (other.gameObject.layer == LayerMask.NameToLayer("HitBox"))
{
switch (attackerType)
switch (attackerAiType)
{
case AttackerType.NONE:
case EAiType.NONE:
print("aiType == NONE Error");
break;
case AttackerType.OFFENSE:
if (!other.gameObject.CompareTag("Enemy") && !other.gameObject.CompareTag("House"))
case EAiType.PLAYER:
case EAiType.PIRATE:
if (other.gameObject.CompareTag("Enemy"))
{
return;
break;
}
break;
case AttackerType.DEFENSE:
if (!other.gameObject.CompareTag("Player") && !other.gameObject.CompareTag("Pirate"))
{
return;
}
case EAiType.ENEMY:
if (other.gameObject.CompareTag("Pirate") || other.gameObject.CompareTag("Player"))
{
break;
}
return;
default:
throw new ArgumentOutOfRangeException();
}
@ -154,7 +164,7 @@ namespace BlueWaterProject
/// <summary>
/// 화살이 발사 되기 직전에 필요한 데이터들을 입력받는 함수
/// </summary>
public void SetShootingArrow(Vector3 shootLocationPos, Vector3? attackPos, Vector3 targetPosition, AiStat attackerAiStat, AttackerType type, float inaccuracyValue)
public void SetShootingArrow(Vector3 shootLocationPos, Vector3? attackPos, Vector3 targetPosition, AiStat attackerAiStat, EAiType aiType, float inaccuracyValue, bool isOffense)
{
isAttacked = false;
transform.position = shootLocationPos;
@ -164,8 +174,9 @@ namespace BlueWaterProject
}
targetPos = targetPosition;
attackerStat = attackerAiStat;
attackerType = type;
attackerAiType = aiType;
inaccuracy = inaccuracyValue;
this.isOffense = isOffense;
}
#endregion

View File

@ -10,7 +10,7 @@ namespace BlueWaterProject
private bool isAttacked;
private AttackerType attackerType;
private EAttackerType eAttackerType;
private AiStat attackerStat;
#endregion
@ -23,17 +23,17 @@ namespace BlueWaterProject
if (other.gameObject.layer == LayerMask.NameToLayer("HitBox"))
{
switch (attackerType)
switch (eAttackerType)
{
case AttackerType.NONE:
case EAttackerType.NONE:
break;
case AttackerType.OFFENSE:
case EAttackerType.OFFENSE:
if (!other.gameObject.CompareTag("Enemy") && !other.gameObject.CompareTag("House"))
{
return;
}
break;
case AttackerType.DEFENSE:
case EAttackerType.DEFENSE:
if (!other.gameObject.CompareTag("Player") && !other.gameObject.CompareTag("Pirate"))
{
return;
@ -56,7 +56,7 @@ namespace BlueWaterProject
#region Custom function
public void SetIsAttacked(bool value) => isAttacked = value;
public void SetAttackerType(AttackerType value) => attackerType = value;
public void SetAttackerType(EAttackerType value) => eAttackerType = value;
public void SetAttackerStat(AiStat value) => attackerStat = value;
#endregion

View File

@ -31,7 +31,7 @@ Transform:
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0.125, y: 0.25, z: 0.25}
m_LocalScale: {x: 0.625, y: 1.25, z: 1.25}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
@ -147,5 +147,4 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
autoDestroyTime: 5
arrowSpeed: 10
isAttacked: 0
arrowSpeed: 20

View File

@ -20942,7 +20942,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!4 &3209293871077764151
Transform:
m_ObjectHideFlags: 0
@ -28809,7 +28809,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
m_IsActive: 1
--- !u!4 &7468684795553312367
Transform:
m_ObjectHideFlags: 0