From 2d7232ed0cb115d7c15776da283e1939cd3b32e7 Mon Sep 17 00:00:00 2001 From: Jens Pitkanen Date: Sun, 4 Aug 2019 18:35:24 +0300 Subject: [PATCH] Add melee enemy --- Assets/Scenes/MainScene.unity | 366 +++++++++++------- Assets/Scripts/AI/BehaviourBranch.cs | 2 + Assets/Scripts/AI/Behaviours/Follow.cs | 21 +- .../AI/Behaviours/MeleeAttackFollowed.cs | 80 ++++ .../AI/Behaviours/MeleeAttackFollowed.cs.meta | 11 + Assets/Scripts/{ => AI}/EnemyFollower.cs | 0 Assets/Scripts/{ => AI}/EnemyFollower.cs.meta | 2 +- Assets/Scripts/AI/PlayerFollower.cs | 18 + Assets/Scripts/AI/PlayerFollower.cs.meta | 11 + Assets/Scripts/AI/Triggers/PlayerSighted.cs | 13 + .../Scripts/AI/Triggers/PlayerSighted.cs.meta | 11 + Assets/Scripts/Bullets/RevolverBullet.cs | 2 +- Assets/Scripts/Util.cs | 29 +- ProjectSettings/TagManager.asset | 3 +- 14 files changed, 421 insertions(+), 148 deletions(-) create mode 100644 Assets/Scripts/AI/Behaviours/MeleeAttackFollowed.cs create mode 100644 Assets/Scripts/AI/Behaviours/MeleeAttackFollowed.cs.meta rename Assets/Scripts/{ => AI}/EnemyFollower.cs (100%) rename Assets/Scripts/{ => AI}/EnemyFollower.cs.meta (83%) create mode 100644 Assets/Scripts/AI/PlayerFollower.cs create mode 100644 Assets/Scripts/AI/PlayerFollower.cs.meta create mode 100644 Assets/Scripts/AI/Triggers/PlayerSighted.cs create mode 100644 Assets/Scripts/AI/Triggers/PlayerSighted.cs.meta diff --git a/Assets/Scenes/MainScene.unity b/Assets/Scenes/MainScene.unity index b7bc3af..51d6e75 100644 --- a/Assets/Scenes/MainScene.unity +++ b/Assets/Scenes/MainScene.unity @@ -120,6 +120,37 @@ NavMeshSettings: debug: m_Flags: 0 m_NavMeshData: {fileID: 0} +--- !u!1 &61637923 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 61637924} + m_Layer: 0 + m_Name: AnimationRoot + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &61637924 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 61637923} + 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_Children: + - {fileID: 490037238} + m_Father: {fileID: 895097236} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &162528936 GameObject: m_ObjectHideFlags: 0 @@ -154,7 +185,7 @@ MonoBehaviour: m_GameObject: {fileID: 162528936} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 10bbd1a0d6cdfe747980a222ff5625b2, type: 3} + m_Script: {fileID: 11500000, guid: c119fe08cf5d2da43a8d58e6439195b3, type: 3} m_Name: m_EditorClassIdentifier: Follow: {fileID: 162528939} @@ -187,6 +218,7 @@ MonoBehaviour: CurrentStatus: Target: {fileID: 0} CloseEnoughRadius: 1 + TargetPositionUpdateFrequency: 5 --- !u!114 &162528940 MonoBehaviour: m_ObjectHideFlags: 0 @@ -1035,6 +1067,87 @@ Tilemap: m_ObjectToInstantiate: {fileID: 0} m_TileFlags: 1 m_ColliderType: 1 + - first: {x: -2, y: 2, z: 0} + second: + m_TileIndex: 13 + m_TileSpriteIndex: 13 + m_TileMatrixIndex: 0 + m_TileColorIndex: 8 + m_ObjectToInstantiate: {fileID: 0} + m_TileFlags: 1 + m_ColliderType: 1 + - first: {x: -1, y: 2, z: 0} + second: + m_TileIndex: 13 + m_TileSpriteIndex: 13 + m_TileMatrixIndex: 0 + m_TileColorIndex: 8 + m_ObjectToInstantiate: {fileID: 0} + m_TileFlags: 1 + m_ColliderType: 1 + - first: {x: 0, y: 2, z: 0} + second: + m_TileIndex: 14 + m_TileSpriteIndex: 14 + m_TileMatrixIndex: 0 + m_TileColorIndex: 8 + m_ObjectToInstantiate: {fileID: 0} + m_TileFlags: 1 + m_ColliderType: 1 + - first: {x: 1, y: 2, z: 0} + second: + m_TileIndex: 14 + m_TileSpriteIndex: 14 + m_TileMatrixIndex: 0 + m_TileColorIndex: 8 + m_ObjectToInstantiate: {fileID: 0} + m_TileFlags: 1 + m_ColliderType: 1 + - first: {x: 2, y: 2, z: 0} + second: + m_TileIndex: 14 + m_TileSpriteIndex: 14 + m_TileMatrixIndex: 0 + m_TileColorIndex: 8 + m_ObjectToInstantiate: {fileID: 0} + m_TileFlags: 1 + m_ColliderType: 1 + - first: {x: 3, y: 2, z: 0} + second: + m_TileIndex: 14 + m_TileSpriteIndex: 14 + m_TileMatrixIndex: 0 + m_TileColorIndex: 8 + m_ObjectToInstantiate: {fileID: 0} + m_TileFlags: 1 + m_ColliderType: 1 + - first: {x: 4, y: 2, z: 0} + second: + m_TileIndex: 14 + m_TileSpriteIndex: 14 + m_TileMatrixIndex: 0 + m_TileColorIndex: 8 + m_ObjectToInstantiate: {fileID: 0} + m_TileFlags: 1 + m_ColliderType: 1 + - first: {x: 5, y: 2, z: 0} + second: + m_TileIndex: 14 + m_TileSpriteIndex: 14 + m_TileMatrixIndex: 0 + m_TileColorIndex: 8 + m_ObjectToInstantiate: {fileID: 0} + m_TileFlags: 1 + m_ColliderType: 1 + - first: {x: 6, y: 2, z: 0} + second: + m_TileIndex: 14 + m_TileSpriteIndex: 14 + m_TileMatrixIndex: 0 + m_TileColorIndex: 8 + m_ObjectToInstantiate: {fileID: 0} + m_TileFlags: 1 + m_ColliderType: 1 m_AnimatedTiles: {} m_TileAssetArray: - m_RefCount: 0 @@ -1063,9 +1176,9 @@ Tilemap: m_Data: {fileID: 0} - m_RefCount: 0 m_Data: {fileID: 0} - - m_RefCount: 0 - m_Data: {fileID: 0} - - m_RefCount: 6 + - m_RefCount: 2 + m_Data: {fileID: 11400000, guid: bafa49c09188b224cb96cc5219e71fe2, type: 2} + - m_RefCount: 13 m_Data: {fileID: 11400000, guid: feb24d6900738d146ab6c5ecbb272804, type: 2} m_TileSpriteArray: - m_RefCount: 0 @@ -1095,13 +1208,14 @@ Tilemap: m_Data: {fileID: 0} - m_RefCount: 0 m_Data: {fileID: 0} - - m_RefCount: 0 - m_Data: {fileID: 0} - - m_RefCount: 6 + - m_RefCount: 2 + m_Data: {fileID: 8040196581939011165, guid: 3b5f43ce65db7e74f9d3a906dfc2c460, + type: 3} + - m_RefCount: 13 m_Data: {fileID: -6936079216851816805, guid: 3b5f43ce65db7e74f9d3a906dfc2c460, type: 3} m_TileMatrixArray: - - m_RefCount: 65 + - m_RefCount: 74 m_Data: e00: 1 e01: 0 @@ -1136,7 +1250,7 @@ Tilemap: m_Data: {r: 0, g: 0, b: 0, a: 0} - m_RefCount: 0 m_Data: {r: 0, g: 0, b: 0, a: 0} - - m_RefCount: 65 + - m_RefCount: 74 m_Data: {r: 1, g: 1, b: 1, a: 1} m_AnimationFrameRate: 1 m_Color: {r: 1, g: 1, b: 1, a: 1} @@ -1435,7 +1549,7 @@ Transform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] - m_Father: {fileID: 895097236} + m_Father: {fileID: 61637924} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!212 &490037239 @@ -1475,9 +1589,9 @@ SpriteRenderer: m_LightmapParameters: {fileID: 0} m_SortingLayerID: -947994997 m_SortingLayer: 3 - m_SortingOrder: 0 + m_SortingOrder: 1 m_Sprite: {fileID: 21300000, guid: 472874229c563e241bddc073ec2dbb90, type: 3} - m_Color: {r: 1, g: 1, b: 1, a: 1} + m_Color: {r: 0.7873081, g: 1, b: 0.6839622, a: 1} m_FlipX: 0 m_FlipY: 0 m_DrawMode: 0 @@ -1502,7 +1616,7 @@ GameObject: - component: {fileID: 628992545} m_Layer: 0 m_Name: Walls - m_TagString: Untagged + m_TagString: Environment m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 @@ -1719,15 +1833,6 @@ Tilemap: m_TileFlags: 1 m_ColliderType: 1 - first: {x: 5, y: 0, z: 0} - second: - m_TileIndex: 7 - m_TileSpriteIndex: 7 - m_TileMatrixIndex: 0 - m_TileColorIndex: 8 - m_ObjectToInstantiate: {fileID: 0} - m_TileFlags: 1 - m_ColliderType: 1 - - first: {x: 6, y: 0, z: 0} second: m_TileIndex: 14 m_TileSpriteIndex: 14 @@ -1754,24 +1859,6 @@ Tilemap: m_ObjectToInstantiate: {fileID: 0} m_TileFlags: 1 m_ColliderType: 1 - - first: {x: -2, y: 1, z: 0} - second: - m_TileIndex: 10 - m_TileSpriteIndex: 10 - m_TileMatrixIndex: 0 - m_TileColorIndex: 8 - m_ObjectToInstantiate: {fileID: 0} - m_TileFlags: 1 - m_ColliderType: 1 - - first: {x: 6, y: 1, z: 0} - second: - m_TileIndex: 13 - m_TileSpriteIndex: 13 - m_TileMatrixIndex: 0 - m_TileColorIndex: 8 - m_ObjectToInstantiate: {fileID: 0} - m_TileFlags: 1 - m_ColliderType: 1 - first: {x: -6, y: 2, z: 0} second: m_TileIndex: 9 @@ -1790,87 +1877,6 @@ Tilemap: m_ObjectToInstantiate: {fileID: 0} m_TileFlags: 1 m_ColliderType: 1 - - first: {x: -2, y: 2, z: 0} - second: - m_TileIndex: 11 - m_TileSpriteIndex: 11 - m_TileMatrixIndex: 0 - m_TileColorIndex: 8 - m_ObjectToInstantiate: {fileID: 0} - m_TileFlags: 1 - m_ColliderType: 1 - - first: {x: -1, y: 2, z: 0} - second: - m_TileIndex: 7 - m_TileSpriteIndex: 7 - m_TileMatrixIndex: 0 - m_TileColorIndex: 8 - m_ObjectToInstantiate: {fileID: 0} - m_TileFlags: 1 - m_ColliderType: 1 - - first: {x: 0, y: 2, z: 0} - second: - m_TileIndex: 7 - m_TileSpriteIndex: 7 - m_TileMatrixIndex: 0 - m_TileColorIndex: 8 - m_ObjectToInstantiate: {fileID: 0} - m_TileFlags: 1 - m_ColliderType: 1 - - first: {x: 1, y: 2, z: 0} - second: - m_TileIndex: 7 - m_TileSpriteIndex: 7 - m_TileMatrixIndex: 0 - m_TileColorIndex: 8 - m_ObjectToInstantiate: {fileID: 0} - m_TileFlags: 1 - m_ColliderType: 1 - - first: {x: 2, y: 2, z: 0} - second: - m_TileIndex: 7 - m_TileSpriteIndex: 7 - m_TileMatrixIndex: 0 - m_TileColorIndex: 8 - m_ObjectToInstantiate: {fileID: 0} - m_TileFlags: 1 - m_ColliderType: 1 - - first: {x: 3, y: 2, z: 0} - second: - m_TileIndex: 7 - m_TileSpriteIndex: 7 - m_TileMatrixIndex: 0 - m_TileColorIndex: 8 - m_ObjectToInstantiate: {fileID: 0} - m_TileFlags: 1 - m_ColliderType: 1 - - first: {x: 4, y: 2, z: 0} - second: - m_TileIndex: 7 - m_TileSpriteIndex: 7 - m_TileMatrixIndex: 0 - m_TileColorIndex: 8 - m_ObjectToInstantiate: {fileID: 0} - m_TileFlags: 1 - m_ColliderType: 1 - - first: {x: 5, y: 2, z: 0} - second: - m_TileIndex: 7 - m_TileSpriteIndex: 7 - m_TileMatrixIndex: 0 - m_TileColorIndex: 8 - m_ObjectToInstantiate: {fileID: 0} - m_TileFlags: 1 - m_ColliderType: 1 - - first: {x: 6, y: 2, z: 0} - second: - m_TileIndex: 14 - m_TileSpriteIndex: 14 - m_TileMatrixIndex: 0 - m_TileColorIndex: 8 - m_ObjectToInstantiate: {fileID: 0} - m_TileFlags: 1 - m_ColliderType: 1 m_AnimatedTiles: {} m_TileAssetArray: - m_RefCount: 0 @@ -1887,21 +1893,21 @@ Tilemap: m_Data: {fileID: 0} - m_RefCount: 0 m_Data: {fileID: 0} - - m_RefCount: 15 + - m_RefCount: 7 m_Data: {fileID: 11400000, guid: 2004c99dc125dd542aafd24f4ad842f4, type: 2} - m_RefCount: 0 m_Data: {fileID: 0} - m_RefCount: 1 m_Data: {fileID: 11400000, guid: d71c3f314fe54f141b9df7c5699b66ab, type: 2} - - m_RefCount: 4 - m_Data: {fileID: 11400000, guid: 3a266bd53dfebcf479f723737979e62d, type: 2} - m_RefCount: 3 + m_Data: {fileID: 11400000, guid: 3a266bd53dfebcf479f723737979e62d, type: 2} + - m_RefCount: 2 m_Data: {fileID: 11400000, guid: bf9ccb7cbc24ca346944cfd6efb15bf6, type: 2} - m_RefCount: 1 m_Data: {fileID: 11400000, guid: b673d03227bc8f74eab4645216e9d2a4, type: 2} - - m_RefCount: 4 - m_Data: {fileID: 11400000, guid: 607b380a0644eb9438d6f72c3c8434c5, type: 2} - m_RefCount: 3 + m_Data: {fileID: 11400000, guid: 607b380a0644eb9438d6f72c3c8434c5, type: 2} + - m_RefCount: 2 m_Data: {fileID: 11400000, guid: 4bbf78a58bd67f246927f19ce84be3fd, type: 2} m_TileSpriteArray: - m_RefCount: 0 @@ -1918,7 +1924,7 @@ Tilemap: m_Data: {fileID: 0} - m_RefCount: 0 m_Data: {fileID: 0} - - m_RefCount: 15 + - m_RefCount: 7 m_Data: {fileID: 6408231970667830406, guid: 3b5f43ce65db7e74f9d3a906dfc2c460, type: 3} - m_RefCount: 0 @@ -1926,22 +1932,22 @@ Tilemap: - m_RefCount: 1 m_Data: {fileID: 5441223297315994465, guid: 3b5f43ce65db7e74f9d3a906dfc2c460, type: 3} - - m_RefCount: 4 + - m_RefCount: 3 m_Data: {fileID: -8025435653959805260, guid: 3b5f43ce65db7e74f9d3a906dfc2c460, type: 3} - - m_RefCount: 3 + - m_RefCount: 2 m_Data: {fileID: -7869403223043187030, guid: 3b5f43ce65db7e74f9d3a906dfc2c460, type: 3} - m_RefCount: 1 m_Data: {fileID: -6108889420429456849, guid: 3b5f43ce65db7e74f9d3a906dfc2c460, type: 3} - - m_RefCount: 4 + - m_RefCount: 3 m_Data: {fileID: -6315978382755026507, guid: 3b5f43ce65db7e74f9d3a906dfc2c460, type: 3} - - m_RefCount: 3 + - m_RefCount: 2 m_Data: {fileID: 511961965738296472, guid: 3b5f43ce65db7e74f9d3a906dfc2c460, type: 3} m_TileMatrixArray: - - m_RefCount: 31 + - m_RefCount: 19 m_Data: e00: 1 e01: 0 @@ -1976,7 +1982,7 @@ Tilemap: m_Data: {r: 0, g: 0, b: 0, a: 0} - m_RefCount: 0 m_Data: {r: 0, g: 0, b: 0, a: 0} - - m_RefCount: 31 + - m_RefCount: 19 m_Data: {r: 1, g: 1, b: 1, a: 1} m_AnimationFrameRate: 1 m_Color: {r: 1, g: 1, b: 1, a: 1} @@ -2149,7 +2155,7 @@ MonoBehaviour: m_GameObject: {fileID: 867100008} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 10bbd1a0d6cdfe747980a222ff5625b2, type: 3} + m_Script: {fileID: 11500000, guid: c119fe08cf5d2da43a8d58e6439195b3, type: 3} m_Name: m_EditorClassIdentifier: Follow: {fileID: 867100016} @@ -2182,6 +2188,7 @@ MonoBehaviour: CurrentStatus: Target: {fileID: 0} CloseEnoughRadius: 1 + TargetPositionUpdateFrequency: 5 --- !u!114 &867100017 MonoBehaviour: m_ObjectHideFlags: 0 @@ -2228,7 +2235,12 @@ GameObject: - component: {fileID: 895097240} - component: {fileID: 895097239} - component: {fileID: 895097238} + - component: {fileID: 895097244} - component: {fileID: 895097237} + - component: {fileID: 895097243} + - component: {fileID: 895097241} + - component: {fileID: 895097242} + - component: {fileID: 895097245} m_Layer: 0 m_Name: Enemy (Default Melee) m_TagString: Untagged @@ -2308,10 +2320,10 @@ Transform: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 895097232} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: -0.43, y: -2.53, z: 0} + m_LocalPosition: {x: -0.14, y: -1.57, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: - - {fileID: 490037238} + - {fileID: 61637924} m_Father: {fileID: 0} m_RootOrder: 6 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -2358,8 +2370,9 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: bbf2158cd27572e4599b4c813f555fd8, type: 3} m_Name: m_EditorClassIdentifier: - Trigger: {fileID: 0} - TriggeredNodes: [] + Trigger: {fileID: 895097241} + TriggeredNodes: + - {fileID: 895097244} NotTriggeredNodes: - {fileID: 895097238} --- !u!114 &895097240 @@ -2377,6 +2390,83 @@ MonoBehaviour: MoveSpeed: 1 BehaviourTree: {fileID: 895097239} CurrentBehavior: Nothing +--- !u!114 &895097241 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 895097232} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 173be6658a5fcba49b9b1f1c91fa5f33, type: 3} + m_Name: + m_EditorClassIdentifier: + Radius: 3 +--- !u!114 &895097242 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 895097232} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f7e23822f429fcc46a8fd9163e68f332, type: 3} + m_Name: + m_EditorClassIdentifier: + CurrentStatus: + Target: {fileID: 0} + CloseEnoughRadius: 1 + TargetPositionUpdateFrequency: 2 +--- !u!114 &895097243 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 895097232} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6e805202a073c5541acd3aa2bde26513, type: 3} + m_Name: + m_EditorClassIdentifier: + Follow: {fileID: 895097242} + PlayerSighted: {fileID: 895097241} +--- !u!114 &895097244 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 895097232} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 163f55033e69e2e4282c151e1a806bc6, type: 3} + m_Name: + m_EditorClassIdentifier: + Behaviours: + - {fileID: 895097245} + - {fileID: 895097242} +--- !u!114 &895097245 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 895097232} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3195d7385bc331f4296251042082af39, type: 3} + m_Name: + m_EditorClassIdentifier: + CurrentStatus: + Follow: {fileID: 895097242} + AnimatableTransform: {fileID: 61637924} + MeleeRange: 1.3 + AttackAnimationLength: 0.1 + ReleaseAnimationLength: 0.25 + CooldownLength: 0.7 --- !u!1 &963194225 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/AI/BehaviourBranch.cs b/Assets/Scripts/AI/BehaviourBranch.cs index 66a0009..39942af 100644 --- a/Assets/Scripts/AI/BehaviourBranch.cs +++ b/Assets/Scripts/AI/BehaviourBranch.cs @@ -5,6 +5,8 @@ namespace Saltosion.OneWeapon.AI { [Serializable] public class BehaviourBranch : BehaviourNode { public Trigger Trigger; + // FIXME: Change these from arrays to just single ones + // BehaviourLeaf already has the capability to have multiple behaviours public BehaviourNode[] TriggeredNodes; public BehaviourNode[] NotTriggeredNodes; diff --git a/Assets/Scripts/AI/Behaviours/Follow.cs b/Assets/Scripts/AI/Behaviours/Follow.cs index 97ec6df..3e2080e 100644 --- a/Assets/Scripts/AI/Behaviours/Follow.cs +++ b/Assets/Scripts/AI/Behaviours/Follow.cs @@ -4,16 +4,31 @@ namespace Saltosion.OneWeapon.AI.Behaviours { public class Follow : AIBehaviour { public Transform Target; public float CloseEnoughRadius; + public float TargetPositionUpdateFrequency = 5f; + + private Vector2 TargetPosition; + private float TargetPositionUpdateCooldown; + + private void Update() { + + if (Target != null && TargetPositionUpdateCooldown <= 0) { + TargetPositionUpdateCooldown = 1.0f / TargetPositionUpdateFrequency; + TargetPosition = Target.position; + } else if (Target == null) { + TargetPositionUpdateCooldown = 0.0f; + } else { + TargetPositionUpdateCooldown -= Time.deltaTime; + } + } public override bool CanBehave(Enemy subject) { - return true; + return Target != null; } public override bool Execute(Enemy subject) { if (Target != null) { Vector2 position = subject.transform.position; - Vector2 targetPosition = Target.position; - Vector2 delta = targetPosition - position; + Vector2 delta = TargetPosition - position; if (delta.magnitude > CloseEnoughRadius) { delta -= delta.normalized * CloseEnoughRadius; subject.StartMovingTo(position + delta); diff --git a/Assets/Scripts/AI/Behaviours/MeleeAttackFollowed.cs b/Assets/Scripts/AI/Behaviours/MeleeAttackFollowed.cs new file mode 100644 index 0000000..2b8aade --- /dev/null +++ b/Assets/Scripts/AI/Behaviours/MeleeAttackFollowed.cs @@ -0,0 +1,80 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace Saltosion.OneWeapon.AI.Behaviours { + public class MeleeAttackFollowed : AIBehaviour { + public Follow Follow; + [Tooltip("This should be at 0,0,0 locally by default.")] + public Transform AnimatableTransform; + public float MeleeRange; + public float AttackAnimationLength; + public float ReleaseAnimationLength; + public float CooldownLength; + + private bool AttackHit; + private float AnimationProgress; + private float CooldownProgress; + private Vector3 LocalOrigin; + + private void Start() { + if (AnimatableTransform.localPosition.magnitude != 0) { + Debug.LogWarning($"{name} has an animated melee attack, and AnimatableTransform is not at local origin!"); + } + LocalOrigin = AnimatableTransform.localPosition; + Reset(); + } + + private void Reset() { + AttackHit = false; + AnimationProgress = 0.0f; + CooldownProgress = 1.0f; + AnimatableTransform.localPosition = LocalOrigin; + } + + private void Update() { + if (CooldownProgress > 0) { + CurrentStatus = "Cooldown"; + CooldownProgress -= Time.deltaTime / CooldownLength; + } + } + + public override bool CanBehave(Enemy subject) { + return Follow.Target != null && (Follow.Target.position - subject.transform.position).magnitude <= MeleeRange; + } + + public override bool Execute(Enemy subject) { + if (CooldownProgress > 0) { + return false; + } + + Vector2 Root = AnimatableTransform.parent.position + LocalOrigin; + Vector2 Target = Follow.Target.transform.position; + if (!AttackHit) { + CurrentStatus = "Hit"; + AnimationProgress += Time.deltaTime / AttackAnimationLength; + AnimatableTransform.position = Vector2.Lerp(Root, Target, AnimationProgress); + if (AnimationProgress >= 1.0f) { + // Attack hit, deal damage and start return animation + AttackHit = true; + AnimationProgress = 0.0f; + } + } else { + CurrentStatus = "Retreat"; + AnimationProgress += Time.deltaTime / ReleaseAnimationLength; + AnimatableTransform.position = Vector2.Lerp(Target, Root, AnimationProgress); + if (AnimationProgress >= 1.0f) { + // Attack finished, reset + Reset(); + } + } + + return false; + } + + private void OnDrawGizmosSelected() { + Gizmos.color = Color.red; + Gizmos.DrawWireSphere(transform.position, MeleeRange); + } + } +} diff --git a/Assets/Scripts/AI/Behaviours/MeleeAttackFollowed.cs.meta b/Assets/Scripts/AI/Behaviours/MeleeAttackFollowed.cs.meta new file mode 100644 index 0000000..38076f8 --- /dev/null +++ b/Assets/Scripts/AI/Behaviours/MeleeAttackFollowed.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3195d7385bc331f4296251042082af39 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/EnemyFollower.cs b/Assets/Scripts/AI/EnemyFollower.cs similarity index 100% rename from Assets/Scripts/EnemyFollower.cs rename to Assets/Scripts/AI/EnemyFollower.cs diff --git a/Assets/Scripts/EnemyFollower.cs.meta b/Assets/Scripts/AI/EnemyFollower.cs.meta similarity index 83% rename from Assets/Scripts/EnemyFollower.cs.meta rename to Assets/Scripts/AI/EnemyFollower.cs.meta index a3b1b95..2a09d2f 100644 --- a/Assets/Scripts/EnemyFollower.cs.meta +++ b/Assets/Scripts/AI/EnemyFollower.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 10bbd1a0d6cdfe747980a222ff5625b2 +guid: c119fe08cf5d2da43a8d58e6439195b3 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Scripts/AI/PlayerFollower.cs b/Assets/Scripts/AI/PlayerFollower.cs new file mode 100644 index 0000000..65d60f9 --- /dev/null +++ b/Assets/Scripts/AI/PlayerFollower.cs @@ -0,0 +1,18 @@ +using UnityEngine; +using Saltosion.OneWeapon.AI; + +namespace Saltosion.OneWeapon { + [RequireComponent(typeof(AI.Behaviours.Follow), typeof(AI.Triggers.PlayerSighted))] + public class PlayerFollower : MonoBehaviour { + public AI.Behaviours.Follow Follow; + public AI.Triggers.PlayerSighted PlayerSighted; + + private void Update() { + if (PlayerSighted.Player == null) { + Follow.Target = null; + } else { + Follow.Target = PlayerSighted.Player.transform; + } + } + } +} diff --git a/Assets/Scripts/AI/PlayerFollower.cs.meta b/Assets/Scripts/AI/PlayerFollower.cs.meta new file mode 100644 index 0000000..c8dba32 --- /dev/null +++ b/Assets/Scripts/AI/PlayerFollower.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6e805202a073c5541acd3aa2bde26513 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/AI/Triggers/PlayerSighted.cs b/Assets/Scripts/AI/Triggers/PlayerSighted.cs new file mode 100644 index 0000000..8ed198d --- /dev/null +++ b/Assets/Scripts/AI/Triggers/PlayerSighted.cs @@ -0,0 +1,13 @@ +using UnityEngine; + +namespace Saltosion.OneWeapon.AI.Triggers { + public class PlayerSighted : Trigger { + public float Radius; + public Player Player { get; private set; } + + public override bool IsTriggered(Enemy subject) { + Player = Util.GetClosestTo(transform, Radius, true); + return Player != null; + } + } +} diff --git a/Assets/Scripts/AI/Triggers/PlayerSighted.cs.meta b/Assets/Scripts/AI/Triggers/PlayerSighted.cs.meta new file mode 100644 index 0000000..b26cd95 --- /dev/null +++ b/Assets/Scripts/AI/Triggers/PlayerSighted.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 173be6658a5fcba49b9b1f1c91fa5f33 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Bullets/RevolverBullet.cs b/Assets/Scripts/Bullets/RevolverBullet.cs index 30c130e..5c6c031 100644 --- a/Assets/Scripts/Bullets/RevolverBullet.cs +++ b/Assets/Scripts/Bullets/RevolverBullet.cs @@ -47,7 +47,7 @@ namespace Saltosion.OneWeapon.Bullets { Explodable Explodable = collider.GetComponent(); if (Explodable != null) { Explodable.Explode(true); - } else { + } else if (collider.tag == "Environment") { BloodLauncher.DebrisExplode(transform.position, Body.velocity.normalized * 0.7f, 5, 30f, 360); } } diff --git a/Assets/Scripts/Util.cs b/Assets/Scripts/Util.cs index f03cded..5d857ed 100644 --- a/Assets/Scripts/Util.cs +++ b/Assets/Scripts/Util.cs @@ -2,14 +2,35 @@ using UnityEngine; namespace Saltosion.OneWeapon { public class Util { - public static T GetClosestTo(Transform target, float radius) where T : MonoBehaviour { - Collider2D[] NearbyColliders = Physics2D.OverlapCircleAll(target.position, radius); + public static T GetClosestTo(Transform Searcher, float radius, bool needsLineOfSight = false) where T : MonoBehaviour { + Collider2D[] NearbyColliders = Physics2D.OverlapCircleAll(Searcher.position, radius); float LowestDistance = float.PositiveInfinity; T FoundTarget = null; foreach (Collider2D Collider in NearbyColliders) { - float Distance = (Collider.transform.position - target.position).magnitude; + if (Collider.gameObject == Searcher.gameObject) { + continue; + } + + Vector2 Delta = (Collider.transform.position - Searcher.position); + float Distance = Delta.magnitude; T TargetComponent = Collider.GetComponent(); - if (TargetComponent != null && Distance < LowestDistance && Collider.gameObject != target.gameObject) { + RaycastHit2D[] Hits = Physics2D.RaycastAll(Searcher.position, Delta.normalized, Distance); + + bool LineOfSightObstructed; + if (needsLineOfSight) { + LineOfSightObstructed = false; + foreach (RaycastHit2D Hit in Hits) { + if (Hit.collider != Collider && Hit.transform != Searcher) { + // Hit something between the target and the searcher + LineOfSightObstructed = true; + break; + } + } + } else { + LineOfSightObstructed = false; + } + + if (TargetComponent != null && !LineOfSightObstructed && Distance < LowestDistance) { LowestDistance = Distance; FoundTarget = TargetComponent; } diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset index 37345c6..179d872 100644 --- a/ProjectSettings/TagManager.asset +++ b/ProjectSettings/TagManager.asset @@ -3,7 +3,8 @@ --- !u!78 &1 TagManager: serializedVersion: 2 - tags: [] + tags: + - Environment layers: - Default - TransparentFX