private void Reset(bool changePosition = false)
        {
            step = 0;
            var targetPosition  = target.localPosition;
            var initialRotation = Quaternion.identity;
            var initialVelocity = Vector3.zero;

            if (changePosition)
            {
                var randomZ = Random.Range(0, 2);
                if (randomZ == 0)
                {
                    targetPosition.z = 0;
                    var randomX = Random.Range(0, 2);
                    if (randomX == 0)
                    {
                        targetPosition.x = -5f;
                    }
                    else
                    {
                        targetPosition.x = 5f;
                    }
                }
                else
                {
                    targetPosition.z = -5f;
                    var randomX = Random.Range(-5f, 5f);
                    targetPosition.x = randomX;
                }
            }

            ResetUnityEntities(initialRotation, targetPosition);

            unityAgent.model = RotateAgent.Update(unityAgent.model, initialRotation, targetPosition, initialVelocity, initialTurnDirection);
        }
        private void Initialize()
        {
            step = 0;
            var targetPosition = target.localPosition;

            unityAgent.model = RotateAgent.Create(Quaternion.identity, targetPosition, rotationAngle);
            ResetUnityEntities(Quaternion.identity, targetPosition);
        }
        public void Step(int maxSteps)
        {
            step += 1;

            var agentBody      = unityAgent.body;
            var agentPosition  = agentBody.transform.localPosition;
            var agentRotation  = agentBody.rotation;
            var agentVelocity  = agentBody.angularVelocity;
            var targetPosition = target.localPosition;
            var turnDirection  = CalculateTurnDirection(agentBody, targetPosition, agentPosition);

            unityAgent.model = RotateAgent.Update(unityAgent.model, agentRotation, targetPosition, agentVelocity, turnDirection);

            if (IsFacingTarget(agentBody, targetPosition, agentPosition))
            {
                if (stepsFacing >= mustFaceTargetSteps)
                {
                    AgentDone();
                }
                else
                {
                    FacingReward(agentBody, targetPosition, agentPosition, maxSteps);
                }
            }
            else if (GoingWrongDirection(turnDirection))
            {
                AgentFail();
            }
            else if (step > maxSteps)
            {
                TimeUp();
            }
            else
            {
                AgentStep(maxSteps, turnDirection);
            }
        }