#24 화살타워 추가

This commit is contained in:
NTG_Lenovo 2023-09-20 12:30:58 +09:00
parent 5f20d3d57a
commit c56898125c
4 changed files with 105 additions and 57 deletions

View File

@ -73505,7 +73505,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!4 &187351605
Transform:
m_ObjectHideFlags: 0
@ -709237,7 +709237,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1871370245}
serializedVersion: 2
m_LocalRotation: {x: 0.67640686, y: -0.0000002980232, z: 0.0000002980232, w: 0.7365283}
m_LocalRotation: {x: 0.6764068, y: -0, z: -0, w: 0.7365283}
m_LocalPosition: {x: -0.0000002384187, y: 120, z: -10.000001}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0

View File

@ -2,8 +2,8 @@
using System.Collections;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Pool;
using Random = UnityEngine.Random;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
@ -14,6 +14,9 @@ namespace BlueWaterProject
[Title("Tower Stat")]
[SerializeField] private bool isDrawGizmosInFieldOfView = true;
[SerializeField] private bool isPredictAttack = true;
[OnValueChanged(nameof(SetLayer))]
[SerializeField] private EAiType aiType;
[SerializeField] private float maxHp;
[SerializeField] private float currentHp;
@ -25,8 +28,9 @@ namespace BlueWaterProject
[Title("실시간 타겟 정보")]
[SerializeField] private LayerMask targetLayer;
[SerializeField] private LayerMask arrowLayer;
[SerializeField] private Collider[] colliderWithinRange;
[SerializeField] private Transform targetTransform;
[SerializeField] private Collider targetCollider;
[Title("화살 오브젝트 관리")]
[Tooltip("화살 오브젝트 풀링할 최대 갯수")]
@ -49,16 +53,15 @@ namespace BlueWaterProject
Gizmos.color = Color.blue;
Gizmos.DrawWireSphere(transform.position, atkRange);
if (!targetTransform) return;
if (!targetCollider) return;
Gizmos.color = Color.red;
Gizmos.DrawLine(transform.position, targetTransform.position);
Gizmos.DrawLine(shootLocation.position, targetCollider.bounds.center);
}
private void Awake()
{
InitComponent();
SetLayer();
}
private void Start()
@ -80,7 +83,7 @@ namespace BlueWaterProject
// 건물 파괴
if (changeHp == 0f)
{
Destroy(gameObject);
Die();
// RemoveIslandInfo();
}
}
@ -111,73 +114,113 @@ namespace BlueWaterProject
colliderWithinRange = new Collider[TARGET_MAX_SIZE];
}
private void SetLayer()
{
switch (aiType)
{
case EAiType.NONE:
print("aiType == NONE error");
targetLayer = 0;
break;
case EAiType.PLAYER:
case EAiType.PIRATE:
targetLayer |= LayerMask.GetMask("Enemy");
targetLayer = LayerMask.GetMask("Enemy");
break;
case EAiType.ENEMY:
targetLayer |= LayerMask.GetMask("Player") | LayerMask.GetMask("Pirate");
targetLayer = LayerMask.GetMask("Player") | LayerMask.GetMask("Pirate");
break;
default:
targetLayer = 0;
arrowLayer = 0;
throw new ArgumentOutOfRangeException();
}
arrowLayer = targetLayer | LayerMask.GetMask("Ground") | LayerMask.GetMask("Water") |
LayerMask.GetMask("Props");
}
private IEnumerator Attack()
{
while (true)
{
FindNearestTargetInRange(transform.position, atkRange);
FindNearestTargetInRange(atkRange);
if (!targetTransform) yield return new WaitForSeconds(atkCooldown);
if (!targetCollider)
{
yield return new WaitForSeconds(atkCooldown);
continue;
}
var arrow = arrowPool.Get();
var targetPos = isPredictAttack ? PredictTargetPosition(shootLocation, targetCollider, arrow.GetArrowSpeed()) : targetCollider.bounds.center;
arrow.SetShootingArrow(shootLocation.position, transform.position,
targetTransform.position, aiType, atk, shieldPenetrationRate, inaccuracy, false);
targetPos, aiType, atk, shieldPenetrationRate, inaccuracy, false);
arrow.ShootArrowCoroutine();
yield return new WaitForSeconds(atkCooldown);
}
}
private void FindNearestTargetInRange(Vector3 centerPos, float range)
private void FindNearestTargetInRange(float range)
{
Array.Clear(colliderWithinRange, 0, TARGET_MAX_SIZE);
var maxColliderCount = Physics.OverlapSphereNonAlloc(centerPos, range, colliderWithinRange,
var maxColliderCount = Physics.OverlapSphereNonAlloc(transform.position, range, colliderWithinRange,
targetLayer, QueryTriggerInteraction.Collide);
if (maxColliderCount <= 0)
{
SetTargetTransform(null);
SetTargetCollider(null);
return;
}
var nearestDistance = Mathf.Infinity;
Transform nearestTargetTransform = null;
Collider nearestTargetTransform = null;
for (var i = 0; i < maxColliderCount; i++)
{
var distanceToTarget = Vector3.Distance(transform.position, colliderWithinRange[i].transform.position);
var distanceToTarget = Vector3.Distance(shootLocation.position, colliderWithinRange[i].bounds.center);
if (!IsRaycastHitTarget(shootLocation.position, colliderWithinRange[i]) || distanceToTarget >= nearestDistance) continue;
if (distanceToTarget >= nearestDistance) continue;
nearestDistance = distanceToTarget;
nearestTargetTransform = colliderWithinRange[i].transform;
nearestTargetTransform = colliderWithinRange[i];
}
SetTargetTransform(nearestTargetTransform);
SetTargetCollider(nearestTargetTransform);
}
private bool IsRaycastHitTarget(Vector3 startPos, Collider target)
{
var direction = ((target.bounds.center) - (startPos)).normalized;
var raycastHitTarget = Physics.Raycast(startPos, direction, out var hit, atkRange, arrowLayer, QueryTriggerInteraction.Collide);
return raycastHitTarget && target == hit.collider;
}
private Vector3 PredictTargetPosition(Transform shooter, Collider target, float arrowSpeed)
{
var targetVelocity = target.GetComponent<NavMeshAgent>().velocity;
var targetPos = target.bounds.center;
var directionToTarget = targetPos - shooter.position;
var distanceToTarget = directionToTarget.magnitude;
var timeToImpact = distanceToTarget / arrowSpeed;
var predictedPosition = targetPos + targetVelocity * timeToImpact;
return predictedPosition;
}
private void Die()
{
StopAllCoroutines();
Destroy(gameObject);
}
private void SetCurrentHp(float value) => currentHp = value;
private void SetTargetTransform(Transform value) => targetTransform = value;
private void SetTargetCollider(Collider value) => targetCollider = value;
#endregion

View File

@ -222,6 +222,8 @@ namespace BlueWaterProject
gameObject.SetActive(false);
}
public float GetArrowSpeed() => arrowSpeed;
#endregion
}
}

View File

@ -42,8 +42,8 @@ GameObject:
- component: {fileID: 9031747955947254101}
- component: {fileID: 8726458248037506361}
- component: {fileID: 8190100621632311398}
- component: {fileID: 9087576015726480415}
- component: {fileID: 3766443407819787020}
- component: {fileID: 9087576015726480415}
m_Layer: 16
m_Name: ArrowTower
m_TagString: Tower
@ -117,34 +117,6 @@ MeshRenderer:
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!114 &9087576015726480415
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8848616787261608530}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bd421891d0204bc5a748862f0ac9c0f1, type: 3}
m_Name:
m_EditorClassIdentifier:
isDrawGizmosInFieldOfView: 1
aiType: 0
maxHp: 500
currentHp: 0
atk: 20
atkRange: 30
atkCooldown: 2
shieldPenetrationRate: 50
inaccuracy: 0
colliderWithinRange: []
targetTransform: {fileID: 0}
arrowMaxSize: 100
arrowsPoolLocation: {fileID: 0}
targetLayer:
serializedVersion: 2
m_Bits: 0
--- !u!65 &3766443407819787020
BoxCollider:
m_ObjectHideFlags: 0
@ -164,5 +136,36 @@ BoxCollider:
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Size: {x: 4.0214233, y: 4.0214243, z: 8.281539}
m_Center: {x: 0, y: 0.00000011920932, z: 2.6434815}
m_Size: {x: 2.930729, y: 3.065148, z: 3.854234}
m_Center: {x: 0.07538414, y: -0.21270323, z: 0.4423293}
--- !u!114 &9087576015726480415
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8848616787261608530}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: bd421891d0204bc5a748862f0ac9c0f1, type: 3}
m_Name:
m_EditorClassIdentifier:
isDrawGizmosInFieldOfView: 1
isPredictAttack: 1
aiType: 2
maxHp: 500
currentHp: 0
atk: 20
atkRange: 30
atkCooldown: 1
shieldPenetrationRate: 50
inaccuracy: 0
targetLayer:
serializedVersion: 2
m_Bits: 768
arrowLayer:
serializedVersion: 2
m_Bits: 66328
colliderWithinRange: []
targetCollider: {fileID: 0}
arrowMaxSize: 100