+ Layer Boids, Boid로 분리
+ Fish의 로직을 Boids(군집) 알고리즘으로 변경
+ 군집에 이펙트를 통해 낚시 가시성 추가
+ 테스트용 군집 애니메이션 추가
+ Epic Toon EX 에셋의 스크립트 수정 버전
  ㄴ ParticleWeapon(Layer 선택, UnityEvent Hit 델리게이트 기능 추가) 사용
+ Cannon의 x축 회전 고정
+ Cannon이 공격한 Layer에 따른 기능 변경
+ DataManager에 PlayerInventory 추가
  ㄴ 초창기에 사용한 코딩 삭제
+ 초창기에 사용했던 스크립트들 일부 정리
This commit is contained in:
NTG 2024-01-03 06:39:53 +09:00
parent b8d9b964da
commit 2da1b44a53
296 changed files with 11411 additions and 7790 deletions

View File

@ -233,9 +233,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 910f2fd54fe913648b37e911580e8068, type: 3}
m_Name:
m_EditorClassIdentifier:
islandInfo: {fileID: 357776294}
maxHp: 500
currentHp: 0
--- !u!65 &44403560
BoxCollider:
m_ObjectHideFlags: 0
@ -811,28 +808,8 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
_persistent: 0
<EnemyViewDataSo>k__BackingField: {fileID: 11400000, guid: d4ed8ebcf48bbdb4d84caf4a4cab7c04,
type: 2}
<PirateViewDataSo>k__BackingField: {fileID: 11400000, guid: 33ac25d6eca8f6447a342dfb44a2a282,
type: 2}
<EnemyStatDataSo>k__BackingField: {fileID: 11400000, guid: c19ae12d221eae64f90d58e15a04d592,
type: 2}
<PirateStatDataSo>k__BackingField: {fileID: 11400000, guid: 0f0ed8929be00534e97398bb55d8c541,
type: 2}
<EnemyUnitStatDataSo>k__BackingField: {fileID: 11400000, guid: d363ca1023ab0754489bda2d69d79564,
type: 2}
<PirateUnitDataSo>k__BackingField: {fileID: 11400000, guid: 6cd374040492d94498f1cce6c3a10e14,
type: 2}
<CardDataSo>k__BackingField: {fileID: 11400000, guid: 0db3b35c9121e9e4bbe8559a0922145f,
type: 2}
<CardList>k__BackingField:
- card_001
- card_002
- card_003
- card_004
- card_005
- card_006
- card_007
<PlayerInventory>k__BackingField:
fishInfoList: []
mouseSpot: {fileID: 1347266192824951316, guid: 049de7a77e0534ced92b672937a0f8db,
type: 3}
boat: {fileID: 2987405546353765599, guid: 96173da392e9a408d9aea814b4cfe00e, type: 3}
@ -843,6 +820,9 @@ MonoBehaviour:
vomit: {fileID: 8216347814332420713, guid: 55593ff8cc9154523aa7f5951f2444a5, type: 3}
nukeFire: {fileID: 128572, guid: d8aca1dfdbd0741fca61f68fd3bc8119, type: 3}
grenadeFire: {fileID: 128572, guid: 8d387b0f65dfa4cdc965c4b56216e120, type: 3}
emojiHeart: {fileID: 0}
emojiPuke: {fileID: 0}
emojiAnger: {fileID: 0}
cardType:
- {fileID: 21300000, guid: 550b6170d3e5c4cf885cf56fa1df8f6b, type: 3}
- {fileID: 21300000, guid: fa70a195a66db4c7fb6180f4205a06b1, type: 3}
@ -1679,7 +1659,6 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 200595900}
- component: {fileID: 200595902}
- component: {fileID: 200595901}
m_Layer: 0
m_Name: SecondMap
@ -1747,26 +1726,6 @@ MonoBehaviour:
m_MinRegionArea: 2
m_NavMeshData: {fileID: 23800000, guid: ed36e1064a49b084bac46d5debdc1de3, type: 2}
m_BuildHeightMesh: 0
--- !u!114 &200595902
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 200595899}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e21653ba0089cfe46beca2cdf851abcd, type: 3}
m_Name:
m_EditorClassIdentifier:
<IslandName>k__BackingField:
<HouseList>k__BackingField: []
<TowerList>k__BackingField: []
<UnitList>k__BackingField: []
<EnemyList>k__BackingField: []
<ExceptHouseList>k__BackingField: []
<TargetAllList>k__BackingField: []
<IslandCam>k__BackingField: {fileID: 0}
--- !u!1001 &214342752
PrefabInstance:
m_ObjectHideFlags: 0
@ -3047,7 +3006,6 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 357776295}
- component: {fileID: 357776294}
- component: {fileID: 357776293}
m_Layer: 0
m_Name: FirstMap
@ -3087,195 +3045,6 @@ MonoBehaviour:
m_MinRegionArea: 2
m_NavMeshData: {fileID: 23800000, guid: 5ea25972c984549389ea883b022806f2, type: 2}
m_BuildHeightMesh: 0
--- !u!114 &357776294
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 357776292}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e21653ba0089cfe46beca2cdf851abcd, type: 3}
m_Name:
m_EditorClassIdentifier:
<IslandName>k__BackingField: FirstIsland
<HouseList>k__BackingField:
- {fileID: 1256859591}
- {fileID: 1332914089}
- {fileID: 44403557}
<TowerList>k__BackingField: []
<UnitList>k__BackingField:
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
<EnemyList>k__BackingField:
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
<ExceptHouseList>k__BackingField:
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
<TargetAllList>k__BackingField:
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 0}
- {fileID: 1256859591}
- {fileID: 1332914089}
- {fileID: 44403557}
<IslandCam>k__BackingField: {fileID: 541711048}
--- !u!4 &357776295
Transform:
m_ObjectHideFlags: 0
@ -6972,17 +6741,17 @@ PrefabInstance:
- target: {fileID: 1800824703194841433, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_LocalPosition.x
value: -13.5
value: -91.9
objectReference: {fileID: 0}
- target: {fileID: 1800824703194841433, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_LocalPosition.y
value: -88.1
value: -25.1
objectReference: {fileID: 0}
- target: {fileID: 1800824703194841433, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_LocalPosition.z
value: 163.8
value: 15.9
objectReference: {fileID: 0}
- target: {fileID: 1800824703194841433, guid: f228040d76c9217409284544f353da47,
type: 3}
@ -7022,23 +6791,28 @@ PrefabInstance:
- target: {fileID: 2854089398056668840, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_LocalScale.x
value: 50
objectReference: {fileID: 0}
- target: {fileID: 2854089398056668840, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_LocalScale.y
value: 20
objectReference: {fileID: 0}
- target: {fileID: 2854089398056668840, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_LocalScale.y
value: 10
objectReference: {fileID: 0}
- target: {fileID: 2854089398056668840, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_LocalScale.z
value: 50
value: 20
objectReference: {fileID: 0}
- target: {fileID: 4541625270423798677, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_Name
value: Boids (1)
objectReference: {fileID: 0}
- target: {fileID: 4541625270423798677, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5146900491857106217, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: boidCount
@ -7047,7 +6821,12 @@ PrefabInstance:
- target: {fileID: 5146900491857106217, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: spawnRange
value: 25
value: 5
objectReference: {fileID: 0}
- target: {fileID: 5146900491857106217, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: showWaterEffect
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5146900491857106217, guid: f228040d76c9217409284544f353da47,
type: 3}
@ -7077,17 +6856,21 @@ PrefabInstance:
- target: {fileID: 5146900491857106217, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: <RandomSpeedRange>k__BackingField.x
value: 3
value: 5
objectReference: {fileID: 0}
- target: {fileID: 5146900491857106217, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: <RandomSpeedRange>k__BackingField.y
value: 6
value: 8
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 2441661978531314766, guid: f228040d76c9217409284544f353da47,
type: 3}
insertIndex: -1
addedObject: {fileID: 1408368785}
m_SourcePrefab: {fileID: 100100000, guid: f228040d76c9217409284544f353da47, type: 3}
--- !u!1 &734248429
GameObject:
@ -9511,9 +9294,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 910f2fd54fe913648b37e911580e8068, type: 3}
m_Name:
m_EditorClassIdentifier:
islandInfo: {fileID: 357776294}
maxHp: 500
currentHp: 0
--- !u!65 &1256859594
BoxCollider:
m_ObjectHideFlags: 0
@ -9922,9 +9702,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 910f2fd54fe913648b37e911580e8068, type: 3}
m_Name:
m_EditorClassIdentifier:
islandInfo: {fileID: 357776294}
maxHp: 500
currentHp: 0
--- !u!65 &1332914092
BoxCollider:
m_ObjectHideFlags: 0
@ -10482,6 +10259,34 @@ MonoBehaviour:
- {fileID: 1354317160}
- {fileID: 957406935}
- {fileID: 745028227}
--- !u!1 &1408368779 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 2441661978531314766, guid: f228040d76c9217409284544f353da47,
type: 3}
m_PrefabInstance: {fileID: 718723263}
m_PrefabAsset: {fileID: 0}
--- !u!95 &1408368785
Animator:
serializedVersion: 7
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1408368779}
m_Enabled: 1
m_Avatar: {fileID: 0}
m_Controller: {fileID: 9100000, guid: d59e6dd2b1d1f7a499297dfecfc7b777, type: 2}
m_CullingMode: 0
m_UpdateMode: 0
m_ApplyRootMotion: 0
m_LinearVelocityBlending: 0
m_StabilizeFeet: 0
m_AnimatePhysics: 0
m_WarningMessage:
m_HasTransformHierarchy: 1
m_AllowConstantClipSamplingOptimization: 1
m_KeepAnimatorStateOnDisable: 0
m_WriteDefaultValuesOnDisable: 0
--- !u!1001 &1446558449
PrefabInstance:
m_ObjectHideFlags: 0
@ -10767,8 +10572,8 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1485085414}
serializedVersion: 2
m_LocalRotation: {x: 0.38024017, y: 0.6187369, z: -0.46296236, w: 0.5081809}
m_LocalPosition: {x: -0.0006790161, y: 0, z: -0.00340271}
m_LocalRotation: {x: 0.38024342, y: 0.6187334, z: -0.4629597, w: 0.50818527}
m_LocalPosition: {x: -0.0008125305, y: 0, z: -0.004096985}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
@ -11648,7 +11453,7 @@ MonoBehaviour:
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 0}
GameObject: {fileID: 1683670876}
Ordinal: 2
Priority: 0
IconType: 1000
@ -11660,7 +11465,7 @@ MonoBehaviour:
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 107190133}
GameObject: {fileID: 2105062287}
Ordinal: 3
Priority: 0
IconType: 1000
@ -11670,34 +11475,10 @@ MonoBehaviour:
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 0}
Ordinal: 4
Priority: 0
IconType: 1000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 0
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 2105062287}
Ordinal: 5
Priority: 0
IconType: 1000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 0
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 357776292}
Ordinal: 6
Ordinal: 4
Priority: 0
IconType: 6000
IconTexture: {fileID: 0}
@ -11709,7 +11490,7 @@ MonoBehaviour:
- Type: 0
Name:
GameObject: {fileID: 200595899}
Ordinal: 7
Ordinal: 5
Priority: 0
IconType: 6000
IconTexture: {fileID: 0}
@ -11718,22 +11499,10 @@ MonoBehaviour:
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 0}
Ordinal: 8
Priority: 0
IconType: 6000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 9000
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 776161953}
Ordinal: 9
Ordinal: 6
Priority: 0
IconType: 290000
IconTexture: {fileID: 0}
@ -11745,7 +11514,7 @@ MonoBehaviour:
- Type: 0
Name:
GameObject: {fileID: 649179606}
Ordinal: 10
Ordinal: 7
Priority: 0
IconType: 341000
IconTexture: {fileID: 0}
@ -11757,7 +11526,7 @@ MonoBehaviour:
- Type: 0
Name:
GameObject: {fileID: 168896972}
Ordinal: 11
Ordinal: 8
Priority: 0
IconType: 341000
IconTexture: {fileID: 0}
@ -11766,12 +11535,48 @@ MonoBehaviour:
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 0}
Ordinal: 9
Priority: 0
IconType: 341000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 0
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 0}
Ordinal: 10
Priority: 0
IconType: 7000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 0
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 0}
Ordinal: 11
Priority: 0
IconType: 7000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 0
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 0}
Ordinal: 12
Priority: 0
IconType: 341000
IconType: 7000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 0
@ -11780,10 +11585,10 @@ MonoBehaviour:
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 0}
GameObject: {fileID: 476261169}
Ordinal: 13
Priority: 0
IconType: 341000
IconType: 200000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 0
@ -11795,7 +11600,7 @@ MonoBehaviour:
GameObject: {fileID: 0}
Ordinal: 14
Priority: 0
IconType: 341000
IconType: 200000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 0
@ -11807,78 +11612,6 @@ MonoBehaviour:
GameObject: {fileID: 0}
Ordinal: 15
Priority: 0
IconType: 341000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 0
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 0}
Ordinal: 16
Priority: 0
IconType: 7000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 0
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 0}
Ordinal: 17
Priority: 0
IconType: 7000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 0
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 0}
Ordinal: 18
Priority: 0
IconType: 7000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 0
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 476261169}
Ordinal: 19
Priority: 0
IconType: 200000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 0
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 0}
Ordinal: 20
Priority: 0
IconType: 200000
IconTexture: {fileID: 0}
IsIconRecursive: 0
BackgroundType: 0
BackgroundTexture: {fileID: 0}
IsBackgroundRecursive: 0
IsHidden: 0
- Type: 0
Name:
GameObject: {fileID: 0}
Ordinal: 21
Priority: 0
IconType: 200000
IconTexture: {fileID: 0}
IsIconRecursive: 0
@ -12501,6 +12234,66 @@ PrefabInstance:
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 6b556d7a85528a84aac27247ff9eeb24, type: 3}
--- !u!1 &1683670876
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1683670877}
- component: {fileID: 1683670878}
m_Layer: 0
m_Name: DataManager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1683670877
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1683670876}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1683670878
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1683670876}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 996bb30c01d484013ab3cb98f88b5c03, type: 3}
m_Name:
m_EditorClassIdentifier:
_persistent: 0
<PlayerInventory>k__BackingField:
fishInfoList: []
mouseSpot: {fileID: 0}
boat: {fileID: 0}
assaultCard: {fileID: 0}
radarTargetUi: {fileID: 0}
vomit: {fileID: 0}
nukeFire: {fileID: 0}
grenadeFire: {fileID: 0}
emojiHeart: {fileID: 0}
emojiPuke: {fileID: 0}
emojiAnger: {fileID: 0}
cardType: []
cursorTexture: {fileID: 0}
enemyMarker: {fileID: 0}
--- !u!1001 &1708098703
PrefabInstance:
m_ObjectHideFlags: 0
@ -14608,6 +14401,11 @@ PrefabInstance:
propertyPath: speed
value: 2000
objectReference: {fileID: 0}
- target: {fileID: 7810505435716704953, guid: 8c9e74631c8994b8cb728cde8efae49a,
type: 3}
propertyPath: height
value: 20
objectReference: {fileID: 0}
- target: {fileID: 7810505435716704953, guid: 8c9e74631c8994b8cb728cde8efae49a,
type: 3}
propertyPath: firePos
@ -15789,7 +15587,7 @@ PrefabInstance:
- target: {fileID: 1800824703194841433, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_LocalPosition.y
value: -13.2
value: -9.48
objectReference: {fileID: 0}
- target: {fileID: 1800824703194841433, guid: f228040d76c9217409284544f353da47,
type: 3}
@ -15831,11 +15629,46 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 2146763844810315378, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 2146763844810315378, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 2854089398056668840, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_LocalScale.x
value: 10
objectReference: {fileID: 0}
- target: {fileID: 2854089398056668840, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_LocalScale.z
value: 10
objectReference: {fileID: 0}
- target: {fileID: 4541625270423798677, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: m_Name
value: Boids
objectReference: {fileID: 0}
- target: {fileID: 5146900491857106217, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: escapeMode
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5146900491857106217, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: viewRadius
value: 20
objectReference: {fileID: 0}
- target: {fileID: 5146900491857106217, guid: f228040d76c9217409284544f353da47,
type: 3}
propertyPath: isDirectionChange
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
@ -16480,6 +16313,7 @@ SceneRoots:
- {fileID: 734248431}
- {fileID: 55264371}
- {fileID: 1806659892}
- {fileID: 1683670877}
- {fileID: 1540310984}
- {fileID: 2105062291}
- {fileID: 1560348101}

View File

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

View File

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

View File

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

View File

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

View File

@ -1,19 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/CombatAction")]
public class DieOfCombat : CombatAction
{
public override void OnStart()
{
combatAi.Die();
}
public override TaskStatus OnUpdate()
{
return TaskStatus.Success;
}
}
}

View File

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

View File

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

View File

@ -1,24 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/EnemyAction")]
public class AttackOfEnemy : EnemyAction
{
public override void OnStart()
{
enemyAi.Attack();
}
public override TaskStatus OnUpdate()
{
return enemyAi.GetIsAttackCoroutine() ? TaskStatus.Running : TaskStatus.Success;
}
public override void OnEnd()
{
StopAllCoroutines();
}
}
}

View File

@ -1,20 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/EnemyAction")]
public class BeAttackedOfEnemy : EnemyAction
{
public override TaskStatus OnUpdate()
{
if (enemyAi.GetCombatAgent().pathPending || enemyAi.GetCombatAgent().remainingDistance > enemyAi.GetCombatAgent().stoppingDistance)
{
return TaskStatus.Running;
}
enemyAi.SetBeAttacked(false, true);
return TaskStatus.Success;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d11582d2ef4686a45b306c5a93d70bb6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,19 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/EnemyAction")]
public class FindTargetOfEnemy : EnemyAction
{
public override void OnStart()
{
enemyAi.FindTarget();
}
public override TaskStatus OnUpdate()
{
return TaskStatus.Success;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: df8ebf14d54ec644f9203c1d3dcb3274
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,22 +0,0 @@
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/EnemyAction")]
public class InitBaseEnemy : EnemyAction
{
[RequiredField] public SharedAttackerType attackerType;
public override void OnStart()
{
attackerType.Value = enemyAi.EnemyStat.AttackerType;
}
public override TaskStatus OnUpdate()
{
return TaskStatus.Success;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 6b7c7916c685bf741ad0c84618c3ef00
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,22 +0,0 @@
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/EnemyAction")]
public class InitDefenseEnemy : EnemyAction
{
[RequiredField] public SharedGameObject myObj;
public override void OnStart()
{
myObj.Value = gameObject;
}
public override TaskStatus OnUpdate()
{
return TaskStatus.Success;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: cac9370c446b93e4e8a596c75db1ba1d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,19 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/EnemyAction")]
public class MoveTargetOfEnemy : EnemyAction
{
public override void OnStart()
{
enemyAi.MoveTargetInDefense(enemyAi.GetTargetTransform().position);
}
public override TaskStatus OnUpdate()
{
return TaskStatus.Success;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 8228d4b74ab4bcd47a4c2acfbb49441d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,19 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/EnemyAction")]
public class ReturnDefensePosOfEnemy : EnemyAction
{
public override void OnStart()
{
enemyAi.ReturnDefensePos(enemyAi.GetDefensePos());
}
public override TaskStatus OnUpdate()
{
return TaskStatus.Success;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 0984e3cb3464c4247922ba7d9eae2b71
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -1,14 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/EnemyConditional")]
public class CanAttackOfEnemy : EnemyConditional
{
public override TaskStatus OnUpdate()
{
return enemyAi.CanAttack() ? TaskStatus.Success : TaskStatus.Failure;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 2ce7d209551b49e4e802d662e4ca90eb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,14 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/EnemyConditional")]
public class CanComebackDefensePosOfEnemy : EnemyConditional
{
public override TaskStatus OnUpdate()
{
return enemyAi.transform.position != enemyAi.GetDefensePos() ? TaskStatus.Success : TaskStatus.Failure;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 272b142d6b035b948b8315474050f48b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

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

View File

@ -1,24 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/PirateAction")]
public class AttackOfPirate : PirateAction
{
public override void OnStart()
{
pirateAi.Attack();
}
public override TaskStatus OnUpdate()
{
return pirateAi.GetIsAttackCoroutine() ? TaskStatus.Running : TaskStatus.Success;
}
public override void OnEnd()
{
StopAllCoroutines();
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 152eaa40581591946884634c29014ed1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,19 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/PirateAction")]
public class FindTargetOfPirate : PirateAction
{
public override void OnStart()
{
pirateAi.FindTarget();
}
public override TaskStatus OnUpdate()
{
return TaskStatus.Success;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 67078393a27b3414fb475b36e0787001
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,23 +0,0 @@
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/PirateAction")]
public class InitBasePirate : PirateAction
{
[RequiredField] public SharedAttackerType attackerType;
public override void OnStart()
{
attackerType.Value = pirateAi.PirateStat.AttackerType;
}
public override TaskStatus OnUpdate()
{
return TaskStatus.Success;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 86c2cf9f56d3adf4ebadf9a0e1915e9a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,22 +0,0 @@
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/PirateAction")]
public class InitOffensePirate : PirateAction
{
[RequiredField] public SharedGameObject myObj;
public override void OnStart()
{
myObj.Value = gameObject;
}
public override TaskStatus OnUpdate()
{
return TaskStatus.Success;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: cfedbfa8c252b5648b9faf49acff2222
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,19 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/PirateAction")]
public class MoveTargetOfPirate : PirateAction
{
public override void OnStart()
{
pirateAi.MoveTarget(pirateAi.GetTargetTransform().position, GlobalValue.MAXIMUM_STOP_DISTANCE);
}
public override TaskStatus OnUpdate()
{
return TaskStatus.Success;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: b3be30dac4ab81d47a4313e506fbf7b8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -1,14 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[TaskCategory("Custom/PirateConditional")]
public class CanAttackOfPirate : PirateConditional
{
public override TaskStatus OnUpdate()
{
return pirateAi.CanAttack() ? TaskStatus.Success : TaskStatus.Failure;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 68fbf203f20f0444694fc0cd87678685
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

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

View File

@ -1,26 +0,0 @@
using BlueWaterProject;
// ReSharper disable once CheckNamespace
namespace BehaviorDesigner.Runtime.Tasks.Unity.SharedVariables
{
[TaskCategory("Unity/SharedVariable")]
[TaskDescription("Returns success if the variable value is equal to the compareTo value.")]
public class CompareSharedAiType : Conditional
{
[Tooltip("The first variable to compare")]
public SharedAiType variable;
[Tooltip("The variable to compare to")]
public SharedAiType compareTo;
public override TaskStatus OnUpdate()
{
return variable.Value.Equals(compareTo.Value) ? TaskStatus.Success : TaskStatus.Failure;
}
public override void OnReset()
{
variable = EAiType.NONE;
compareTo = EAiType.NONE;
}
}
}

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: e3fdf6e71e3deef46bb9ab0bcf3ea68e
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -1,26 +0,0 @@
using BlueWaterProject;
// ReSharper disable once CheckNamespace
namespace BehaviorDesigner.Runtime.Tasks.Unity.SharedVariables
{
[TaskCategory("Unity/SharedVariable")]
[TaskDescription("Returns success if the variable value is equal to the compareTo value.")]
public class CompareSharedAttackerType : Conditional
{
[Tooltip("The first variable to compare")]
public SharedAttackerType variable;
[Tooltip("The variable to compare to")]
public SharedAttackerType compareTo;
public override TaskStatus OnUpdate()
{
return variable.Value.Equals(compareTo.Value) ? TaskStatus.Success : TaskStatus.Failure;
}
public override void OnReset()
{
variable = EAttackerType.NONE;
compareTo = EAttackerType.NONE;
}
}
}

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 6a6c4dcf5ecd5494d84255dd2ea4a646
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

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

View File

@ -1,15 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class CombatAction : Action
{
protected CombatAi combatAi;
public override void OnAwake()
{
combatAi = GetComponent<CombatAi>();
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 7f96e64d7dffad149835e1501b362e91
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,15 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class EnemyAction : Action
{
protected EnemyAi enemyAi;
public override void OnAwake()
{
enemyAi = GetComponent<EnemyAi>();
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 84f9fa3fad1de6640a44b43f28baf46f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,15 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class EnemyConditional : Conditional
{
protected EnemyAi enemyAi;
public override void OnAwake()
{
enemyAi = GetComponent<EnemyAi>();
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 0ac6714e1a3da5e42b2433907ceace0c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,15 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class PirateAction : Action
{
protected PirateAi pirateAi;
public override void OnAwake()
{
pirateAi = GetComponent<PirateAi>();
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: ecb029565680f1d4694b164292599545
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,15 +0,0 @@
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class PirateConditional : Conditional
{
protected PirateAi pirateAi;
public override void OnAwake()
{
pirateAi = GetComponent<PirateAi>();
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 775faef187f436241b9bf4fae9115d48
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -1,18 +0,0 @@
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class IncreaseSharedInt : Action
{
public SharedInt targetInt;
public override TaskStatus OnUpdate()
{
targetInt.Value++;
return TaskStatus.Success;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 94aaede23a4430d42ae8ef55a1b21e9b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,26 +0,0 @@
using UnityEngine;
namespace BehaviorDesigner.Runtime.Tasks.Unity.UnityVector2
{
[TaskCategory("Unity/Vector2")]
[TaskDescription("Sets the value of the Vector2.")]
public class SetValue : Action
{
[Tooltip("The Vector2 to get the values of")]
public SharedVector2 vector2Value;
[Tooltip("The Vector2 to set the values of")]
public SharedVector2 vector2Variable;
public override TaskStatus OnUpdate()
{
vector2Variable.Value = vector2Value.Value;
return TaskStatus.Success;
}
public override void OnReset()
{
vector2Value = Vector2.zero;
vector2Variable = Vector2.zero;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 85d3b21532037744fa14ddebf47c3c74
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,11 +0,0 @@
// using BlueWaterProject;
//
// // ReSharper disable once CheckNamespace
// namespace BehaviorDesigner.Runtime
// {
// [System.Serializable]
// public class SharedAiStat : SharedVariable<AiStat>
// {
// public static implicit operator SharedAiStat(AiStat value) { return new SharedAiStat { mValue = value }; }
// }
// }

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 02ba639560737f44db74c938a6eaf769
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -1,11 +0,0 @@
using BlueWaterProject;
// ReSharper disable once CheckNamespace
namespace BehaviorDesigner.Runtime
{
[System.Serializable]
public class SharedAiType : SharedVariable<EAiType>
{
public static implicit operator SharedAiType(EAiType value) { return new SharedAiType { mValue = value }; }
}
}

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: a8a13c299691ac64ab6d467bb8e8932f
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -1,11 +0,0 @@
using BlueWaterProject;
// ReSharper disable once CheckNamespace
namespace BehaviorDesigner.Runtime
{
[System.Serializable]
public class SharedAttackerType : SharedVariable<EAttackerType>
{
public static implicit operator SharedAttackerType(EAttackerType value) { return new SharedAttackerType { mValue = value }; }
}
}

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: ff361707107fef94788b3ff999b21044
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -1,11 +0,0 @@
using BlueWaterProject;
// ReSharper disable once CheckNamespace
namespace BehaviorDesigner.Runtime
{
[System.Serializable]
public class SharedIslandInfo : SharedVariable<IslandInfo>
{
public static implicit operator SharedIslandInfo(IslandInfo value) { return new SharedIslandInfo { mValue = value }; }
}
}

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 6e23fcea0f1d6544db6c749d0bbb2de5
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

@ -1,12 +0,0 @@
using BlueWaterProject;
using UnityEngine.AI;
// ReSharper disable once CheckNamespace
namespace BehaviorDesigner.Runtime
{
[System.Serializable]
public class SharedNavMeshAgent : SharedVariable<NavMeshAgent>
{
public static implicit operator SharedNavMeshAgent(NavMeshAgent value) { return new SharedNavMeshAgent { mValue = value }; }
}
}

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 00580f11879e46d4998b60f02d843ba7
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:

View File

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

View File

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

View File

@ -1,195 +0,0 @@
using BehaviorDesigner.Runtime;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Animations;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public abstract class CombatAi : HumanAi
{
#region Properties and variables
// 일반 변수
[SerializeField] protected bool isDrawGizmosInFieldOfView = true;
[SerializeField] protected bool isAttacking;
[SerializeField] protected LayerMask targetLayer;
[SerializeField] protected Vector3 defensePos;
[SerializeField] protected Transform targetTransform;
[SerializeField] protected Collider[] colliderWithinRange = new Collider[TARGET_MAX_SIZE];
[SerializeField] protected IslandInfo attackingIslandInfo;
[SerializeField] protected IslandInfo defendingIslandInfo;
// 컴포넌트 관련 변수
protected Animator combatAnimator;
protected NavMeshAgent combatAgent;
protected CapsuleCollider myCollider;
protected CapsuleCollider hitBoxCollider;
protected LookAtConstraint lookAtConstraint;
protected BehaviorTree behaviorTree;
// 애니메이션 관련 변수
protected static readonly int SpeedHash = Animator.StringToHash("Speed");
protected static readonly int AttackHash = Animator.StringToHash("Attack");
protected static readonly int DamageHash = Animator.StringToHash("TakeDamage");
protected static readonly int DeathTypeHash = Animator.StringToHash("DeathType");
protected static readonly int DeathHash = Animator.StringToHash("Death");
protected static readonly int ShieldHash = Animator.StringToHash("Shield");
protected static readonly int OutlineColorHash = Shader.PropertyToID("_OutlineColor");
protected const int TARGET_MAX_SIZE = 30;
#endregion
#region Abstract methods
protected abstract void SetLayer();
protected abstract void SetCurrentHp(float value, bool useBehaviorTreeVariable = false);
protected abstract void RemoveAiListElement();
public abstract void FindTarget();
public abstract bool CanAttack();
public abstract void Attack();
#endregion
#region Unity built-in methods
protected override void Awake()
{
base.Awake();
FlagLookAtCamera();
SetLayer();
}
private void Update()
{
if (combatAnimator.runtimeAnimatorController != null && combatAnimator.isActiveAndEnabled)
{
combatAnimator.SetFloat(SpeedHash, combatAgent.velocity.magnitude);
}
UpdateLookAtTarget();
}
#endregion
#region Custom methods
protected override void InitComponent()
{
base.InitComponent();
combatAnimator = Utils.GetComponentAndAssert<Animator>(transform);
combatAgent = Utils.GetComponentAndAssert<NavMeshAgent>(transform);
myCollider = Utils.GetComponentAndAssert<CapsuleCollider>(transform);
hitBoxCollider = Utils.GetComponentAndAssert<CapsuleCollider>(transform.Find("HitBox"));
lookAtConstraint = Utils.GetComponentAndAssert<LookAtConstraint>(flagContainer);
}
protected void FlagLookAtCamera()
{
if (CameraManager.Inst.MainCam != null)
{
var source = new ConstraintSource
{
sourceTransform = CameraManager.Inst.MainCam.transform,
weight = 1f
};
lookAtConstraint.AddSource(source);
}
lookAtConstraint.constraintActive = true;
}
protected void SetBehaviorTree(ExternalBehaviorTree externalBehaviorTree)
{
if (!externalBehaviorTree)
{
print("externalBehaviorTree == null error");
}
var bt = gameObject.GetComponent<BehaviorTree>();
if (bt != null)
{
Destroy(bt);
}
behaviorTree = gameObject.AddComponent<BehaviorTree>();
behaviorTree.StartWhenEnabled = false;
behaviorTree.ExternalBehavior = externalBehaviorTree;
behaviorTree.EnableBehavior();
}
public void MoveTarget(Vector3 targetPos, float stopDistance)
{
if (Vector3.Distance(combatAgent.destination, targetPos) < 0.1f) return;
combatAgent.stoppingDistance = stopDistance;
combatAgent.SetDestination(targetPos);
}
private void UpdateLookAtTarget()
{
if (CanAttack())
{
combatAgent.updateRotation = false;
var targetPos = targetTransform.position;
targetPos.y = transform.position.y;
transform.LookAt(targetPos);
}
else
{
combatAgent.updateRotation = true;
}
}
public void SetTargetTransform(Transform value, bool useBehaviorTreeVariable = false)
{
targetTransform = value;
if (!useBehaviorTreeVariable) return;
Utils.SetBehaviorVariable(behaviorTree, "TargetTransform", value);
}
public void Die()
{
RemoveIslandInfo();
RemoveAiListElement();
StopAllCoroutines();
combatAgent.enabled = false;
myCollider.enabled = false;
hitBoxCollider.enabled = false;
var randomValue = Random.Range(0, 2);
combatAnimator.SetInteger(DeathTypeHash, randomValue);
// TODO : 죽었을 때 처리(죽는 애니메이션 이후 사라지는 효과 등)
combatAnimator.SetTrigger(DeathHash);
}
private void RemoveIslandInfo()
{
if (defendingIslandInfo == null) return;
defendingIslandInfo.RemoveListElement(defendingIslandInfo.EnemyList, transform);
defendingIslandInfo.RemoveListElement(defendingIslandInfo.ExceptHouseList, transform);
defendingIslandInfo.RemoveListElement(defendingIslandInfo.TargetAllList, transform);
}
protected void SetAnimatorController(string controllerName) => combatAnimator.runtimeAnimatorController =
UnitManager.Inst.AIAnimatorControllerList.Find(obj => obj.name == controllerName);
protected void SetMoveSpeed(float value) => combatAgent.speed = value;
public void SetAttackingIslandInfo(IslandInfo info) => attackingIslandInfo = info;
public void SetDefendingIslandInfo(IslandInfo info) => defendingIslandInfo = info;
public Transform GetTargetTransform() => targetTransform;
public Vector3 GetDefensePos() => defensePos;
public NavMeshAgent GetCombatAgent() => combatAgent;
#endregion
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 7d395879fb0a0d740910a879261f7383
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -1,429 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Random = UnityEngine.Random;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public abstract class EnemyAi : CombatAi, IDamageable
{
#region Properties and variables
[field: SerializeField] public EnemyStat EnemyStat { get; set; }
protected bool isAttackCoroutine;
private bool beAttacked;
private EnemyUnit enemyUnit;
private int childNum;
#endregion
#region Unit Built-in methods
protected virtual void OnDrawGizmosSelected()
{
if (!isDrawGizmosInFieldOfView) return;
if (EnemyStat.AttackerType == EAttackerType.OFFENSE)
{
if (!targetTransform) return;
Gizmos.color = Color.red;
Gizmos.DrawLine(transform.position, targetTransform.position);
}
else if (EnemyStat.AttackerType == EAttackerType.DEFENSE)
{
if (EnemyStat.DefenseType == EDefenseType.DEFENDER)
{
Gizmos.color = Color.red;
var startPos = Application.isPlaying ? defensePos : transform.position;
Gizmos.DrawWireSphere(startPos, EnemyStat.DefenseRange);
}
Gizmos.color = Color.blue;
Gizmos.DrawWireSphere(transform.position, EnemyStat.ViewRange);
if (!targetTransform) return;
Gizmos.color = Color.red;
Gizmos.DrawLine(transform.position, targetTransform.position);
}
}
private void Start()
{
InitStart();
}
#endregion
#region IDamageable interface
public void TakeDamage(float attackerPower, Vector3? attackPos = null)
{
if (attackPos != null && EnemyStat.AttackerType == EAttackerType.DEFENSE && !targetTransform)
{
BeAttackedMovement((Vector3)attackPos);
}
// 회피 성공 체크
if (Random.Range(0, 100) < EnemyStat.AvoidanceRate)
{
// TODO : 회피 처리
return;
}
var finalDamage = 0f;
if (EnemyStat.UsingShield)
{
// var penetrationChance = attackerShieldPenetrationRate -
// (attackerShieldPenetrationRate * EnemyStat.PenetrationResistivity * 0.01f);
//
// // 방패를 관통했다면,
// if (Random.Range(0, 100) < penetrationChance)
// {
// finalDamage = attackerPower - EnemyStat.Def;
// finalDamage = Mathf.Max(finalDamage, 0);
// }
// else
// {
// finalDamage = 0f;
// }
}
finalDamage = attackerPower - EnemyStat.Def;
finalDamage = Mathf.Max(finalDamage, 0);
// 방패 막기 체크
if (finalDamage == 0f)
{
combatAnimator.SetTrigger(ShieldHash);
return;
}
var changeHp = Mathf.Max(EnemyStat.CurrentHp - finalDamage, 0);
SetCurrentHp(changeHp, true);
// 죽었는지 체크
if (changeHp == 0f) return;
combatAnimator.SetTrigger(DamageHash);
}
#endregion
#region Custom methods
protected override void InitComponent()
{
base.InitComponent();
enemyUnit = Utils.GetComponentAndAssert<EnemyUnit>(transform.parent);
}
protected override void SetLayer()
{
gameObject.layer = LayerMask.NameToLayer("Enemy");
var hitBoxObj = hitBoxCollider.gameObject;
hitBoxObj.layer = LayerMask.NameToLayer("HitBox");
hitBoxObj.tag = "Enemy";
targetLayer = LayerMask.GetMask("Player") | LayerMask.GetMask("Pirate");
if (EnemyStat.AttackerType == EAttackerType.OFFENSE)
{
targetLayer |= LayerMask.GetMask("Props");
}
}
#if UNITY_EDITOR
public virtual void InitStartInEditor()
{
var enemyViewData = DataManager.Inst.GetEnemyViewSoFromKey(EnemyStat.ViewIdx);
InitComponent();
SetLayer();
InitViewModel(enemyViewData);
}
#endif
protected virtual void InitStart()
{
var enemyViewData = DataManager.Inst.GetEnemyViewDictionaryFromKey(EnemyStat.ViewIdx);
InitViewModel(enemyViewData);
SetBehaviorTree(UnitManager.Inst.EnemyBehaviorTree);
SetCurrentHp(EnemyStat.MaxHp, true);
SetMoveSpeed(EnemyStat.MoveSpd);
if (EnemyStat.AttackerType == EAttackerType.DEFENSE)
{
SetDefensePos(transform.position, true);
childNum = transform.GetSiblingIndex();
enemyUnit.SetDefensePos(defensePos, childNum);
}
}
private void InitViewModel(EnemyView enemyView)
{
SetActiveViewModel(backpackContainer, enemyView.Backpack);
SetActiveViewModel(leftWeaponContainer, enemyView.LeftWeapon);
SetActiveViewModel(leftShieldContainer, enemyView.LeftShield);
SetActiveViewModel(headContainer, enemyView.Head);
SetActiveViewModel(rightWeaponContainer, enemyView.RightWeapon);
SetActiveViewModel(bodyContainer, enemyView.Body);
SetActiveViewModel(flagContainer, enemyView.Flag);
}
public override void FindTarget()
{
switch (EnemyStat.AttackerType)
{
case EAttackerType.NONE:
print("EnemyStat.AttackerType == NONE Error");
break;
case EAttackerType.OFFENSE:
FindTargetInOffense();
break;
case EAttackerType.DEFENSE:
FindTargetInDefense();
break;
default:
throw new ArgumentOutOfRangeException();
}
}
public override bool CanAttack()
{
if (!targetTransform) return false;
var attackInRange = Vector3.Distance(transform.position, targetTransform.position) <= EnemyStat.AtkRange;
return attackInRange;
}
public override void Attack()
{
isAttackCoroutine = true;
StartCoroutine(nameof(AttackAnimation));
}
protected abstract IEnumerator AttackAnimation();
private void FindTargetInOffense()
{
if (!attackingIslandInfo)
{
print("attackingIslandInfo == null error");
return;
}
switch (EnemyStat.OffenseType)
{
case EOffenseType.NONE:
print("AiStat.OffenseType == NONE Error");
break;
case EOffenseType.NORMAL:
if (attackingIslandInfo.ExceptHouseList.Count > 0)
{
FindNearestTargetInList(attackingIslandInfo.ExceptHouseList);
}
else if (attackingIslandInfo.HouseList.Count > 0)
{
FindNearestTargetInList(attackingIslandInfo.HouseList);
}
break;
case EOffenseType.ONLY_HOUSE:
if (attackingIslandInfo.HouseList.Count > 0)
{
FindNearestTargetInList(attackingIslandInfo.HouseList);
}
else if (attackingIslandInfo.ExceptHouseList.Count > 0)
{
FindNearestTargetInList(attackingIslandInfo.ExceptHouseList);
}
break;
default:
throw new ArgumentOutOfRangeException();
}
}
protected virtual void FindNearestTargetInList(List<Transform> targetList)
{
if (targetList.Count <= 0) return;
var nearestTarget = targetList.OrderBy(t => t ?
Vector3.Distance(transform.position, t.position) : float.MaxValue).FirstOrDefault();
if (nearestTarget == null) return;
SetTargetTransform(nearestTarget, true);
}
private void FindTargetInDefense()
{
switch (EnemyStat.DefenseType)
{
case EDefenseType.NONE:
print("EnemyStat.DefenseType == NONE Error");
break;
case EDefenseType.STRIKER:
FindNearestTargetInRange(transform.position, EnemyStat.ViewRange);
break;
case EDefenseType.MIDFIELDER:
FindNearestTargetInRange(transform.position, EnemyStat.ViewRange);
break;
case EDefenseType.DEFENDER:
FindNearestTargetInRange(defensePos, EnemyStat.DefenseRange);
break;
case EDefenseType.KEEPER:
FindNearestTargetInRange(transform.position, EnemyStat.ViewRange);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
protected virtual void FindNearestTargetInRange(Vector3 centerPos, float range)
{
Array.Clear(colliderWithinRange, 0, TARGET_MAX_SIZE);
var maxColliderCount = Physics.OverlapSphereNonAlloc(centerPos, range, colliderWithinRange,
targetLayer, QueryTriggerInteraction.Collide);
if (maxColliderCount <= 0)
{
SetTargetTransform(null, true);
return;
}
var nearestDistance = Mathf.Infinity;
Transform nearestTargetTransform = null;
for (var i = 0; i < maxColliderCount; i++)
{
var distanceToTarget = Vector3.Distance(transform.position, colliderWithinRange[i].transform.position);
if (distanceToTarget >= nearestDistance) continue;
nearestDistance = distanceToTarget;
nearestTargetTransform = colliderWithinRange[i].transform;
}
SetTargetTransform(nearestTargetTransform, true);
}
public void MoveTargetInDefense(Vector3 targetPos)
{
switch (EnemyStat.DefenseType)
{
case EDefenseType.NONE:
print("EnemyStat.DefenseType == NONE error");
break;
case EDefenseType.STRIKER:
case EDefenseType.MIDFIELDER:
break;
case EDefenseType.DEFENDER:
if (Vector3.Distance(targetPos, defensePos) > EnemyStat.DefenseRange)
{
combatAgent.stoppingDistance = GlobalValue.MINIMUM_STOP_DISTANCE;
combatAgent.SetDestination(defensePos);
return;
}
break;
case EDefenseType.KEEPER:
return;
default:
throw new ArgumentOutOfRangeException();
}
if (Vector3.Distance(combatAgent.destination, targetPos) < 0.1f) return;
combatAgent.stoppingDistance = GlobalValue.MAXIMUM_STOP_DISTANCE;
combatAgent.SetDestination(targetPos);
}
public void ReturnDefensePos(Vector3 targetPos)
{
if (Vector3.Distance(combatAgent.destination, targetPos) < 0.1f) return;
combatAgent.stoppingDistance = GlobalValue.MINIMUM_STOP_DISTANCE;
combatAgent.SetDestination(targetPos);
}
protected override void SetCurrentHp(float value, bool useBehaviorTreeVariable = false)
{
EnemyStat.CurrentHp = value;
if (!useBehaviorTreeVariable) return;
Utils.SetBehaviorVariable(behaviorTree, "CurrentHp", value);
}
protected override void RemoveAiListElement()
{
if (enemyUnit.enemyUnitStat.EnemyAiList.Contains(this))
{
enemyUnit.enemyUnitStat.EnemyAiList.Remove(this);
}
enemyUnit.ResetDefensePos();
}
private void BeAttackedMovement(Vector3 attackPos)
{
switch (EnemyStat.DefenseType)
{
case EDefenseType.NONE:
print("EnemyStat.DefenseType == NONE Error");
break;
case EDefenseType.STRIKER:
case EDefenseType.MIDFIELDER:
break;
case EDefenseType.DEFENDER:
if (Vector3.Distance(defensePos, attackPos) > EnemyStat.DefenseRange) return;
break;
case EDefenseType.KEEPER:
return;
default:
throw new ArgumentOutOfRangeException();
}
foreach (var item in enemyUnit.enemyUnitStat.EnemyAiList)
{
if (item.GetTargetTransform()) continue;
item.SetBeAttacked(true, true);
item.MoveTarget(attackPos, GlobalValue.MAXIMUM_STOP_DISTANCE);
}
}
public void SetDefensePos(Vector3 value, bool useBehaviorTreeVariable = false)
{
defensePos = value;
if (!useBehaviorTreeVariable) return;
Utils.SetBehaviorVariable(behaviorTree, "DefensePos", value);
}
public void SetBeAttacked(bool value, bool useBehaviorTreeVariable = false)
{
beAttacked = value;
if (!useBehaviorTreeVariable) return;
Utils.SetBehaviorVariable(behaviorTree, "BeAttacked", value);
}
public bool GetIsAttackCoroutine() => isAttackCoroutine;
public void SetAttackerType(EAttackerType type) => EnemyStat.AttackerType = type;
public void SetOffenseType(EOffenseType type) => EnemyStat.OffenseType = type;
public void SetDefenseType(EDefenseType type) => EnemyStat.DefenseType = type;
#endregion
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 9bc95105830b2294d9941f686fc2f0ba
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,174 +0,0 @@
using System;
using Sirenix.OdinInspector;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[Serializable]
public class EnemyStat : IIdx
{
#region Property and variable
[field: Tooltip("고유 인덱스")]
[field: SerializeField] public string Idx { get; set; }
[field: Tooltip("캐릭터 모델 인덱스")]
[field: SerializeField] public string ViewIdx { get; set; }
[field: Tooltip("Ai 종류")]
[field: SerializeField] public GlobalValue.UnitType UnitType { 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; }
[field: Tooltip("캐릭터 현재 체력")]
[field: SerializeField] public float CurrentHp { get; set; }
[field: Tooltip("공격력")]
[field: SerializeField] public float Atk { get; set; }
[field: Tooltip("방어력")]
[field: SerializeField] public float Def { get; set; }
[field: Tooltip("이동속도")]
[field: SerializeField] public float MoveSpd { get; set; }
[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; }
[field: Tooltip("공격을 피할 수 있는 회피율")]
[field: Range(0, 100)]
[field: SerializeField] public int AvoidanceRate { get; set; }
[field: Tooltip("캐릭터의 방패 사용 유무")]
[field: SerializeField] public bool UsingShield { get; set; }
[field: Tooltip("방패 캐릭터가 관통 당할 확률을 줄여주는 관통 저항률")]
[field: ShowIf("@UsingShield == true")]
[field: Range(0, 100)]
[field: SerializeField] public int PenetrationResistivity { get; set; }
[field: Tooltip("캐릭터의 활 사용 유무")]
[field: SerializeField] public bool UsingBow { get; set; }
[field: Tooltip("화살이 타겟에 도달하는 오차 범위(부정확함)")]
[field: ShowIf("@UsingBow == true")]
[field: Range(0, 5f)]
[field: SerializeField] public float Inaccuracy { get; set; }
#endregion
#region Constructor
/// <summary>
/// 기본 생성자
/// </summary>
public EnemyStat()
{
Idx = null;
ViewIdx = null;
UnitType = GlobalValue.UnitType.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;
PenetrationResistivity = 0;
UsingBow = false;
Inaccuracy = 0;
}
/// <summary>
/// 일반 생성자
/// </summary>
public EnemyStat(string idx, string viewIdx, GlobalValue.UnitType unitType, 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;
MaxHp = maxHp;
CurrentHp = currentHp;
Atk = atk;
Def = def;
MoveSpd = moveSpd;
AtkCooldown = atkCooldown;
ViewRange = viewRange;
AtkRange = atkRange;
DefenseRange = defenseRange;
ShieldPenetrationRate = shieldPenetrationRate;
AvoidanceRate = avoidanceRate;
UsingShield = usingShield;
PenetrationResistivity = penetrationResistivity;
UsingBow = usingBow;
Inaccuracy = inaccuracy;
}
/// <summary>
/// 복사 생성자
/// </summary>
public EnemyStat(EnemyStat enemyStat)
{
Idx = enemyStat.Idx;
ViewIdx = enemyStat.ViewIdx;
UnitType = enemyStat.UnitType;
AttackerType = enemyStat.AttackerType;
OffenseType = enemyStat.OffenseType;
DefenseType = enemyStat.DefenseType;
MaxHp = enemyStat.MaxHp;
CurrentHp = enemyStat.CurrentHp;
Atk = enemyStat.Atk;
Def = enemyStat.Def;
MoveSpd = enemyStat.MoveSpd;
AtkCooldown = enemyStat.AtkCooldown;
ViewRange = enemyStat.ViewRange;
AtkRange = enemyStat.AtkRange;
DefenseRange = enemyStat.DefenseRange;
ShieldPenetrationRate = enemyStat.ShieldPenetrationRate;
AvoidanceRate = enemyStat.AvoidanceRate;
UsingShield = enemyStat.UsingShield;
PenetrationResistivity = enemyStat.PenetrationResistivity;
UsingBow = enemyStat.UsingBow;
Inaccuracy = enemyStat.Inaccuracy;
}
#endregion
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 4c8366e51a915e1428ed891371635918
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,87 +0,0 @@
using System;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[Serializable]
public class EnemyView : IIdx
{
#region Property and variable
[field: Tooltip("고유 인덱스")]
[field: SerializeField] public string Idx { get; set; }
[field: Tooltip("등에 메고 다닐 모델\n화살통 등")]
[field: SerializeField] public int Backpack { get; set; }
[field: Tooltip("왼손 무기 모델\n활, 스태프 등")]
[field: SerializeField] public int LeftWeapon { get; set; }
[field: Tooltip("왼손 방패 모델")]
[field: SerializeField] public int LeftShield { get; set; }
[field: Tooltip("머리 전체 모델")]
[field: SerializeField] public int Head { get; set; }
[field: Tooltip("오른손 무기 모델\n왼손 무기를 제외한 무기 등")]
[field: SerializeField] public int RightWeapon { get; set; }
[field: Tooltip("몸통 및 팔, 다리 전체 모델")]
[field: SerializeField] public int Body { get; set; }
[field: Tooltip("부대 깃발 모델")]
[field: SerializeField] public int Flag { get; set; }
#endregion
#region Constructor
/// <summary>
/// 기본 생성자
/// </summary>
public EnemyView()
{
Idx = null;
Backpack = -1;
LeftWeapon = -1;
LeftShield = -1;
Head = -1;
RightWeapon = -1;
Body = -1;
Flag = -1;
}
/// <summary>
/// 일반 생성자
/// </summary>
public EnemyView(string idx, int backpack, int leftWeapon, int leftShield, int head, int rightWeapon, int body, int flag)
{
Idx = idx;
Backpack = backpack;
LeftWeapon = leftWeapon;
LeftShield = leftShield;
Head = head;
RightWeapon = rightWeapon;
Body = body;
Flag = flag;
}
/// <summary>
/// 복사 생성자
/// </summary>
public EnemyView(EnemyView enemyView)
{
Idx = enemyView.Idx;
Backpack = enemyView.Backpack;
LeftWeapon = enemyView.LeftWeapon;
LeftShield = enemyView.LeftShield;
Head = enemyView.Head;
RightWeapon = enemyView.RightWeapon;
Body = enemyView.Body;
Flag = enemyView.Flag;
}
#endregion
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 594e11827de1c1b4c8f08e75516453f1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -1,230 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Pool;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class EnemyArcher : EnemyAi
{
#region Property and variable
[Header("화살 오브젝트 관리")]
[Tooltip("화살 오브젝트 풀링할 최대 갯수")]
[SerializeField] private int arrowMaxSize = 100;
[Tooltip("화살 발사 후 오브젝트 저장될 위치")]
[SerializeField] private Transform arrowsPoolLocation;
[SerializeField] private LayerMask arrowLayer;
private IEnumerator shootArrowCoroutine;
private IObjectPool<Arrow> arrowPool;
[SerializeField] private Vector3 rayOffset = new(0f, 3.5f, 0);
#endregion
#region Unity built-in methods
protected override void OnDrawGizmosSelected()
{
if (!isDrawGizmosInFieldOfView) return;
if (EnemyStat.AttackerType == EAttackerType.OFFENSE)
{
if (!targetTransform) return;
Gizmos.color = Color.red;
Gizmos.DrawLine(transform.position + rayOffset, targetTransform.position + rayOffset);
}
else if (EnemyStat.AttackerType == EAttackerType.DEFENSE)
{
if (EnemyStat.DefenseType == EDefenseType.DEFENDER)
{
Gizmos.color = Color.red;
var startPos = Application.isPlaying ? defensePos : transform.position;
Gizmos.DrawWireSphere(startPos, EnemyStat.DefenseRange);
}
Gizmos.color = Color.blue;
Gizmos.DrawWireSphere(transform.position, EnemyStat.ViewRange);
if (!targetTransform) return;
Gizmos.color = Color.red;
Gizmos.DrawLine(transform.position + rayOffset, targetTransform.position + rayOffset);
}
}
#endregion
#region Custom methods
protected override void InitComponent()
{
base.InitComponent();
var animatorControllerList = UnitManager.Inst.AIAnimatorControllerList;
if (animatorControllerList == null)
{
Debug.LogError("Animator Controller List is null!");
return;
}
var archerController = animatorControllerList.Find(obj => obj.name == "Archer");
if (archerController == null)
{
Debug.LogError("No AnimatorController named 'Archer' was found in the list.");
return;
}
combatAnimator.runtimeAnimatorController = archerController;
arrowsPoolLocation = GameObject.Find("ObjectPoolData/Arrows")?.transform;
if (!arrowsPoolLocation)
{
var objectPoolData = GameObject.Find("ObjectPoolData")?.transform;
if (!objectPoolData)
{
objectPoolData = new GameObject("ObjectPoolData").transform;
}
if (!objectPoolData.Find("Arrows"))
{
Instantiate(new GameObject("Arrows"), Vector3.zero, Quaternion.identity, objectPoolData);
}
}
arrowPool = new ObjectPool<Arrow>(CreateArrow, OnGetArrow, OnReleaseArrow, OnDestroyArrow, maxSize:arrowMaxSize);
}
protected override void SetLayer()
{
base.SetLayer();
arrowLayer = LayerMask.GetMask("Ground") | LayerMask.GetMask("Water") |
LayerMask.GetMask("Player") | LayerMask.GetMask("Pirate") |
LayerMask.GetMask("Props");
}
protected override void InitStart()
{
base.InitStart();
SetAnimatorController("Archer");
}
protected override void FindNearestTargetInList(List<Transform> targetList)
{
if (targetList.Count <= 0) return;
var myPos = transform.position;
var nearestTarget = targetList.OrderBy(t => t && IsRaycastHitTarget(myPos, t) ?
Vector3.Distance(myPos, t.position) :
float.MaxValue).FirstOrDefault();
if (nearestTarget == null) return;
SetTargetTransform(nearestTarget, true);
}
protected override void FindNearestTargetInRange(Vector3 centerPos, float range)
{
Array.Clear(colliderWithinRange, 0, TARGET_MAX_SIZE);
var maxColliderCount = Physics.OverlapSphereNonAlloc(centerPos, range, colliderWithinRange,
targetLayer, QueryTriggerInteraction.Collide);
if (maxColliderCount <= 0)
{
SetTargetTransform(null, true);
return;
}
var nearestDistance = Mathf.Infinity;
Transform nearestTargetTransform = null;
var myPos = transform.position;
for (var i = 0; i < maxColliderCount; i++)
{
var distanceToTarget = Vector3.Distance(myPos, colliderWithinRange[i].transform.position);
if (!IsRaycastHitTarget(myPos, colliderWithinRange[i].transform) || distanceToTarget >= nearestDistance) continue;
nearestDistance = distanceToTarget;
nearestTargetTransform = colliderWithinRange[i].transform;
}
SetTargetTransform(nearestTargetTransform, true);
}
private bool IsRaycastHitTarget(Vector3 myPos, Transform target)
{
var direction = ((target.position + rayOffset) - (myPos + rayOffset)).normalized;
var raycastHitTarget = Physics.Raycast(myPos + rayOffset, direction, out var hit, EnemyStat.AtkRange, arrowLayer, QueryTriggerInteraction.Collide);
return raycastHitTarget && target == hit.transform;
}
protected override IEnumerator AttackAnimation()
{
combatAnimator.SetTrigger(AttackHash);
while (isAttacking)
{
yield return null;
}
yield return new WaitForSeconds(EnemyStat.AtkCooldown);
isAttackCoroutine = false;
}
/// <summary>
/// Archer attack 애니메이션에 event 부착용 함수
/// </summary>
public void OnShootArrow()
{
if (!targetTransform) return;
var arrow = arrowPool.Get();
var isOffense = EnemyStat.AttackerType == EAttackerType.OFFENSE;
arrow.SetShootingArrow(leftWeaponContainer.position, transform.position,
targetTransform.position + rayOffset, EAiType.ENEMY, EnemyStat.Atk, EnemyStat.ShieldPenetrationRate, EnemyStat.Inaccuracy, isOffense);
arrow.ShootArrowCoroutine();
}
/// <summary>
/// Archer attack 애니메이션에 event 부착용 함수
/// </summary>
public void OnStoppedMove(int boolValue)
{
if (!combatAgent.enabled) return;
combatAgent.isStopped = boolValue == 1;
}
private void OnAttacking(int boolValue) => isAttacking = boolValue == 1;
#endregion
#region ObjectPool Function
private Arrow CreateArrow()
{
var arrow = Instantiate(UnitManager.Inst.ArrowPrefab, leftWeaponContainer.position, Quaternion.identity, arrowsPoolLocation).GetComponent<Arrow>();
arrow.SetManagedPool(arrowPool);
return arrow;
}
private void OnGetArrow(Arrow arrow) => arrow.gameObject.SetActive(true);
private void OnReleaseArrow(Arrow arrow) => arrow.ReleaseArrowSetting();
private void OnDestroyArrow(Arrow arrow) => Destroy(arrow.gameObject);
#endregion
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 3f93377933923904282d8a32d7b6dcd8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,70 +0,0 @@
using System.Collections;
using Unity.VisualScripting;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class EnemySpearKnight : EnemyAi
{
#region Properties and variables
private CloseWeapon closeWeapon;
#endregion
#region Custrom methods
#if UNITY_EDITOR
public override void InitStartInEditor()
{
base.InitStartInEditor();
SetCloseWeapon();
}
#endif
protected override void InitStart()
{
base.InitStart();
SetAnimatorController("SpearKnight");
SetCloseWeapon();
}
private void SetCloseWeapon()
{
var rightWeaponView = Application.isPlaying ?
DataManager.Inst.GetEnemyViewDictionaryFromKey(EnemyStat.ViewIdx).RightWeapon :
DataManager.Inst.GetEnemyViewSoFromKey(EnemyStat.ViewIdx).RightWeapon;
if (rightWeaponView == -1) return;
closeWeapon = rightWeaponContainer.GetChild(rightWeaponView).AddComponent<CloseWeapon>();
var closeWeaponObj = closeWeapon.gameObject;
closeWeaponObj.layer = LayerMask.NameToLayer("Weapon");
closeWeaponObj.tag = "Enemy";
closeWeapon.SetAttackerAiType(EAiType.ENEMY);
closeWeapon.SetBoxCollider();
}
protected override IEnumerator AttackAnimation()
{
closeWeapon.SetIsAttacked(false);
closeWeapon.SetWeaponStat(EnemyStat.Atk, EnemyStat.ShieldPenetrationRate, EnemyStat.AttackerType == EAttackerType.OFFENSE);
combatAnimator.SetTrigger(AttackHash);
while (isAttacking)
{
yield return null;
}
yield return new WaitForSeconds(EnemyStat.AtkCooldown);
isAttackCoroutine = false;
}
private void SetCloseWeaponCanAttack(int boolValue) => closeWeapon.SetCanAttack(boolValue == 1);
private void OnAttacking(int boolValue) => isAttacking = boolValue == 1;
#endregion
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 3081b5da8eafc39478ee39b61bd01249
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,70 +0,0 @@
using System.Collections;
using Unity.VisualScripting;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class EnemySpearman : EnemyAi
{
#region Properties and variables
private CloseWeapon closeWeapon;
#endregion
#region Custrom methods
#if UNITY_EDITOR
public override void InitStartInEditor()
{
base.InitStartInEditor();
SetCloseWeapon();
}
#endif
protected override void InitStart()
{
base.InitStart();
SetAnimatorController("Spearman");
SetCloseWeapon();
}
private void SetCloseWeapon()
{
var rightWeaponView = Application.isPlaying ?
DataManager.Inst.GetEnemyViewDictionaryFromKey(EnemyStat.ViewIdx).RightWeapon :
DataManager.Inst.GetEnemyViewSoFromKey(EnemyStat.ViewIdx).RightWeapon;
if (rightWeaponView == -1) return;
closeWeapon = rightWeaponContainer.GetChild(rightWeaponView).AddComponent<CloseWeapon>();
var closeWeaponObj = closeWeapon.gameObject;
closeWeaponObj.layer = LayerMask.NameToLayer("Weapon");
closeWeaponObj.tag = "Enemy";
closeWeapon.SetAttackerAiType(EAiType.ENEMY);
closeWeapon.SetBoxCollider();
}
protected override IEnumerator AttackAnimation()
{
closeWeapon.SetIsAttacked(false);
closeWeapon.SetWeaponStat(EnemyStat.Atk, EnemyStat.ShieldPenetrationRate, EnemyStat.AttackerType == EAttackerType.OFFENSE);
combatAnimator.SetTrigger(AttackHash);
while (isAttacking)
{
yield return null;
}
yield return new WaitForSeconds(EnemyStat.AtkCooldown);
isAttackCoroutine = false;
}
private void SetCloseWeaponCanAttack(int boolValue) => closeWeapon.SetCanAttack(boolValue == 1);
private void OnAttacking(int boolValue) => isAttacking = boolValue == 1;
#endregion
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: c14f537594d346b408093acb546136d8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,70 +0,0 @@
using System.Collections;
using Unity.VisualScripting;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class EnemySwordKnight : EnemyAi
{
#region Properties and variables
private CloseWeapon closeWeapon;
#endregion
#region Custrom methods
#if UNITY_EDITOR
public override void InitStartInEditor()
{
base.InitStartInEditor();
SetCloseWeapon();
}
#endif
protected override void InitStart()
{
base.InitStart();
SetAnimatorController("SwordKnight");
SetCloseWeapon();
}
private void SetCloseWeapon()
{
var rightWeaponView = Application.isPlaying ?
DataManager.Inst.GetEnemyViewDictionaryFromKey(EnemyStat.ViewIdx).RightWeapon :
DataManager.Inst.GetEnemyViewSoFromKey(EnemyStat.ViewIdx).RightWeapon;
if (rightWeaponView == -1) return;
closeWeapon = rightWeaponContainer.GetChild(rightWeaponView).AddComponent<CloseWeapon>();
var closeWeaponObj = closeWeapon.gameObject;
closeWeaponObj.layer = LayerMask.NameToLayer("Weapon");
closeWeaponObj.tag = "Enemy";
closeWeapon.SetAttackerAiType(EAiType.ENEMY);
closeWeapon.SetBoxCollider();
}
protected override IEnumerator AttackAnimation()
{
closeWeapon.SetIsAttacked(false);
closeWeapon.SetWeaponStat(EnemyStat.Atk, EnemyStat.ShieldPenetrationRate, EnemyStat.AttackerType == EAttackerType.OFFENSE);
combatAnimator.SetTrigger(AttackHash);
while (isAttacking)
{
yield return null;
}
yield return new WaitForSeconds(EnemyStat.AtkCooldown);
isAttackCoroutine = false;
}
private void SetCloseWeaponCanAttack(int boolValue) => closeWeapon.SetCanAttack(boolValue == 1);
private void OnAttacking(int boolValue) => isAttacking = boolValue == 1;
#endregion
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 215148f883898b34a99799d0ad0236e5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,70 +0,0 @@
using System.Collections;
using Unity.VisualScripting;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class EnemySwordman : EnemyAi
{
#region Properties and variables
private CloseWeapon closeWeapon;
#endregion
#region Custrom methods
#if UNITY_EDITOR
public override void InitStartInEditor()
{
base.InitStartInEditor();
SetCloseWeapon();
}
#endif
protected override void InitStart()
{
base.InitStart();
SetAnimatorController("Swordman");
SetCloseWeapon();
}
private void SetCloseWeapon()
{
var rightWeaponView = Application.isPlaying ?
DataManager.Inst.GetEnemyViewDictionaryFromKey(EnemyStat.ViewIdx).RightWeapon :
DataManager.Inst.GetEnemyViewSoFromKey(EnemyStat.ViewIdx).RightWeapon;
if (rightWeaponView == -1) return;
closeWeapon = rightWeaponContainer.GetChild(rightWeaponView).AddComponent<CloseWeapon>();
var closeWeaponObj = closeWeapon.gameObject;
closeWeaponObj.layer = LayerMask.NameToLayer("Weapon");
closeWeaponObj.tag = "Enemy";
closeWeapon.SetAttackerAiType(EAiType.ENEMY);
closeWeapon.SetBoxCollider();
}
protected override IEnumerator AttackAnimation()
{
closeWeapon.SetIsAttacked(false);
closeWeapon.SetWeaponStat(EnemyStat.Atk, EnemyStat.ShieldPenetrationRate, EnemyStat.AttackerType == EAttackerType.OFFENSE);
combatAnimator.SetTrigger(AttackHash);
while (isAttacking)
{
yield return null;
}
yield return new WaitForSeconds(EnemyStat.AtkCooldown);
isAttackCoroutine = false;
}
private void SetCloseWeaponCanAttack(int boolValue) => closeWeapon.SetCanAttack(boolValue == 1);
private void OnAttacking(int boolValue) => isAttacking = boolValue == 1;
#endregion
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 3bf2b5b70d0f63e40b3dddbd22c90c84
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -1,439 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using UnityEngine;
using Random = UnityEngine.Random;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public abstract class PirateAi : CombatAi, IDamageable
{
#region Properties and variables
[Title("Skin")]
[Tooltip("SkinnedMeshRenderer, MeshRenderer의 Material을 모두 담고 있는 리스트")]
[SerializeField] protected List<Material> skinMaterialList = new(10);
[Tooltip("캐릭터 외곽선의 기본 색상")]
[SerializeField] protected Color defaultSkinColor = Color.black;
[Tooltip("캐릭터에 마우스 커서가 올라가 있을 때 색상")]
[SerializeField] protected Color mouseEnterHighlightSkinColor = Color.white;
[Tooltip("캐릭터가 선택되었을 때 색상")]
[SerializeField] protected Color selectedSkinColor = Color.red;
[field: SerializeField] public PirateStat PirateStat { get; set; }
private PirateUnit pirateUnit;
private PirateUnit mouseEnterPirateUnit;
private UnitSelection unitSelection;
[SerializeField] protected bool isAttackCoroutine;
[SerializeField] private bool isCommanded;
#endregion
#region Unit Built-in methods
protected virtual void OnDrawGizmosSelected()
{
if (!isDrawGizmosInFieldOfView) return;
if (PirateStat.AttackerType == EAttackerType.OFFENSE)
{
if (!targetTransform) return;
Gizmos.color = Color.red;
Gizmos.DrawLine(transform.position, targetTransform.position);
}
else if (PirateStat.AttackerType == EAttackerType.DEFENSE)
{
if (PirateStat.DefenseType == EDefenseType.DEFENDER)
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(defensePos, PirateStat.DefenseRange);
}
Gizmos.color = Color.blue;
Gizmos.DrawWireSphere(transform.position, PirateStat.ViewRange);
if (!targetTransform) return;
Gizmos.color = Color.red;
Gizmos.DrawLine(transform.position, targetTransform.position);
}
}
private void OnMouseEnter()
{
if (!unitSelection || !unitSelection.IsSelectable) return;
mouseEnterPirateUnit = gameObject.GetComponentInParent<PirateUnit>();
if (mouseEnterPirateUnit == unitSelection.SelectedPirateUnit) return;
foreach (var pirateAi in mouseEnterPirateUnit.pirateUnitStat.PirateAiList)
{
pirateAi.MouseEnterHighlight();
}
}
private void OnMouseExit()
{
if (!unitSelection || !unitSelection.IsSelectable ||
!mouseEnterPirateUnit || mouseEnterPirateUnit == unitSelection.SelectedPirateUnit) return;
foreach (var pirateAi in mouseEnterPirateUnit.pirateUnitStat.PirateAiList)
{
pirateAi.ResetHighlight();
}
mouseEnterPirateUnit = null;
}
private void Start()
{
InitStart();
}
#endregion
#region IDamageable interface
public void TakeDamage(float attackerPower, Vector3? attackPos = null)
{
if (attackPos != null && combatAgent.enabled && PirateStat.AttackerType == EAttackerType.DEFENSE && !targetTransform)
{
// BeAttackedMovement((Vector3)attackPos);
}
// 회피 성공 체크
if (Random.Range(0, 100) < PirateStat.AvoidanceRate)
{
// TODO : 회피 처리
return;
}
var finalDamage = 0f;
if (PirateStat.UsingShield)
{
// var penetrationChance = attackerShieldPenetrationRate -
// (attackerShieldPenetrationRate * PirateStat.PenetrationResistivity * 0.01f);
//
// // 방패를 관통했다면,
// if (Random.Range(0, 100) < penetrationChance)
// {
// finalDamage = attackerPower - PirateStat.Def;
// finalDamage = Mathf.Max(finalDamage, 0);
// }
// else
// {
// finalDamage = 0f;
// }
}
finalDamage = attackerPower - PirateStat.Def;
finalDamage = Mathf.Max(finalDamage, 0);
// 방패 막기 체크
if (finalDamage == 0f)
{
combatAnimator.SetTrigger(ShieldHash);
return;
}
var changeHp = Mathf.Max(PirateStat.CurrentHp - finalDamage, 0);
SetCurrentHp(changeHp, true);
// 죽었는지 체크
if (changeHp == 0f) return;
combatAnimator.SetTrigger(DamageHash);
}
#endregion
#region Custom methods
protected override void InitComponent()
{
base.InitComponent();
pirateUnit = Utils.GetComponentAndAssert<PirateUnit>(transform.parent);
unitSelection = Utils.GetComponentAndAssert<UnitSelection>(GameObject.Find("UnitManager").transform);
}
protected override void SetLayer()
{
gameObject.layer = LayerMask.NameToLayer("Pirate");
var hitBoxObj = hitBoxCollider.gameObject;
hitBoxObj.layer = LayerMask.NameToLayer("HitBox");
hitBoxObj.tag = "Pirate";
targetLayer = LayerMask.GetMask("Enemy");
if (PirateStat.AttackerType == EAttackerType.OFFENSE)
{
targetLayer |= LayerMask.GetMask("Props");
}
}
protected virtual void InitStart()
{
var pirateViewData = DataManager.Inst.GetPirateViewDictionaryFromKey(PirateStat.ViewIdx);
InitViewModel(pirateViewData);
FindMaterial();
SetBehaviorTree(UnitManager.Inst.PirateBehaviorTree);
SetCurrentHp(PirateStat.MaxHp, true);
SetMoveSpeed(PirateStat.MoveSpd);
if (PirateStat.AttackerType == EAttackerType.DEFENSE)
{
defensePos = transform.position;
}
}
private void InitViewModel(PirateView pirateView)
{
SetActiveViewModel(backpackContainer, pirateView.Backpack);
SetActiveViewModel(leftWeaponContainer, pirateView.LeftWeapon);
SetActiveViewModel(leftShieldContainer, pirateView.LeftShield);
SetActiveViewModel(headContainer, pirateView.Head);
SetActiveViewModel(rightWeaponContainer, pirateView.RightWeapon);
SetActiveViewModel(bodyContainer, pirateView.Body);
SetActiveViewModel(flagContainer, pirateView.Flag);
}
private void FindMaterial()
{
var skinnedMeshRenderers = GetComponentsInChildren<SkinnedMeshRenderer>();
var meshRenderers = GetComponentsInChildren<MeshRenderer>();
foreach (var skin in skinnedMeshRenderers)
{
if (!skin.gameObject.activeSelf) continue;
skinMaterialList.Add(skin.material);
}
foreach (var skin in meshRenderers)
{
if (!skin.gameObject.activeSelf) continue;
skinMaterialList.Add(skin.material);
}
}
public void CommandMoveTarget(Vector3 movePos)
{
StartCoroutine(CommandMoveCoroutine(movePos));
}
private IEnumerator CommandMoveCoroutine(Vector3 movePos)
{
while (isAttacking)
{
yield return null;
}
combatAgent.stoppingDistance = GlobalValue.MAXIMUM_STOP_DISTANCE;
combatAgent.SetDestination(movePos);
SetIsCommanded(true, true);
while (combatAgent.pathPending || combatAgent.remainingDistance > combatAgent.stoppingDistance)
{
yield return null;
}
SetIsCommanded(false, true);
}
public override void FindTarget()
{
switch (PirateStat.AttackerType)
{
case EAttackerType.NONE:
print("PirateStat.AttackerType == NONE Error");
break;
case EAttackerType.OFFENSE:
FindTargetInOffense();
break;
case EAttackerType.DEFENSE:
FindTargetInDefense();
break;
default:
throw new ArgumentOutOfRangeException();
}
}
public override bool CanAttack()
{
if (!targetTransform) return false;
var attackInRange = Vector3.Distance(transform.position, targetTransform.position) <= PirateStat.AtkRange;
return attackInRange;
}
public override void Attack()
{
isAttackCoroutine = true;
StartCoroutine(nameof(AttackAnimation));
}
protected abstract IEnumerator AttackAnimation();
private void FindTargetInOffense()
{
if (!attackingIslandInfo)
{
print("attackingIslandInfo == null error");
return;
}
switch (PirateStat.OffenseType)
{
case EOffenseType.NONE:
print("AiStat.OffenseType == NONE Error");
break;
case EOffenseType.NORMAL:
if (attackingIslandInfo.ExceptHouseList.Count > 0)
{
FindNearestTargetInList(attackingIslandInfo.ExceptHouseList);
}
else if (attackingIslandInfo.HouseList.Count > 0)
{
FindNearestTargetInList(attackingIslandInfo.HouseList);
}
break;
case EOffenseType.ONLY_HOUSE:
if (attackingIslandInfo.HouseList.Count > 0)
{
FindNearestTargetInList(attackingIslandInfo.HouseList);
}
else if (attackingIslandInfo.ExceptHouseList.Count > 0)
{
FindNearestTargetInList(attackingIslandInfo.ExceptHouseList);
}
break;
default:
throw new ArgumentOutOfRangeException();
}
}
protected virtual void FindNearestTargetInList(List<Transform> targetList)
{
if (targetList.Count <= 0) return;
var nearestTarget = targetList.OrderBy(t => t ?
Vector3.Distance(transform.position, t.position) : float.MaxValue).FirstOrDefault();
if (nearestTarget == null) return;
SetTargetTransform(nearestTarget, true);
}
private void FindTargetInDefense()
{
switch (PirateStat.DefenseType)
{
case EDefenseType.NONE:
print("EnemyStat.DefenseType == NONE Error");
break;
case EDefenseType.STRIKER:
FindNearestTargetInRange(transform.position, PirateStat.ViewRange);
break;
case EDefenseType.MIDFIELDER:
FindNearestTargetInRange(transform.position, PirateStat.ViewRange);
break;
case EDefenseType.DEFENDER:
FindNearestTargetInRange(defensePos, PirateStat.DefenseRange);
break;
case EDefenseType.KEEPER:
FindNearestTargetInRange(transform.position, PirateStat.ViewRange);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
protected virtual void FindNearestTargetInRange(Vector3 centerPos, float range)
{
Array.Clear(colliderWithinRange, 0, TARGET_MAX_SIZE);
var maxColliderCount = Physics.OverlapSphereNonAlloc(centerPos, range, colliderWithinRange,
targetLayer, QueryTriggerInteraction.Collide);
if (maxColliderCount <= 0)
{
SetTargetTransform(null, true);
return;
}
var nearestDistance = Mathf.Infinity;
Transform nearestTargetTransform = null;
for (var i = 0; i < maxColliderCount; i++)
{
var distanceToTarget = Vector3.Distance(transform.position, colliderWithinRange[i].transform.position);
if (distanceToTarget >= nearestDistance) continue;
nearestDistance = distanceToTarget;
nearestTargetTransform = colliderWithinRange[i].transform;
}
SetTargetTransform(nearestTargetTransform, true);
}
private void SetOutlineColor(Color color)
{
foreach (var skin in skinMaterialList)
{
skin.SetColor(OutlineColorHash, color);
}
}
public void SetIsCommanded(bool value, bool useBehaviorTreeVariable = false)
{
isCommanded = value;
if (!useBehaviorTreeVariable) return;
Utils.SetBehaviorVariable(behaviorTree, "IsCommanded", value);
}
protected override void SetCurrentHp(float value, bool useBehaviorTreeVariable = false)
{
PirateStat.CurrentHp = value;
if (!useBehaviorTreeVariable) return;
Utils.SetBehaviorVariable(behaviorTree, "CurrentHp", value);
}
protected override void RemoveAiListElement()
{
if (pirateUnit.pirateUnitStat.PirateAiList.Contains(this))
{
pirateUnit.pirateUnitStat.PirateAiList.Remove(this);
}
}
public bool GetIsAttackCoroutine() => isAttackCoroutine;
public bool GetIsCommanded() => isCommanded;
public void SetAttackerType(EAttackerType type) => PirateStat.AttackerType = type;
public void SetOffenseType(EOffenseType type) => PirateStat.OffenseType = type;
public void SetDefenseType(EDefenseType type) => PirateStat.DefenseType = type;
public void ResetHighlight() => SetOutlineColor(defaultSkinColor);
public void MouseEnterHighlight() => SetOutlineColor(mouseEnterHighlightSkinColor);
public void SelectedHighlight() => SetOutlineColor(selectedSkinColor);
#endregion
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: e86a27e3e99581c4c93d65fa02fdcdb5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,174 +0,0 @@
using System;
using Sirenix.OdinInspector;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
[Serializable]
public class PirateStat : IIdx
{
#region Property and variable
[field: Tooltip("고유 인덱스")]
[field: SerializeField] public string Idx { get; set; }
[field: Tooltip("캐릭터 모델 인덱스")]
[field: SerializeField] public string ViewIdx { get; set; }
[field: Tooltip("Ai 종류")]
[field: SerializeField] public GlobalValue.UnitType UnitType { 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; }
[field: Tooltip("캐릭터 현재 체력")]
[field: SerializeField] public float CurrentHp { get; set; }
[field: Tooltip("공격력")]
[field: SerializeField] public float Atk { get; set; }
[field: Tooltip("방어력")]
[field: SerializeField] public float Def { get; set; }
[field: Tooltip("이동속도")]
[field: SerializeField] public float MoveSpd { get; set; }
[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; }
[field: Tooltip("공격을 피할 수 있는 회피율")]
[field: Range(0, 100)]
[field: SerializeField] public int AvoidanceRate { get; set; }
[field: Tooltip("캐릭터의 방패 사용 유무")]
[field: SerializeField] public bool UsingShield { get; set; }
[field: Tooltip("방패 캐릭터가 관통 당할 확률을 줄여주는 관통 저항률")]
[field: ShowIf("@UsingShield == true")]
[field: Range(0, 100)]
[field: SerializeField] public int PenetrationResistivity { get; set; }
[field: Tooltip("캐릭터의 활 사용 유무")]
[field: SerializeField] public bool UsingBow { get; set; }
[field: Tooltip("화살이 타겟에 도달하는 오차 범위(부정확함)")]
[field: ShowIf("@UsingBow == true")]
[field: Range(0, 5f)]
[field: SerializeField] public float Inaccuracy { get; set; }
#endregion
#region Constructor
/// <summary>
/// 기본 생성자
/// </summary>
public PirateStat()
{
Idx = null;
ViewIdx = null;
UnitType = GlobalValue.UnitType.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;
PenetrationResistivity = 0;
UsingBow = false;
Inaccuracy = 0;
}
/// <summary>
/// 일반 생성자
/// </summary>
public PirateStat(string idx, string viewIdx, GlobalValue.UnitType unitType, 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;
MaxHp = maxHp;
CurrentHp = currentHp;
Atk = atk;
Def = def;
MoveSpd = moveSpd;
AtkCooldown = atkCooldown;
ViewRange = viewRange;
AtkRange = atkRange;
DefenseRange = defenseRange;
ShieldPenetrationRate = shieldPenetrationRate;
AvoidanceRate = avoidanceRate;
UsingShield = usingShield;
PenetrationResistivity = penetrationResistivity;
UsingBow = usingBow;
Inaccuracy = inaccuracy;
}
/// <summary>
/// 복사 생성자
/// </summary>
public PirateStat(PirateStat pirateStat)
{
Idx = pirateStat.Idx;
ViewIdx = pirateStat.ViewIdx;
UnitType = pirateStat.UnitType;
AttackerType = pirateStat.AttackerType;
OffenseType = pirateStat.OffenseType;
DefenseType = pirateStat.DefenseType;
MaxHp = pirateStat.MaxHp;
CurrentHp = pirateStat.CurrentHp;
Atk = pirateStat.Atk;
Def = pirateStat.Def;
MoveSpd = pirateStat.MoveSpd;
AtkCooldown = pirateStat.AtkCooldown;
ViewRange = pirateStat.ViewRange;
AtkRange = pirateStat.AtkRange;
DefenseRange = pirateStat.DefenseRange;
ShieldPenetrationRate = pirateStat.ShieldPenetrationRate;
AvoidanceRate = pirateStat.AvoidanceRate;
UsingShield = pirateStat.UsingShield;
PenetrationResistivity = pirateStat.PenetrationResistivity;
UsingBow = pirateStat.UsingBow;
Inaccuracy = pirateStat.Inaccuracy;
}
#endregion
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: affbf90a87d7aa74ea6c4326fa3a9656
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More