This commit is contained in:
Nikita Kruglickiy 2024-03-19 21:38:59 +03:00
parent 05f51f9d83
commit 88a032c39b
8 changed files with 208 additions and 246 deletions

View File

@ -1,5 +1,27 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1101 &-8008422709658283192
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions: []
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 0}
m_Solo: 0
m_Mute: 0
m_IsExit: 1
serializedVersion: 3
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 0.94
m_HasExitTime: 1
m_HasFixedDuration: 0
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1101 &-7177139180987167045
AnimatorStateTransition:
m_ObjectHideFlags: 1
@ -13,7 +35,7 @@ AnimatorStateTransition:
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: -3543533935865275089}
m_Solo: 0
m_Solo: 1
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
@ -24,31 +46,6 @@ AnimatorStateTransition:
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 0
--- !u!1101 &-6818529094234887481
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 1
m_ConditionEvent: attack
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 6469307968501949992}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0.105819285
m_TransitionOffset: 0
m_ExitTime: 0.000000016145702
m_HasExitTime: 1
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1101 &-6298246179504697329
AnimatorStateTransition:
@ -57,44 +54,16 @@ AnimatorStateTransition:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 2
m_ConditionEvent: dance
m_EventTreshold: 0
m_Conditions: []
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 0}
m_Solo: 0
m_Mute: 0
m_IsExit: 1
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 0.9632353
m_HasExitTime: 0
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1101 &-5992129908580872030
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 1
m_ConditionEvent: attack
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 6469307968501949992}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionOffset: 0
m_ExitTime: 0.94186044
m_HasExitTime: 1
m_HasFixedDuration: 1
m_InterruptionSource: 0
@ -107,7 +76,7 @@ AnimatorState:
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: z fall to bite and stand 0
m_Name: stunned
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
@ -179,28 +148,6 @@ AnimatorState:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter: speed
--- !u!1101 &-3088080077202337175
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions: []
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 1102751178008254848}
m_Solo: 0
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionOffset: 0
m_ExitTime: 0.94
m_HasExitTime: 1
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1101 &-2680946984351937023
AnimatorStateTransition:
m_ObjectHideFlags: 1
@ -210,15 +157,15 @@ AnimatorStateTransition:
m_Name:
m_Conditions:
- m_ConditionMode: 1
m_ConditionEvent: damage
m_ConditionEvent: stunned
m_EventTreshold: 0
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: -5914887121904355405}
m_Solo: 0
m_Solo: 1
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 1.10299
m_TransitionDuration: 0.25
m_TransitionOffset: 0
m_ExitTime: 0.080844834
m_HasExitTime: 0
@ -284,20 +231,20 @@ AnimatorController:
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 0}
- m_Name: stun
m_Type: 4
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 0}
- m_Name: attack
- m_Name: stunned
m_Type: 9
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 0}
- m_Name: dance
m_Type: 4
m_Type: 9
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 0}
- m_Name: attack
m_Type: 9
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
@ -417,7 +364,6 @@ AnimatorState:
m_Transitions:
- {fileID: 1101976969126293670}
- {fileID: -4063881565528374387}
- {fileID: 8378993677699007574}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
@ -445,7 +391,6 @@ AnimatorState:
m_CycleOffset: 0
m_Transitions:
- {fileID: 1101067943808544730}
- {fileID: -5992129908580872030}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
@ -479,28 +424,26 @@ AnimatorStateMachine:
- serializedVersion: 1
m_State: {fileID: 2316826469527330622}
m_Position: {x: 120, y: -170, z: 0}
- serializedVersion: 1
m_State: {fileID: 3530830070236652748}
m_Position: {x: 560, y: 440, z: 0}
- serializedVersion: 1
m_State: {fileID: -5914887121904355405}
m_Position: {x: 650, y: 10, z: 0}
m_Position: {x: 800, y: 100, z: 0}
- serializedVersion: 1
m_State: {fileID: 6469307968501949992}
m_Position: {x: 540, y: -170, z: 0}
m_Position: {x: 800, y: 150, z: 0}
- serializedVersion: 1
m_State: {fileID: -3543533935865275089}
m_Position: {x: 500, y: 210, z: 0}
m_Position: {x: 800, y: 50, z: 0}
m_ChildStateMachines: []
m_AnyStateTransitions:
- {fileID: -2680946984351937023}
- {fileID: -7177139180987167045}
- {fileID: 5837019369696166552}
m_EntryTransitions: []
m_StateMachineTransitions: {}
m_StateMachineBehaviours: []
m_AnyStatePosition: {x: 520, y: 100, z: 0}
m_AnyStatePosition: {x: 500, y: 100, z: 0}
m_EntryPosition: {x: 140, y: 120, z: 0}
m_ExitPosition: {x: 864, y: 144, z: 0}
m_ExitPosition: {x: 1100, y: 100, z: 0}
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
m_DefaultState: {fileID: 1102751178008254848}
--- !u!1102 &2316826469527330622
@ -515,7 +458,6 @@ AnimatorState:
m_CycleOffset: 0
m_Transitions:
- {fileID: -1746738016173991043}
- {fileID: -6818529094234887481}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
@ -531,32 +473,6 @@ AnimatorState:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1102 &3530830070236652748
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: z fall to bite and stand
m_Speed: 1
m_CycleOffset: 0
m_Transitions: []
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: -203655887218126122, guid: 9175fddd2326b1545ac71cf4346baa83, type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1101 &4133929114904890219
AnimatorStateTransition:
m_ObjectHideFlags: 1
@ -564,52 +480,22 @@ AnimatorStateTransition:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- m_ConditionMode: 2
m_ConditionEvent: stun
m_EventTreshold: 0
m_Conditions: []
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: 0}
m_Solo: 0
m_Mute: 0
m_IsExit: 1
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 0.9639423
m_HasExitTime: 1
m_HasFixedDuration: 1
m_HasFixedDuration: 0
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
--- !u!1102 &6469307968501949992
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: zNeckBite
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
- {fileID: -3088080077202337175}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: -203655887218126122, guid: 44e7c5a9d9018944591bb3f85d64726b, type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
--- !u!1101 &8378993677699007574
--- !u!1101 &5837019369696166552
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
@ -628,9 +514,36 @@ AnimatorStateTransition:
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionOffset: 0
m_ExitTime: 0.9375
m_HasExitTime: 1
m_ExitTime: 0.75
m_HasExitTime: 0
m_HasFixedDuration: 1
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
m_CanTransitionToSelf: 0
--- !u!1102 &6469307968501949992
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: attack
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
- {fileID: -8008422709658283192}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
m_WriteDefaultValues: 1
m_Mirror: 0
m_SpeedParameterActive: 0
m_MirrorParameterActive: 0
m_CycleOffsetParameterActive: 0
m_TimeParameterActive: 0
m_Motion: {fileID: -203655887218126122, guid: 44e7c5a9d9018944591bb3f85d64726b, type: 3}
m_Tag:
m_SpeedParameter:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:

View File

@ -4,6 +4,7 @@ using Mirror;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Animations.Rigging;
using UnityEngine.Serialization;
namespace Characters.Enemy
{
@ -19,13 +20,14 @@ namespace Characters.Enemy
[HideInInspector] public bool canAttack;
[SyncVar(hook = nameof(OnStateChanged))] public EnemyState state = EnemyState.Idle;
[SyncVar] public EnemyState state = EnemyState.Idle;
[SyncVar, HideInInspector] public float aimRigWeight;
public readonly StateMachine<EnemyState> stateMachine = new StateMachine<EnemyState>();
public Transform target;
[FormerlySerializedAs("target")] public Transform targetTransform;
public NetworkAnimator networkAnimator;
public float DistanceToTarget => Vector3.Distance(targetTransform.transform.position, transform.position);
private CustomNetworkManager _networkManager;
private NetworkGameManager _networkGameManager;
@ -50,6 +52,7 @@ namespace Characters.Enemy
stateMachine.Add(new PatrolState(this));
stateMachine.Add(new ChaseState(this));
stateMachine.Add(new StunnedState(this));
stateMachine.Add(new AttackState(this));
stateMachine.SetCurrentState(state);
}
@ -58,13 +61,16 @@ namespace Characters.Enemy
{
Footsteps();
stateMachine.Update();
if (isServer)
{
agent.speed = _speedMul * RunSpeed;
animator.SetFloat(SpeedAnimHash, agent.velocity.magnitude);
}
aimRigWeight = isServer ? Mathf.Lerp(aimRigWeight, _targetAimRigWeight, Time.deltaTime) : aimRigWeight;
aimRig.weight = aimRigWeight;
animator.SetFloat(SpeedAnimHash, agent.velocity.magnitude);
stateMachine.Update();
}
void FixedUpdate()
@ -92,24 +98,54 @@ namespace Characters.Enemy
}
}
[ClientRpc]
public void RpcKillTarget(Transform target)
{
Interactions interactions = target.GetComponent<Interactions>();
if (interactions != null) interactions.DropProp();
target.GetComponent<Pawn>().Die();
}
[ServerCallback]
public override void TakeDamage()
{
base.TakeDamage();
if (state == EnemyState.Stunned)
{
stateMachine.GetCurrentState().ReEnter();
ChangeState(EnemyState.Stunned);
}
else
public void ChangeState(EnemyState newState)
{
state = EnemyState.Stunned;
state = newState;
stateMachine.SetCurrentState(newState);
}
public Transform GetClosestTarget()
{
var alivePlayers = _networkManager.alive;
if (targetTransform != null && alivePlayers.Count == 1 && alivePlayers[0].transform == targetTransform)
{
return targetTransform;
}
Transform closestTarget = null;
float sortDistance = float.MaxValue;
foreach (var player in _networkManager.alive)
{
float distance = Vector3.Distance(player.transform.position, transform.position);
if (distance <= aggressionDistance && distance < sortDistance && agent.SetDestination(player.transform.position))
{
sortDistance = distance;
closestTarget = player.transform;
}
}
void OnStateChanged(EnemyState _, EnemyState newState)
{
Debug.Log($"{_} -> {newState}");
stateMachine.SetCurrentState(newState);
return closestTarget;
}
}
}

View File

@ -0,0 +1,37 @@
using Koptilnya.StateMachine;
using Mirror;
using UnityEngine;
namespace Characters.Enemy.States
{
public class AttackState : State<EnemyState>
{
private readonly Enemy _enemy;
private static readonly int AttackAnimHash = Animator.StringToHash("attack");
public AttackState(Enemy enemy) : base(EnemyState.Attack)
{
_enemy = enemy;
}
[ServerCallback]
public override void Enter()
{
_enemy.SetSpeedMul(1f);
}
[ServerCallback]
public override void Update()
{
_enemy.networkAnimator.SetTrigger(AttackAnimHash);
_enemy.RpcKillTarget(_enemy.targetTransform);
_enemy.ChangeState(EnemyState.Patrol);
}
[ServerCallback]
public override void Exit()
{
_enemy.targetTransform = null;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3e9f5beb8e3e4632a4fb963810a1386f
timeCreated: 1710870974

View File

@ -1,4 +1,5 @@
using Koptilnya.StateMachine;
using Mirror;
using UnityEngine;
namespace Characters.Enemy.States
@ -12,48 +13,41 @@ namespace Characters.Enemy.States
_enemy = enemy;
}
[ServerCallback]
public override void Enter()
{
if (!_enemy.isServer) return;
_enemy.SetSpeedMul(1f);
_enemy.SetAimRigWeight(1f);
}
[ServerCallback]
public override void Update()
{
if (!_enemy.isServer) return;
_enemy.agent.destination = _enemy.targetTransform.position;
_enemy.agent.destination = _enemy.target.position;
var distanceToTarget = _enemy.DistanceToTarget;
float distance = Vector3.Distance(_enemy.target.transform.position, _enemy.transform.position);
if (distance < _enemy.aggressionDistance)
if (distanceToTarget < _enemy.aggressionDistance)
{
_enemy.aimTransform.position = _enemy.target.position + _enemy.target.up * 1.2f;
_enemy.aimTransform.position = _enemy.targetTransform.position + _enemy.targetTransform.up * 1.2f;
// if (distance < 1f)
// {
// if (canAttack && !isKilling)
// {
// RpcKillPlayer(_target);
// animator.SetTrigger("attack");
//
// StartCoroutine(AfterKillTimer());
// }
// }
if (distanceToTarget < 1f)
{
_enemy.ChangeState(EnemyState.Attack);
}
}
else
{
_enemy.state = EnemyState.Idle;
}
_enemy.ChangeState(EnemyState.Idle);
}
_enemy.targetTransform = _enemy.GetClosestTarget();
}
[ServerCallback]
public override void Exit()
{
if (!_enemy.isServer) return;
_enemy.target = null;
_enemy.targetTransform = null;
_enemy.SetAimRigWeight(0f);
}

View File

@ -16,33 +16,31 @@ namespace Characters.Enemy.States
_enemy = enemy;
}
[ServerCallback]
public override void Enter()
{
if (!_enemy.isServer) return;
_enemy.SetSpeedMul(0f);
_enemy.networkAnimator.SetTrigger("dance");
_enemy.networkAnimator.SetTrigger(DanceAnimHash);
}
[ServerCallback]
public override void Update()
{
if (!_enemy.isServer) return;
var stateInfo = _enemy.animator.GetCurrentAnimatorStateInfo(0);
bool inAnim = stateInfo.shortNameHash == DanceAnimHash;
if (!_entered && inAnim) _entered = true;
if (_entered && !inAnim) _enemy.state = EnemyState.Patrol;
if (_entered && !inAnim) _enemy.ChangeState(EnemyState.Patrol);
}
[ServerCallback]
public override void Exit()
{
if (!_enemy.isServer) return;
_entered = false;
_enemy.networkAnimator.ResetTrigger("dance");
_enemy.networkAnimator.ResetTrigger(DanceAnimHash);
_enemy.SetSpeedMul(1f);
}
}

View File

@ -19,33 +19,20 @@ namespace Characters.Enemy.States
_networkManager = NetworkManager.singleton.GetComponent<CustomNetworkManager>();
}
[ServerCallback]
public override void Enter()
{
if (!_enemy.isServer) return;
_enemy.SetSpeedMul(1f);
_enemy.SetAimRigWeight(0f);
}
[ServerCallback]
public override void Update()
{
if (!_enemy.isServer) return;
_enemy.targetTransform = _enemy.GetClosestTarget();
float sortDistance = float.MaxValue;
foreach (var player in _networkManager.alive)
if (_enemy.targetTransform != null)
{
float distance = Vector3.Distance(player.transform.position, _enemy.transform.position);
if (distance <= _enemy.aggressionDistance && distance < sortDistance && _enemy.agent.SetDestination(player.transform.position))
{
sortDistance = distance;
_enemy.target = player.transform;
}
}
if (_enemy.target != null)
{
_enemy.state = EnemyState.Chase;
_enemy.ChangeState(EnemyState.Chase);
return;
}

View File

@ -25,10 +25,10 @@ namespace Characters.Enemy.States
if (_enemy.isServer)
{
_enemy.canAttack = false;
_enemy.target = null;
_enemy.targetTransform = null;
_enemy.SetSpeedMul(0f);
_enemy.networkAnimator.SetTrigger("stunned");
_enemy.networkAnimator.SetTrigger(StunnedAnimHash);
}
if(_enemy.isClient)
@ -38,36 +38,30 @@ namespace Characters.Enemy.States
}
}
[Server]
[ServerCallback]
public override void ReEnter()
{
Debug.Log("Reenter stunned state");
_enemy.networkAnimator.SetTrigger("stunned");
_enemy.networkAnimator.SetTrigger(StunnedAnimHash);
}
[ServerCallback]
public override void Update()
{
if (!_enemy.isServer) return;
var stateInfo = _enemy.animator.GetCurrentAnimatorStateInfo(0);
bool inAnim = stateInfo.shortNameHash == StunnedAnimHash;
if (!_entered && inAnim) _entered = true;
if (_entered && !inAnim)
{
_enemy.state = EnemyState.Patrol;
}
if (_entered && !inAnim) _enemy.ChangeState(EnemyState.Patrol);
}
[ServerCallback]
public override void Exit()
{
if (!_enemy.isServer) return;
_entered = false;
_enemy.networkAnimator.ResetTrigger("stunned");
_enemy.networkAnimator.ResetTrigger(StunnedAnimHash);
_enemy.SetSpeedMul(1f);
_enemy.canAttack = true;