Browse Source

Add: base enemy movement and state management

master
KerelOlivier 3 years ago
parent
commit
78ec57c2a5
  1. 2
      Assets/Prefabs/bullet.prefab
  2. 178
      Assets/Scenes/test.unity
  3. 9
      Assets/Scripts/Bullet.cs
  4. 65
      Assets/Scripts/Enemies/BaseEnemy.cs
  5. 35
      Assets/Scripts/Enemies/Enemy.cs
  6. 10
      Assets/Scripts/Enemies/States/AttackState.cs
  7. 11
      Assets/Scripts/Enemies/States/DieState.cs
  8. 11
      Assets/Scripts/Enemies/States/FollowState.cs
  9. 6
      Assets/Scripts/Enemies/States/IdleState.cs
  10. 19
      Assets/Scripts/Enemies/States/PathState.cs
  11. 39
      Assets/Scripts/Enemies/States/TargetState.cs
  12. 0
      Assets/Scripts/Enemies/States/TargetState.cs.meta
  13. 28
      Assets/Scripts/Enemies/States/TargetingState.cs
  14. BIN
      Assets/Sprites/baseEnemy.png
  15. 120
      Assets/Sprites/baseEnemy.png.meta
  16. 5
      ProjectSettings/TagManager.asset

2
Assets/Prefabs/bullet.prefab

@ -14,7 +14,7 @@ GameObject:
- component: {fileID: 409730934181383828} - component: {fileID: 409730934181383828}
m_Layer: 0 m_Layer: 0
m_Name: bullet m_Name: bullet
m_TagString: Untagged m_TagString: Bullet
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0

178
Assets/Scenes/test.unity

@ -123,6 +123,36 @@ NavMeshSettings:
debug: debug:
m_Flags: 0 m_Flags: 0
m_NavMeshData: {fileID: 0} m_NavMeshData: {fileID: 0}
--- !u!1 &225234892
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 225234893}
m_Layer: 0
m_Name: Base
m_TagString: Base
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &225234893
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 225234892}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -2.7, y: 1.46, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 5
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &394882245 --- !u!1 &394882245
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -139,7 +169,7 @@ GameObject:
- component: {fileID: 394882251} - component: {fileID: 394882251}
m_Layer: 0 m_Layer: 0
m_Name: Player m_Name: Player
m_TagString: Untagged m_TagString: Player
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
@ -157,7 +187,7 @@ Transform:
m_Children: m_Children:
- {fileID: 1731621445} - {fileID: 1731621445}
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 1 m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &394882247 --- !u!212 &394882247
SpriteRenderer: SpriteRenderer:
@ -461,7 +491,7 @@ MonoBehaviour:
m_BlendStyleIndex: 0 m_BlendStyleIndex: 0
m_FalloffIntensity: 0.5 m_FalloffIntensity: 0.5
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Intensity: 0.1 m_Intensity: 0.15
m_LightVolumeOpacity: 0 m_LightVolumeOpacity: 0
m_ApplyToSortingLayers: 00000000 m_ApplyToSortingLayers: 00000000
m_LightCookieSprite: {fileID: 0} m_LightCookieSprite: {fileID: 0}
@ -494,11 +524,11 @@ Transform:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1142655128} m_GameObject: {fileID: 1142655128}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -0.18781501, y: -0.13546358, z: 0} m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: [] m_Children: []
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 2 m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1455080910 --- !u!1 &1455080910
GameObject: GameObject:
@ -616,6 +646,144 @@ MonoBehaviour:
- {x: 0.5, y: -0.5, z: 0} - {x: 0.5, y: -0.5, z: 0}
- {x: 0.5, y: 0.5, z: 0} - {x: 0.5, y: 0.5, z: 0}
- {x: -0.5, y: 0.5, z: 0} - {x: -0.5, y: 0.5, z: 0}
--- !u!1 &1849325996
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1849325998}
- component: {fileID: 1849325997}
- component: {fileID: 1849326001}
- component: {fileID: 1849326000}
- component: {fileID: 1849325999}
m_Layer: 0
m_Name: baseEnemy
m_TagString: Enemy
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!212 &1849325997
SpriteRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1849325996}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 0
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 0
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_Sprite: {fileID: 21300000, guid: 24871896504fb6e6bae3b539a5f6e0f2, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 1, y: 1}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!4 &1849325998
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1849325996}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 1, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 4
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!58 &1849325999
CircleCollider2D:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1849325996}
m_Enabled: 1
m_Density: 1
m_Material: {fileID: 0}
m_IsTrigger: 0
m_UsedByEffector: 0
m_UsedByComposite: 0
m_Offset: {x: 0, y: 0}
serializedVersion: 2
m_Radius: 0.27
--- !u!50 &1849326000
Rigidbody2D:
serializedVersion: 4
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1849325996}
m_BodyType: 0
m_Simulated: 1
m_UseFullKinematicContacts: 0
m_UseAutoMass: 0
m_Mass: 1
m_LinearDrag: 0
m_AngularDrag: 0.05
m_GravityScale: 0
m_Material: {fileID: 0}
m_Interpolate: 0
m_SleepingMode: 1
m_CollisionDetection: 0
m_Constraints: 7
--- !u!114 &1849326001
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1849325996}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 637e76a880a1496a9bd4bb5256bc41a2, type: 3}
m_Name:
m_EditorClassIdentifier:
damage: 1
speed: 2
viewRange: 5
attackRange: 1
--- !u!1 &2065747229 --- !u!1 &2065747229
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0

9
Assets/Scripts/Bullet.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using Enemies;
using UnityEngine; using UnityEngine;
public class Bullet : MonoBehaviour public class Bullet : MonoBehaviour
@ -8,6 +9,7 @@ public class Bullet : MonoBehaviour
float lifeTime = 1f; float lifeTime = 1f;
float speed = 15f; float speed = 15f;
float damage = 10f;
// Start is called before the first frame update // Start is called before the first frame update
void Start() void Start()
{ {
@ -20,8 +22,11 @@ public class Bullet : MonoBehaviour
this.transform.Translate(Vector3.right * speed * Time.deltaTime); this.transform.Translate(Vector3.right * speed * Time.deltaTime);
} }
private void OnTriggerEnter(Collider other) void OnTriggerEnter2D(Collider2D other)
{ {
throw new NotImplementedException(); if (other.gameObject.tag == "Enemy")
{
other.gameObject.GetComponent<Enemy>().health -= damage;
}
} }
} }

65
Assets/Scripts/Enemies/BaseEnemy.cs

@ -1,13 +1,18 @@
using System; using System;
using Enemies.States; using Enemies.States;
using UnityEngine;
namespace Enemies namespace Enemies
{ {
public class BaseEnemy :Enemy public class BaseEnemy : Enemy
{ {
private void Awake() private void Awake()
{ {
state = new IdleState(this); this.health = 100;
this.speed = 4;
this.damage = 10;
this.attackRange = .8f;
SwitchState(States.Idle);
} }
private void Update() private void Update()
@ -20,9 +25,61 @@ namespace Enemies
{ {
if (health <= 0) if (health <= 0)
{ {
state = new DieState(this); SwitchState(States.Die);
return;
} }
if (target == null)
{
SwitchState(States.Target);
}
else
{
float dist = Vector2.Distance(target.transform.position, transform.position);
if (currentState == States.Target)
{
SwitchState(States.Path);
}
if (currentState == States.Path)
{
if (dist <= attackRange)
{
SwitchState(target.CompareTag("Player") ? States.Attack : States.Follow);
}
else if (dist > viewRange)
{
target = null;
SwitchState(States.Target);
}
}
if (currentState == States.Attack)
{
if(dist > attackRange)
{
SwitchState(States.Path);
}
}
}
}
public override void SwitchState(States s)
{
if (currentState == s) return;
if (currentState != null) state.Exit();
state = s switch
{
States.Idle => new IdleState(this),
States.Attack => new AttackState(this),
States.Target => new TargetState(this),
States.Follow => new FollowState(this),
States.Path => new PathState(this),
States.Die => new DieState(this),
_ => new IdleState(this)
};
state.Enter();
} }
} }
} }

35
Assets/Scripts/Enemies/Enemy.cs

@ -1,30 +1,33 @@
using System;
using Enemies.States; using Enemies.States;
using UnityEngine; using UnityEngine;
namespace Enemies namespace Enemies
{ {
public class Enemy : MonoBehaviour public abstract class Enemy : MonoBehaviour
{ {
public float health = 10f; public enum States
public float attackPower = 1; {
Idle,
Target,
Path,
Follow,
Attack,
Die
}
public States? currentState;
public float health { get; set; } = 10f;
public float damage = 1;
public GameObject target { get; set; } public GameObject target { get; set; }
private float speed = 2f; public float speed = 2f;
public float viewRange = 5f;
public float attackRange = 1f;
public IState state { get; set; } public IState state { get; set; }
public abstract void SwitchState(States s);
// Start is called before the first frame update
void Start()
{
Destroy(gameObject, 10f);
}
// Update is called once per frame
void Update()
{
}
} }
} }

10
Assets/Scripts/Enemies/States/AttackState.cs

@ -1,27 +1,29 @@
using Enemies.States; using Enemies.States;
using UnityEngine;
namespace Enemies namespace Enemies
{ {
public class AttackState: IState public class AttackState : IState
{ {
private Enemy context; private Enemy context;
public AttackState(Enemy context) public AttackState(Enemy context)
{ {
this.context = context; this.context = context;
} }
public void Enter() public void Enter()
{ {
throw new System.NotImplementedException(); Debug.Log("Entering Attack State");
context.currentState = Enemy.States.Attack;
} }
public void Execute() public void Execute()
{ {
throw new System.NotImplementedException();
} }
public void Exit() public void Exit()
{ {
throw new System.NotImplementedException();
} }
} }
} }

11
Assets/Scripts/Enemies/States/DieState.cs

@ -1,26 +1,29 @@
using UnityEngine; using UnityEngine;
namespace Enemies.States namespace Enemies.States
{ {
public class DieState:IState public class DieState : IState
{ {
private Enemy context; private Enemy context;
public DieState(Enemy context) public DieState(Enemy context)
{ {
this.context = context; this.context = context;
} }
public void Enter() public void Enter()
{ {
throw new System.NotImplementedException(); Debug.Log("Enemy died");
context.currentState = Enemy.States.Die;
Object.Destroy(context.gameObject);
} }
public void Execute() public void Execute()
{ {
Object.Destroy(context.gameObject);
} }
public void Exit() public void Exit()
{ {
throw new System.NotImplementedException();
} }
} }
} }

11
Assets/Scripts/Enemies/States/FollowState.cs

@ -1,4 +1,5 @@
using Enemies.States; using Enemies.States;
using UnityEngine;
namespace Enemies namespace Enemies
{ {
@ -11,17 +12,21 @@ namespace Enemies
} }
public void Enter() public void Enter()
{ {
throw new System.NotImplementedException(); Debug.Log("Entering Follow State");
context.currentState = Enemy.States.Follow;
} }
public void Execute() public void Execute()
{ {
throw new System.NotImplementedException(); //Determine direction to target
Vector2 direction = context.target.transform.position - context.transform.position;
//Move in desired direction
context.transform.Translate(direction.normalized * context.speed * Time.deltaTime);
} }
public void Exit() public void Exit()
{ {
throw new System.NotImplementedException();
} }
} }
} }

6
Assets/Scripts/Enemies/States/IdleState.cs

@ -1,4 +1,5 @@
using Enemies.States; using Enemies.States;
using UnityEngine;
namespace Enemies namespace Enemies
{ {
@ -12,17 +13,16 @@ namespace Enemies
public void Enter() public void Enter()
{ {
throw new System.NotImplementedException(); Debug.Log("Entering Idle State");
context.currentState = Enemy.States.Idle;
} }
public void Execute() public void Execute()
{ {
throw new System.NotImplementedException();
} }
public void Exit() public void Exit()
{ {
throw new System.NotImplementedException();
} }
} }
} }

19
Assets/Scripts/Enemies/States/PathState.cs

@ -1,27 +1,36 @@
using Enemies.States; using Enemies.States;
using UnityEngine;
namespace Enemies namespace Enemies
{ {
public class PathState: IState public class PathState : IState
{ {
private Enemy context; private readonly Enemy context;
public PathState(Enemy context) public PathState(Enemy context)
{ {
this.context = context; this.context = context;
} }
public void Enter() public void Enter()
{ {
throw new System.NotImplementedException(); Debug.Log("Entering Path State");
context.currentState = Enemy.States.Path;
} }
public void Execute() public void Execute()
{ {
throw new System.NotImplementedException(); //Determine direction to target
Vector2 direction = context.target.transform.position - context.transform.position;
//Move in desired direction
context.GetComponent<Rigidbody2D>().MovePosition((Vector2)context.transform.position + direction.normalized * context.speed * Time.deltaTime);
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
context.transform.rotation = Quaternion.Euler(0, 0, angle);
} }
public void Exit() public void Exit()
{ {
throw new System.NotImplementedException();
} }
} }
} }

39
Assets/Scripts/Enemies/States/TargetState.cs

@ -0,0 +1,39 @@
using Enemies.States;
using UnityEngine;
namespace Enemies
{
public class TargetState: IState
{
private readonly Enemy context;
public TargetState(Enemy context)
{
this.context = context;
}
public void Enter()
{
Debug.Log("Entering Target State");
context.currentState = Enemy.States.Target;
//Find nearest target
GameObject player = GameObject.FindWithTag("Player");
GameObject house = GameObject.FindWithTag("Base");
GameObject nearest = player; ;
if (Vector3.Distance(player.transform.position, context.transform.position) > Vector3.Distance(house.transform.position, context.transform.position))
{
nearest = house;
}
context.target = nearest;
}
public void Execute()
{
}
public void Exit()
{
}
}
}

0
Assets/Scripts/Enemies/States/TargetingState.cs.meta → Assets/Scripts/Enemies/States/TargetState.cs.meta

28
Assets/Scripts/Enemies/States/TargetingState.cs

@ -1,28 +0,0 @@
using Enemies.States;
namespace Enemies
{
public class TargetingState: IState
{
private Enemy context;
public TargetingState(Enemy context)
{
this.context = context;
}
public void Enter()
{
throw new System.NotImplementedException();
}
public void Execute()
{
throw new System.NotImplementedException();
}
public void Exit()
{
throw new System.NotImplementedException();
}
}
}

BIN
Assets/Sprites/baseEnemy.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

120
Assets/Sprites/baseEnemy.png.meta

@ -0,0 +1,120 @@
fileFormatVersion: 2
guid: 24871896504fb6e6bae3b539a5f6e0f2
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 11
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 0
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 64
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:

5
ProjectSettings/TagManager.asset

@ -3,7 +3,10 @@
--- !u!78 &1 --- !u!78 &1
TagManager: TagManager:
serializedVersion: 2 serializedVersion: 2
tags: [] tags:
- Bullet
- Base
- Enemy
layers: layers:
- Default - Default
- TransparentFX - TransparentFX

Loading…
Cancel
Save