@ -1,6 +1,6 @@
using System ;
using System.Collections.Generic ;
using System.Threading.Tasks ;
using Animators.Leonid_Animator ;
using Unity.MLAgents ;
using Unity.MLAgents.Actuators ;
using Unity.MLAgents.Sensors ;
@ -10,51 +10,57 @@ using UnityEngine;
public class NPC : Agent , ICharacter
{
[HideInInspector]
private Character A gentCharacter;
public CharacterCondition Condition ;
private FlagZone flagZone = null ;
private Character _a gentCharacter;
public INpcBaseState NpcState { get ; private set ; }
private CharacterCondition _condition ;
private FlagZone _flagZone = null ;
private INpcBaseState NpcState { get ; set ; }
public INpcBaseBodyState NpcBodyState { get ; private set ; }
public Character GetCharacter = > A gentCharacter;
public Character GetCharacter = > _a gentCharacter;
private NpcDirectPointState D irectState;
private NpcInCoverState C overState;
private NpcRunningState R unningState;
private NpcDirectPointState _d irectState;
private NpcInCoverState _c overState;
private NpcRunningState _r unningState;
private NpcStandingState S tandingState;
private NpcCrouchingState C rouchingState;
private NpcStandingState _s tandingState;
private NpcCrouchingState _c rouchingState;
private MovementController moveController ;
private BufferSensorComponent bufferSensor ;
private MovementController _ moveController;
private BufferSensorComponent _ bufferSensor;
private AnimatorHandler _animatorHandler ;
private AimAssistant _assistant ;
private Dictionary < int , NavPoint > _navPointIdDict ;
private Dictionary < int , NavPoint > navPointIdDict ;
#region UnityEvents and ML
private void Awake ( )
{
D irectState = new NpcDirectPointState ( ) ;
C overState = new NpcInCoverState ( ) ;
R unningState = new NpcRunningState ( ) ;
NpcState = D irectState;
_d irectState = new NpcDirectPointState ( ) ;
_c overState = new NpcInCoverState ( ) ;
_r unningState = new NpcRunningState ( ) ;
NpcState = _d irectState;
C rouchingState = new NpcCrouchingState ( ) ;
S tandingState = new NpcStandingState ( ) ;
NpcBodyState = S tandingState;
_c rouchingState = new NpcCrouchingState ( ) ;
_s tandingState = new NpcStandingState ( ) ;
NpcBodyState = _s tandingState;
A gentCharacter = new Character ( ) ;
C ondition = A gentCharacter. Condition ;
_a gentCharacter = new Character ( ) ;
_c ondition = _a gentCharacter. Condition ;
moveController = gameObject . GetComponent < MovementController > ( ) ;
bufferSensor = gameObject . GetComponent < BufferSensorComponent > ( ) ;
_ moveController = gameObject . GetComponent < MovementController > ( ) ;
_ bufferSensor = gameObject . GetComponent < BufferSensorComponent > ( ) ;
_animatorHandler = gameObject . GetComponent < AnimatorHandler > ( ) ;
_assistant = gameObject . GetComponent < AimAssistant > ( ) ;
flagZone = GameObject . FindObjectOfType < FlagZone > ( ) ;
if ( flagZone is null )
_ flagZone = GameObject . FindObjectOfType < FlagZone > ( ) ;
if ( _ flagZone is null )
Debug . LogError ( "Flag Is Not Set" ) ;
navPointIdDict = MapManager . Instance . IDToNavPoint ;
if ( navPointIdDict is null )
_ navPointIdDict = MapManager . Instance . IDToNavPoint ;
if ( _ navPointIdDict is null )
Debug . LogError ( "Cant Find Nav Point Dictionary" ) ;
}
@ -65,54 +71,54 @@ public class NPC : Agent, ICharacter
public override void OnEpisodeBegin ( )
{
if ( navPointIdDict is null )
if ( _ navPointIdDict is null )
Debug . LogError ( "Cant Find Nav Point Dictionary" ) ;
NpcState = D irectState;
flagZone = GameObject . FindObjectOfType < FlagZone > ( ) ;
NpcState = _d irectState;
_ flagZone = GameObject . FindObjectOfType < FlagZone > ( ) ;
}
public override void CollectObservations ( VectorSensor sensor )
{
// Debug.Log("Collect observations called!");
navPointIdDict = MapManager . Instance . IDToNavPoint ;
if ( navPointIdDict is null )
_ navPointIdDict = MapManager . Instance . IDToNavPoint ;
if ( _ navPointIdDict is null )
Debug . LogError ( "Cant Find Nav Point Dictionary" ) ;
var candidates = moveController . GetPointsCandidate ( ) ;
var candidates = _ moveController. GetPointsCandidate ( ) ;
//common sensors
sensor . AddObservation ( GameManager . IsHaveSeenByEnemy ( A gentCharacter. Team . GetOppositeTeam ( ) ,
sensor . AddObservation ( GameManager . IsHaveSeenByEnemy ( _a gentCharacter. Team . GetOppositeTeam ( ) ,
NpcBodyState . GetPointToHit ( gameObject ) ) . ToInt ( ) ) ;
sensor . AddObservation ( A gentCharacter. LastTimeHit ) ;
sensor . AddObservation ( ( ! flagZone . IsNotOccup ) . ToInt ( ) ) ;
sensor . AddObservation ( C ondition. GetHealthPointsInQuantile ( ) ) ;
sensor . AddObservation ( C ondition. GetArmourPointsInQuantile ( ) ) ;
sensor . AddObservation ( _a gentCharacter. LastTimeHit ) ;
sensor . AddObservation ( ( ! _ flagZone. IsNotOccup ) . ToInt ( ) ) ;
sensor . AddObservation ( _c ondition. GetHealthPointsInQuantile ( ) ) ;
sensor . AddObservation ( _c ondition. GetArmourPointsInQuantile ( ) ) ;
sensor . AddObservation ( candidates . Count ) ;
sensor . AddObservation ( moveController . PointStartID ) ;
sensor . AddObservation ( moveController . PointEndID ) ;
sensor . AddObservation ( _ moveController. PointStartID ) ;
sensor . AddObservation ( _ moveController. PointEndID ) ;
// Debug.Log("Done common!");
//state sensors
sensor . AddObservation ( ( int ) NpcState . State ) ;
sensor . AddObservation ( ( int ) NpcBodyState . State ) ;
sensor . AddObservation ( GameManager . IsEnemyNearby ( gameObject . transform . position , A gentCharacter. Team ) ) ;
sensor . AddObservation ( navPointIdDict [ moveController . PointStartID ] . DeathAttr ) ;
sensor . AddObservation ( navPointIdDict [ moveController . PointEndID ] . DeathAttr ) ;
sensor . AddObservation ( moveController . FlagDistance ) ;
sensor . AddObservation ( GameManager . IsEnemyNearby ( gameObject . transform . position , _a gentCharacter. Team ) ) ;
sensor . AddObservation ( _ navPointIdDict[ _ moveController. PointStartID ] . DeathAttr ) ;
sensor . AddObservation ( _ navPointIdDict[ _ moveController. PointEndID ] . DeathAttr ) ;
sensor . AddObservation ( _ moveController. FlagDistance ) ;
// Debug.Log("Done state sensors!");
//point sensors
foreach ( var point in candidates )
{
var position = transform . position ;
bufferSensor . AppendObservation ( new float [ ] {
_ bufferSensor. AppendObservation ( new float [ ] {
point . DeathAttr ,
( int ) point . navType ,
//4 flagEnemyDistance
GameManager . IsCloserToFlagFromNextNavPoint ( point , position ) . ToInt ( ) ,
//5 EnemyVsNavPointDistance
GameManager . IsCloserToEnemyThanToNextNavPoint ( point , position , A gentCharacter. Team . GetOppositeTeam ( ) ) . ToInt ( ) ,
GameManager . IsCloserToEnemyThanToNextNavPoint ( point , position , _a gentCharacter. Team . GetOppositeTeam ( ) ) . ToInt ( ) ,
//6 Have been seen by enemy in this point
GameManager . IsHaveSeenByEnemy ( A gentCharacter. Team . GetOppositeTeam ( ) ,
GameManager . IsHaveSeenByEnemy ( _a gentCharacter. Team . GetOppositeTeam ( ) ,
point . Position ) . ToInt ( )
} ) ;
}
@ -126,16 +132,16 @@ public class NPC : Agent, ICharacter
// Debug.Log(result[0] + " " + result[1]);
if ( result [ 0 ] = = 0 )
{
if ( navPointIdDict [ moveController . PointStartID ] . navType ! = NavPointType . Cover )
if ( _ navPointIdDict[ _ moveController. PointStartID ] . navType ! = NavPointType . Cover )
return ;
NpcState = C overState;
NpcState = _c overState;
switch ( result [ 1 ] )
{
case 0 : Peek ( ) ; break ;
case 1 : Cover ( ) ; break ;
case 3 : Peek ( ) ; moveController . GoToNextNavPoint ( navPointIdDict [ result [ 2 ] ] ) ; break ;
case 4 : NpcState = D irectState; break ;
case 3 : Peek ( ) ; _ moveController. GoToNextNavPoint ( _ navPointIdDict[ result [ 2 ] ] ) ; break ;
case 4 : NpcState = _d irectState; break ;
default : throw new ArgumentException ( "Undefined Action recieved" ) ;
}
}
@ -143,7 +149,7 @@ public class NPC : Agent, ICharacter
if ( result [ 0 ] = = 1 )
{
// Debug.Log("BEFORE SOme shitty if >:(");
if ( navPointIdDict [ moveController . PointStartID ] . navType ! = NavPointType . Direction )
if ( _ navPointIdDict[ _ moveController. PointStartID ] . navType ! = NavPointType . Direction )
{
// Debug.Log("SOme shitty if >:(");
return ;
@ -152,64 +158,72 @@ public class NPC : Agent, ICharacter
switch ( result [ 1 ] )
{
case 0 : moveController . GoToNextNavPoint ( navPointIdDict [ result [ 2 ] ] ) ;
NpcState = R unningState; Debug . Log ( "Go to point " + result [ 2 ] ) ; break ;
case 1 : NpcState = D irectState; break ;
case 0 : _ moveController. GoToNextNavPoint ( _ navPointIdDict[ result [ 2 ] ] ) ;
NpcState = _r unningState; Debug . Log ( "Go to point " + result [ 2 ] ) ; break ;
case 1 : NpcState = _d irectState; break ;
default : throw new ArgumentException ( "Undefined Action recieved" ) ;
}
}
if ( result [ 0 ] = = 2 )
{
if ( moveController . PointStartID = = moveController . PointEndID & & moveController . PointEndID ! = - 1 )
if ( _ moveController. PointStartID = = _ moveController. PointEndID & & _ moveController. PointEndID ! = - 1 )
return ;
switch ( result [ 1 ] )
{
case 0 : moveController . StopOnPath ( ) ; NpcState = D irectState; break ;
case 1 : moveController . ReturnToStartPoint ( ) ; NpcState = R unningState; break ;
case 0 : _ moveController. StopOnPath ( ) ; NpcState = _d irectState; break ;
case 1 : _ moveController. ReturnToStartPoint ( ) ; NpcState = _r unningState; break ;
default : throw new ArgumentException ( "Undefined Action recieved" ) ;
}
}
// Debug.Log("Actions processed!");
}
private void UpdateAnimatorValues ( )
{
var movementDir = _moveController . Velocity ;
//Тут может быть косяк, так как я не помню горизонтальное по x или y.
_animatorHandler . UpdateAnimatorValues ( movementDir . x , movementDir . y ,
false , NpcBodyState = = _crouchingState , _assistant . _isFiring ) ;
}
#endregion
public event Action < NpcBodyState > OnChangePosition ;
private void Peek ( )
{
OnChangePosition ? . Invoke ( global :: NpcBodyState . Standing ) ;
NpcBodyState = S tandingState;
NpcBodyState = _s tandingState;
}
private void Cover ( )
{
OnChangePosition ? . Invoke ( global :: NpcBodyState . Crouching ) ;
NpcBodyState = C rouchingState;
NpcBodyState = _c rouchingState;
}
public event Action < bool > OnDeathEvent ;
public event Action < int , Team > OnDamageRecieved ;
public void GetDamage ( int damage )
{
A gentCharacter. LastTimeHit = TimeManager . Instance . CurrentTime ;
C ondition. GiveHealth ( - Mathf . RoundToInt ( damage * ( 1 - C ondition. ArmourPoints * 0.5f ) ) ) ;
C ondition. GiveArmour ( - Mathf . RoundToInt ( Mathf . Sqrt ( damage ) * 5 ) ) ;
OnDamageRecieved ? . Invoke ( damage , A gentCharacter. Team ) ;
_a gentCharacter. LastTimeHit = TimeManager . Instance . CurrentTime ;
_c ondition. GiveHealth ( - Mathf . RoundToInt ( damage * ( 1 - _c ondition. ArmourPoints * 0.5f ) ) ) ;
_c ondition. GiveArmour ( - Mathf . RoundToInt ( Mathf . Sqrt ( damage ) * 5 ) ) ;
OnDamageRecieved ? . Invoke ( damage , _a gentCharacter. Team ) ;
if ( C ondition. HealthPoints < 0 )
if ( _c ondition. HealthPoints < 0 )
{
MapManager . AddDeathAttributeToPoi nts ( moveController . PointStartID , moveController . PointEndID ,
moveController . DistanceToGo , moveController . RemainingDistance ) ;
OnDeathEve nt? . Invoke ( true ) ;
MapManager . AddDeathAttributeToPoints ( _ moveController. PointStartID , _ moveController. PointEndID ,
_moveController . DistanceToGo , _moveController . RemainingDistance ) ;
var pos = gameObject . transform . position ;
var id = moveController . PointStartID ;
var id = _ moveController. PointStartID ;
CharacterFactory . Instance . ReSpawn ( this , ref pos , ref id ) ;
}
}
//public event OnDeathEvent<
public void ResetCharacter ( )
{
C ondition. Reset ( ) ;
_c ondition. Reset ( ) ;
EndEpisode ( ) ;
}
}