public override void AgentStep(float[] action) { myStepCountInLastSession++; reward = -0.005f; rocket.UpdateEngineForceDirections(); if (paramsText1 != null && Time.frameCount % 15 == 0) { paramsText1.text = string.Format("Success:{0},Fail:{1},stp:{2},", solved, failed, myStepCountInLastSession); paramsText3.text = string.Format("Fail: Position:{0}, Accident:{1}, Speed:{2}, Rotation:{3}", failCounterPosition, failCounterAccident, failCounterSpeed, failCounterRotation); } // ---------------------------------------------------------------------------------------- // Movement // ---------------------------------------------------------------------------------------- switch ((int)action[0]) { case 0: // do nothing - engine is off - rocket falls down break; case 1: // power on engine - rocket moves up rocket.EngineMainEmitBurst(); audioControl.PlaySfxMainEngine(); break; case 2: // left engine on rocket.EngineDownLeftEmitBurst(); audioControl.PlaySfxSideEngine(); break; case 3: // right engine on rocket.EngineDownRightEmitBurst(); audioControl.PlaySfxSideEngine(); break; case 4: // right engine on rocket.EngineStopEmitBurst(); audioControl.PlaySfxSideEngine(); break; case 5: rocket.EngineUpLeftEmitBurst(); audioControl.PlaySfxSideEngine(); break; case 6: rocket.EngineUpRightEmitBurst(); audioControl.PlaySfxSideEngine(); break; default: break; } // ---------------------------------------------------------------------------------------- // Reward \ Punish // ---------------------------------------------------------------------------------------- //// Small punishments\rewards, disabled in this version //float targetingAngle = rocket.GetTargetingAngle(planet2.gameObject); ////Debug.Log("Targeting angle: " + targetingAngle); //const float ALLOWED_ANGLE_DEVIATION = 20; // degrees //const float GRAVITY_RANGE_PLANET_1 = 6; //// 1) Add small punishment if rocket is in gravity range of planet 1 //if (Vector3.Distance(rocket.transform.position, planet1.transform.position) < GRAVITY_RANGE_PLANET_1) //{ // reward += -0.005f; //} //// 2) Add small punishment if rocket's landing angle (rocket's orientation) for target //// planet is more then DELTA //// we need angle close to 180 degrees //else if (Math.Abs(targetingAngle - 180) > ALLOWED_ANGLE_DEVIATION) //{ // // punish if angle deviation is to big // reward += -0.005f; //} //// 3) punish if speed is to high ////if (!IsRocketSpeedOk()) ////{ //// reward += -0.05f; //// //failed++; //// //reward = -1f; //// //done = true; //// //ResetObjectsPosInScene(); //// //UpdateSessionReward(); //// //PrintEndSessionReward(false); //// //return; ////} // ---------------------------------- FAILURE --------------------------------------------- if (rocket.GetLocalPosY() < failureBorderBottom || rocket.GetLocalPosY() > failureBorderTop || rocket.GetLocalPosX() > failureBorderRight || rocket.GetLocalPosX() < failureBorderLeft) { failed++; reward = -1f; done = true; failCounterPosition++; Debug.Log("Fail: position: " + failCounterPosition); ShowFailText("Fail: position"); previousDistanceToTarget = GetDistanceToTarget(); /** * This is required to reset rocket rotation when switching to a new session - when * rocket moves into left or right vertical wall (presumably at a high speed) and * forward button (main engine) is pressed - the session is over with a failure (that * is expected), but the new session is started with rocket rotating around z-axis * rapidly - it looks like in this case Agent.Reset() logic is not enough... Why? * * Workaround: Adding rocket.Reset() here fixes this issue. */ ResetObjectsPosInScene(); UpdateSessionReward(); PrintEndSessionReward(false); return; } if (rocket.AccidentOccured()) { failed++; reward = -1f; done = true; failCounterAccident++; audioControl.PlaySfxAccident(); Debug.Log("Fail: accident: " + failCounterAccident); ShowFailText("Fail: accident"); ResetObjectsPosInScene(); UpdateSessionReward(); PrintEndSessionReward(false); return; } if (!IsPlayerBrain() && !IsRocketSpeedOk()) { failed++; reward = -1f; done = true; failCounterSpeed++; Debug.Log("Fail: speed: " + failCounterSpeed); ShowFailText("Fail: speed"); ResetObjectsPosInScene(); UpdateSessionReward(); PrintEndSessionReward(false); return; } if (!IsPlayerBrain() && Math.Abs(rocket.GetAngularVelocityZ()) > 0.8) { failed++; reward = -1f; done = true; failCounterRotation++; Debug.Log("Fail: angular velocity: " + failCounterRotation); ShowFailText("Fail: rotation speed"); ResetObjectsPosInScene(); UpdateSessionReward(); PrintEndSessionReward(false); return; } // ------------------------------------- SUCCESS ------------------------------------------ if (rocket.IsOnPlanet() && IsRocketSpeedOk()) { reward = 1; solved++; done = true; ShowSuccessText(); previousDistanceToTarget = GetDistanceToTarget(); ResetObjectsPosInScene(); UpdateSessionReward(); PrintEndSessionReward(true); return; } previousDistanceToTarget = GetDistanceToTarget(); UpdateSessionReward(); }