public void TriggerTransition(DinoAiFSMState.StateEnum newState, EntityId targetEntityId, Vector3 targetPosition) { if (IsValidTransition(newState)) { var oldState = Data.CurrentAiState; Data.CurrentAiState = newState; Data.TargetEntityId = targetEntityId; Data.TargetPosition = targetPosition.ToVector3f(); var update = new DinoAiData.Update() { CurrentAiState = Data.CurrentAiState, TargetEntityId = Data.TargetEntityId, TargetPosition = Data.TargetPosition }; _behaviour.aiDataWriter.SendUpdate(update); _startTime = Time.time; TransitionTo(newState); if (_behaviour.logChanges) { Debug.Log("DinoStateMachine: State changed from<" + oldState + "> to<" + newState + ">"); } } else { Debug.LogErrorFormat("DinoStateMachine: Invalid transition from {0} to {1} detected.", Data.CurrentAiState, newState); } }
// Start is called before the first frame update void Start() { allAnimals.Add(_entityId.Id, this); _id = _entityId.Id; var update = new DinoAiData.Update { CurrentAiState = aiDataReader.Data.CurrentAiState }; OnAiDataChanged(update); var update2 = new Age.Update { Age = age.Data.Age }; OnAgeChanged(update2); var update3 = new DinoAttrs.Update { }; OnAttrsChanged(update3); }
void OnAiDataChanged(DinoAiData.Update update) { DinoAiFSMState.StateEnum newAiState = _currentAiState; if (update.CurrentAiState.HasValue) { newAiState = update.CurrentAiState.Value; } Vector3 newPosition = _targetPosition; if (update.TargetPosition.HasValue && update.TargetPosition.Value.ToUnityVector() != DinoStateMachine.InvalidPosition) { newPosition = update.TargetPosition.Value.ToUnityVector(); } else { newPosition = transform.position; } // 状态重复,不执行 if (newAiState == _currentAiState && newPosition == _targetPosition) { Debug.LogWarning("DinoVisualizer - duplicate AI state : " + newAiState); return; } navMeshAgent.speed = 0; if (lookAtCoroutine != null && newAiState != _currentAiState) { // 状态不同的时候才需要停止携程,防止同一个状态下,动画发生抖动(不停地进行【转向】/【停止转向】) StopCoroutine(lookAtCoroutine); } _currentAiState = newAiState; _targetPosition = newPosition; int aniState = 0; switch (_currentAiState) { case DinoAiFSMState.StateEnum.IDLE: { Vector3 newpos = transform.position; newpos.y = 0; transform.position = newpos; gameObject.SetActive(true); } aniState = 0; break; case DinoAiFSMState.StateEnum.WANDER: navMeshAgent.speed = ScriptableAnimalStats.moveSpeed; aniState = 1; break; case DinoAiFSMState.StateEnum.EAT: lookAtCoroutine = StartCoroutine(TurnToLookAtTarget(_targetPosition)); aniState = 2; break; case DinoAiFSMState.StateEnum.RUN_AWAY: navMeshAgent.speed = ScriptableAnimalStats.runSpeed; aniState = 3; break; case DinoAiFSMState.StateEnum.CHASE: navMeshAgent.speed = ScriptableAnimalStats.runSpeed; aniState = 3; break; case DinoAiFSMState.StateEnum.ATTACK: aniState = 4; lookAtCoroutine = StartCoroutine(TurnToLookAtTarget(_targetPosition)); break; case DinoAiFSMState.StateEnum.DEAD: aniState = 5; break; case DinoAiFSMState.StateEnum.HATCH: aniState = 4; break; case DinoAiFSMState.StateEnum.LOOK_FOR_FOOD: navMeshAgent.speed = ScriptableAnimalStats.moveSpeed; aniState = 1; break; case DinoAiFSMState.StateEnum.EAT_FOOD: aniState = 2; break; case DinoAiFSMState.StateEnum.VANISH: aniState = 5; break; } navMeshAgent.SetDestination(_targetPosition); PlayAnimation(aniState); if (_currentAiState == DinoAiFSMState.StateEnum.VANISH) { StartCoroutine(Vanishing()); } }