Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Assets/Scripts/Enemy/EnemyController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ public class EnemyController
protected int currentHealth;
protected EnemyState currentState;
protected NavMeshAgent Agent => enemyView.Agent;
protected EnemyScriptableObject Data => enemyScriptableObject;
protected Quaternion Rotation => enemyView.transform.rotation;
protected Vector3 Position => enemyView.transform.position;
public EnemyScriptableObject Data => enemyScriptableObject;
public Quaternion Rotation => enemyView.transform.rotation;
public Vector3 Position => enemyView.transform.position;


public EnemyController(EnemyScriptableObject enemyScriptableObject)
Expand Down
89 changes: 9 additions & 80 deletions Assets/Scripts/Enemy/OnePunchMan/OnePunchManController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,108 +7,37 @@ namespace StatePattern.Enemy
{
public class OnePunchManController : EnemyController
{
private bool isIdle;
private bool isRotating;
private bool isShooting;
private float idleTimer;
private float shootTimer;
private float targetRotation;
private PlayerController target;


private OnePunchManStateMachine stateMachine;
public OnePunchManController(EnemyScriptableObject enemyScriptableObject) : base(enemyScriptableObject)
{
enemyView.SetController(this);
InitializeVariables();
createSateMachine();
stateMachine.ChangeState(OnePunchManState.IDLE);
}

private void InitializeVariables()
{
isIdle = true;
isRotating = false;
isShooting = false;
idleTimer = enemyScriptableObject.IdleTime;
shootTimer = enemyScriptableObject.RateOfFire;
}

private void createSateMachine() => stateMachine = new OnePunchManStateMachine(this);

public override void UpdateEnemy()
{
if (currentState == EnemyState.DEACTIVE)
return;

if(isIdle && !isRotating && !isShooting)
{
idleTimer -= Time.deltaTime;
if(idleTimer <= 0)
{
isIdle = false;
isRotating = true;
targetRotation = (Rotation.eulerAngles.y + 180) % 360;
}
}

if(!isIdle && isRotating && !isShooting)
{
SetRotation(CalculateRotation());
if(IsRotationComplete())
{
isIdle = true;
isRotating = false;
ResetTimer();
}
}

if(!isIdle && !isRotating && isShooting)
{
Quaternion desiredRotation = CalculateRotationTowardsPlayer();
SetRotation(RotateTowards(desiredRotation));

if(IsFacingPlayer(desiredRotation))
{
shootTimer -= Time.deltaTime;
if (shootTimer <= 0)
{
shootTimer = enemyScriptableObject.RateOfFire;
Shoot();
}
}

}
stateMachine.Update();

}

private void ResetTimer() => idleTimer = enemyScriptableObject.IdleTime;

private Vector3 CalculateRotation() => Vector3.up * Mathf.MoveTowardsAngle(Rotation.eulerAngles.y, targetRotation, enemyScriptableObject.RotationSpeed * Time.deltaTime);

private bool IsRotationComplete() => Mathf.Abs(Mathf.Abs(Rotation.eulerAngles.y) - Mathf.Abs(targetRotation)) < Data.RotationThreshold;

private bool IsFacingPlayer(Quaternion desiredRotation) => Quaternion.Angle(Rotation, desiredRotation) < Data.RotationThreshold;

private Quaternion CalculateRotationTowardsPlayer()
{
Vector3 directionToPlayer = target.Position - Position;
directionToPlayer.y = 0f;
return Quaternion.LookRotation(directionToPlayer, Vector3.up);
}

private Quaternion RotateTowards(Quaternion desiredRotation) => Quaternion.LerpUnclamped(Rotation, desiredRotation, enemyScriptableObject.RotationSpeed / 30 * Time.deltaTime);


public override void PlayerEnteredRange(PlayerController targetToSet)
{
base.PlayerEnteredRange(targetToSet);
isIdle = false;
isRotating = false;
isShooting = true;
target = targetToSet;
shootTimer = 0;
stateMachine.ChangeState(OnePunchManState.SHOOTING);
}

public override void PlayerExitedRange()
{
isIdle = true;
isRotating = false;
isShooting = false;
stateMachine.ChangeState(OnePunchManState.IDLE);
}
}
}
8 changes: 8 additions & 0 deletions Assets/Scripts/State.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions Assets/Scripts/State/IdleState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Collections;
using System.Collections.Generic;
using StatePattern.Enemy;
using UnityEngine;
using StatePattern.State;

public class IdleState : IState
{
public OnePunchManController Owner { get; set; }
private OnePunchManStateMachine stateMachine;
private float timer;

public IdleState(OnePunchManStateMachine stateMachine)
{
this.stateMachine = stateMachine;
}

public void OnStateEnter() => ResetTimer();

public void OnStateExit() => timer = 0;

public void Update()
{
timer -= Time.deltaTime;
if(timer <= 0)
{
stateMachine.ChangeState(OnePunchManState.ROTATING);
}
}


public void ResetTimer() => timer = Owner.Data.IdleTime;
}
11 changes: 11 additions & 0 deletions Assets/Scripts/State/IdleState.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Assets/Scripts/State/Interface.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions Assets/Scripts/State/Interface/IState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Collections;
using System.Collections.Generic;
using StatePattern.Enemy;
using UnityEngine;

namespace StatePattern.State
{
public interface IState
{
public OnePunchManController Owner { get; set; }

public void OnStateEnter();

public void Update();
public void OnStateExit();
}
}

11 changes: 11 additions & 0 deletions Assets/Scripts/State/Interface/IState.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Assets/Scripts/State/OnePunchManState.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Assets/Scripts/State/OnePunchManState/OnePuchManState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
public enum OnePunchManState
{
IDLE,
ROTATING,
SHOOTING
}
11 changes: 11 additions & 0 deletions Assets/Scripts/State/OnePunchManState/OnePuchManState.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions Assets/Scripts/State/OnePunchManState/OnePunchManStateMachine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.Collections;
using System.Collections.Generic;
using StatePattern.Enemy;
using StatePattern.State;
using UnityEngine;

public class OnePunchManStateMachine
{
private OnePunchManController Owner;
private IState currentState;

protected Dictionary<OnePunchManState, IState> states = new Dictionary<OnePunchManState, IState>();

public OnePunchManStateMachine(OnePunchManController owner)
{
this.Owner = owner;
CreateStates();
SetOwner();
}

private void CreateStates()
{
states.Add(OnePunchManState.IDLE,new IdleState(this));
states.Add(OnePunchManState.ROTATING, new RotatingState(this));
states.Add(OnePunchManState.SHOOTING, new ShootingState(this));
}

private void SetOwner()
{
foreach(IState state in states.Values)
{
state.Owner = Owner;
}
}

public void Update() => currentState.Update();

protected void ChangeState(IState newState)
{
currentState?.OnStateExit();
currentState = newState;
currentState?.OnStateEnter();
}

public void ChangeState(OnePunchManState newState) => ChangeState(states[newState]);
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions Assets/Scripts/State/RotatingState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.Collections;
using System.Collections.Generic;
using StatePattern.Enemy;
using UnityEngine;
using StatePattern.State;

public class RotatingState : IState
{
public OnePunchManController Owner { get; set; }
private OnePunchManStateMachine stateMachine;
private float targetRotation;

public RotatingState(OnePunchManStateMachine stateMachine)
{
this.stateMachine = stateMachine;
}

public void OnStateEnter()
{
targetRotation = (Owner.Rotation.eulerAngles.y + 180) % 360;
}

public void OnStateExit()
{
targetRotation = 0;
}

public void Update()
{
Owner.SetRotation(CalculateRotation());
if(IsRotationComplete())
{
stateMachine.ChangeState(OnePunchManState.IDLE);
}
}

private Vector3 CalculateRotation() => Vector3.up * Mathf.MoveTowardsAngle(Owner.Rotation.eulerAngles.y, targetRotation, Owner.Data.RotationSpeed * Time.deltaTime);

private bool IsRotationComplete() => Mathf.Abs(Mathf.Abs(Owner.Rotation.eulerAngles.y) - Mathf.Abs(targetRotation)) < Owner.Data.RotationThreshold;
}
11 changes: 11 additions & 0 deletions Assets/Scripts/State/RotatingState.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading