分离所有RewardFunction相关到单独的一个Script里。
This commit is contained in:
@@ -5,22 +5,8 @@ using UnityEngine;
|
||||
|
||||
public class AgentController : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private GameObject commonParameterContainerObj;
|
||||
[SerializeField]
|
||||
private GameObject environmentObj;
|
||||
[SerializeField]
|
||||
private GameObject enemyContainerObj;
|
||||
[SerializeField]
|
||||
private GameObject sceneBlockContainerObj;
|
||||
[SerializeField]
|
||||
private GameObject environmentUIControlObj;
|
||||
[SerializeField]
|
||||
private GameObject targetControllerObj;
|
||||
[SerializeField]
|
||||
private GameObject HUDObj;
|
||||
[SerializeField]
|
||||
private Camera fpsCam;
|
||||
[SerializeField] public GameObject commonParameterContainerObj;
|
||||
[SerializeField] public Camera fpsCam;
|
||||
|
||||
[Header("GetAxis() Simulate")]
|
||||
public float moveSpeed = 9.0f;
|
||||
@@ -33,45 +19,33 @@ public class AgentController : MonoBehaviour
|
||||
public float mouseYSensitivity = 200;
|
||||
public float yRotation = 0.1f;//定义一个浮点类型的量,记录‘围绕’X轴旋转的角度
|
||||
|
||||
private List<float> spinRecord = new List<float>();
|
||||
private bool lockMouse;
|
||||
private float damage;
|
||||
private float fireRate;
|
||||
private bool lockCameraX;
|
||||
private bool lockCameraY;
|
||||
|
||||
// environment
|
||||
private float lastShootTime = 0.0f;
|
||||
public float lastShootTime = 0.0f;
|
||||
|
||||
private int enemyKillCount = 0;
|
||||
private Vector3 killEnemyPosition;
|
||||
public int enemyKillCount = 0;
|
||||
public Vector3 killEnemyPosition;
|
||||
public bool defaultTPCamera = true;
|
||||
|
||||
[System.NonSerialized] public bool gunReadyToggle = true;
|
||||
private string myTag = "";
|
||||
private float lastEnemyFacingDistance = 0f; // record last enemy facing minimum distance
|
||||
private float lastTargetFacingDistance = 0f; // record last target facing minimum distance
|
||||
public string myTag = "";
|
||||
|
||||
// scripts
|
||||
private RaySensors raySensors;
|
||||
|
||||
private CharacterController playerController;
|
||||
private CommonParameterContainer commonPramCon;
|
||||
private SceneBlockContainer blockContainer;
|
||||
private TargetController targetCon;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// initialize scripts
|
||||
commonPramCon = commonParameterContainerObj.GetComponent<CommonParameterContainer>();
|
||||
blockContainer = sceneBlockContainerObj.GetComponent<SceneBlockContainer>();
|
||||
targetCon = targetControllerObj.GetComponent<TargetController>();
|
||||
raySensors = GetComponent<RaySensors>();
|
||||
playerController = this.transform.GetComponent<CharacterController>();
|
||||
playerController = transform.GetComponent<CharacterController>();
|
||||
|
||||
// initialize Environment parameters
|
||||
lockMouse = commonPramCon.lockMouse;
|
||||
damage = commonPramCon.damage;
|
||||
fireRate = commonPramCon.fireRate;
|
||||
lockCameraX = commonPramCon.lockCameraX;
|
||||
lockCameraY = commonPramCon.lockCameraY;
|
||||
@@ -199,234 +173,7 @@ public class AgentController : MonoBehaviour
|
||||
|
||||
#endregion Camera Control
|
||||
|
||||
#region Reward Functions
|
||||
|
||||
// ballistic 射击弹道处理,并返回获得reward
|
||||
private float Ballistic(int shootState)
|
||||
{
|
||||
Vector3 point = new Vector3(fpsCam.pixelWidth / 2, fpsCam.pixelHeight / 2, 0);//发射位置
|
||||
Ray ray = fpsCam.ScreenPointToRay(point);
|
||||
RaycastHit hit;
|
||||
// Debug.DrawRay(centerRay.origin, centerRay.direction * 100, Color.blue);
|
||||
//按下鼠标左键
|
||||
if (shootState != 0 && gunReadyToggle == true)
|
||||
{
|
||||
lastShootTime = Time.time;
|
||||
if (Physics.Raycast(ray, out hit, 100))
|
||||
{
|
||||
if (hit.collider.tag != myTag && hit.collider.tag != "Wall" && hit.collider.tag != "Untagged")
|
||||
{
|
||||
// kill enemy
|
||||
GameObject gotHitObj = hit.transform.gameObject;//获取受到Ray撞击的对象
|
||||
gotHitObj.GetComponent<States>().ReactToHit(damage, gameObject);
|
||||
shootState = 0;
|
||||
return targetCon.HitEnemyReward(gotHitObj.transform.position);
|
||||
}
|
||||
}
|
||||
if (targetCon.targetTypeInt == (int)Targets.Attack)
|
||||
{
|
||||
// while if attack mode
|
||||
float targetDis = Vector3.Distance(blockContainer.nowBlock.transform.position, transform.position);
|
||||
if (targetDis <= raySensors.viewDistance)
|
||||
{
|
||||
// Debug.DrawRay(new Vector3(0,0,0), viewPoint, Color.red);
|
||||
if (Vector3.Distance(ray.origin + (ray.direction * targetDis), blockContainer.nowBlock.transform.position) <= blockContainer.nowBlock.firebasesAreaDiameter / 2)
|
||||
{
|
||||
// im shooting at target but didn't hit enemy
|
||||
// Debug.DrawRay(centerRay.origin, viewPoint-centerRay.origin, Color.blue);
|
||||
return commonPramCon.shootTargetAreaReward;
|
||||
}
|
||||
}
|
||||
}
|
||||
shootState = 0;
|
||||
return commonPramCon.shootReward;
|
||||
}
|
||||
else if (shootState != 0 && gunReadyToggle == false)
|
||||
{
|
||||
// shoot without ready
|
||||
shootState = 0;
|
||||
return commonPramCon.shootWithoutReadyReward;
|
||||
}
|
||||
else
|
||||
{
|
||||
// do not shoot
|
||||
shootState = 0;
|
||||
return commonPramCon.nonReward;
|
||||
}
|
||||
}
|
||||
|
||||
private float FacingReward()
|
||||
{
|
||||
float nowReward = 0;
|
||||
bool isFacingtoEnemy = false;
|
||||
float enemyFacingDistance = 0f;
|
||||
|
||||
Vector3 screenCenter = new Vector3(fpsCam.pixelWidth / 2, fpsCam.pixelHeight / 2, 0);
|
||||
Vector3 screenLeft = new Vector3(0, fpsCam.pixelHeight / 2, 0);
|
||||
|
||||
Ray centerRay = fpsCam.ScreenPointToRay(screenCenter);
|
||||
Ray leftRay = fpsCam.ScreenPointToRay(screenLeft);
|
||||
|
||||
// target fireBaseArea Position, turen y to camera's y
|
||||
Vector3 fireBaseArea = blockContainer.nowBlock.fireBasesAreaObj.transform.position;
|
||||
fireBaseArea.y = fpsCam.transform.position.y;
|
||||
|
||||
// my position, turn y to camera's y
|
||||
// Debug.DrawRay(fpsCam.transform.position, centerRay.direction * 100, Color.blue);
|
||||
Vector3 myposition = transform.position;
|
||||
myposition.y = fpsCam.transform.position.y;
|
||||
|
||||
// Target to Agent distance
|
||||
//Debug.DrawLine(fireBaseArea, myposition, Color.red);
|
||||
float targetDis = Vector3.Distance(fireBaseArea, myposition);
|
||||
|
||||
// point in centerRay and leftRay which distance is targetDis from camera center
|
||||
Vector3 pointInCenterRay = fpsCam.transform.position + (centerRay.direction * targetDis);
|
||||
Vector3 pointInLeftRay = fpsCam.transform.position + (leftRay.direction * targetDis);
|
||||
|
||||
// center of screen to target's distance
|
||||
// Debug.DrawLine(pointInCenterRay, fireBaseArea,Color.green);
|
||||
float camCenterToTarget = Vector3.Distance(pointInCenterRay, fireBaseArea);
|
||||
|
||||
// left of screen to target's distance
|
||||
// Debug.DrawLine(pointInLeftRay, pointInCenterRay, Color.yellow);
|
||||
float camCenterToViewEdge = Vector3.Distance(pointInLeftRay, pointInCenterRay);
|
||||
|
||||
switch (targetCon.targetTypeInt)
|
||||
{
|
||||
case (int)Targets.Free:
|
||||
//free mode
|
||||
RaycastHit hit;
|
||||
if (Physics.Raycast(centerRay, out hit, 100))
|
||||
{
|
||||
// facing to an enemy
|
||||
if (hit.collider.tag != myTag && hit.collider.tag != "Wall")
|
||||
{
|
||||
nowReward = commonPramCon.facingReward;
|
||||
isFacingtoEnemy = true;
|
||||
}
|
||||
}
|
||||
if (raySensors.inViewEnemies.Count > 0 && !isFacingtoEnemy)
|
||||
{
|
||||
// have enemy in view
|
||||
List<float> projectionDis = new List<float>();
|
||||
foreach (GameObject theEnemy in raySensors.inViewEnemies)
|
||||
{
|
||||
// for each enemy in view
|
||||
Vector3 projection = Vector3.Project(theEnemy.transform.position - transform.position, (centerRay.direction * 10));
|
||||
Vector3 verticalToRay = transform.position + projection - theEnemy.transform.position;
|
||||
projectionDis.Add(verticalToRay.magnitude);
|
||||
// Debug.Log("enemy!" + verticalToRay.magnitude);
|
||||
// Debug.DrawRay(transform.position, (centerRay.direction * 100), Color.cyan);
|
||||
// Debug.DrawRay(transform.position, theEnemy.transform.position - transform.position, Color.yellow);
|
||||
// Debug.DrawRay(transform.position, projection, Color.blue);
|
||||
// Debug.DrawRay(theEnemy.transform.position, verticalToRay, Color.magenta);
|
||||
}
|
||||
enemyFacingDistance = projectionDis.Min();
|
||||
if (enemyFacingDistance <= lastEnemyFacingDistance)
|
||||
{
|
||||
// closing to enemy
|
||||
nowReward = 1 / MathF.Sqrt(commonPramCon.facingInviewEnemyDisCOEF * enemyFacingDistance + 0.00001f);
|
||||
}
|
||||
else
|
||||
{
|
||||
nowReward = 0;
|
||||
}
|
||||
// enemy in view Reward
|
||||
lastEnemyFacingDistance = enemyFacingDistance;
|
||||
if (nowReward >= commonPramCon.facingReward) nowReward = commonPramCon.facingReward; // limit
|
||||
if (nowReward <= -commonPramCon.facingReward) nowReward = -commonPramCon.facingReward; // limit
|
||||
// Debug.Log("ninimum = " + nowReward);
|
||||
}
|
||||
break;
|
||||
case (int)Targets.Attack:
|
||||
// attack mode
|
||||
if (targetDis <= raySensors.viewDistance)
|
||||
{
|
||||
// Debug.DrawRay(new Vector3(0,0,0), viewPoint, Color.red);
|
||||
// while center of screen between target's distance is lower than firebasesAreaDiameter
|
||||
// while facing to target
|
||||
if (camCenterToTarget <= blockContainer.nowBlock.firebasesAreaDiameter / 2)
|
||||
{
|
||||
// Debug.DrawRay(centerRay.origin, viewPoint-centerRay.origin, Color.blue);
|
||||
nowReward = commonPramCon.facingReward;
|
||||
}
|
||||
else
|
||||
{
|
||||
// while not facing to target
|
||||
nowReward = (lastTargetFacingDistance - camCenterToTarget) * commonPramCon.facingTargetReward;
|
||||
}
|
||||
}
|
||||
// update lastTargetFacingDistance
|
||||
lastTargetFacingDistance = camCenterToTarget;
|
||||
break;
|
||||
case (int)Targets.Go:
|
||||
// goto mode
|
||||
if (camCenterToTarget <= camCenterToViewEdge)
|
||||
{
|
||||
// fireArea is in view
|
||||
nowReward = commonPramCon.facingReward;
|
||||
}
|
||||
else
|
||||
{
|
||||
nowReward = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Debug.LogError("Wrong target type");
|
||||
break;
|
||||
}
|
||||
return nowReward;
|
||||
}
|
||||
|
||||
public float RewardCalculate(float sceneReward, float mouseX, float movement, int shootState)
|
||||
{
|
||||
float epreward = 0f;
|
||||
// 击杀reward判断
|
||||
if (enemyKillCount > 0)
|
||||
{
|
||||
for (int i = 0; i < enemyKillCount; i++)
|
||||
{
|
||||
// get
|
||||
epreward += targetCon.KillReward(killEnemyPosition);
|
||||
}
|
||||
enemyKillCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
enemyKillCount = 0;
|
||||
}
|
||||
// 射击动作reward判断
|
||||
epreward += Ballistic(shootState) + sceneReward;
|
||||
// facing reward
|
||||
epreward += FacingReward();
|
||||
// Penalty
|
||||
// spin penalty
|
||||
spinRecord.Add(mouseX);
|
||||
if (spinRecord.Count >= commonPramCon.spinRecordMax)
|
||||
{
|
||||
spinRecord.RemoveAt(0);
|
||||
}
|
||||
float spinPenaltyReward = Math.Abs(spinRecord.ToArray().Sum() * commonPramCon.spinPenalty);
|
||||
if (spinPenaltyReward >= commonPramCon.spinPenaltyThreshold)
|
||||
{
|
||||
epreward -= spinPenaltyReward;
|
||||
}
|
||||
else
|
||||
{
|
||||
epreward -= Math.Abs(mouseX) * commonPramCon.mousePenalty;
|
||||
}
|
||||
// move penalty
|
||||
if (movement != 0)
|
||||
{
|
||||
epreward -= commonPramCon.movePenalty;
|
||||
}
|
||||
return epreward;
|
||||
}
|
||||
|
||||
#endregion Reward Functions
|
||||
|
||||
// GotKill 获得击杀时用于被呼出
|
||||
// Got Kill point
|
||||
public void KillRecord(Vector3 killEnemyPosition)
|
||||
{
|
||||
enemyKillCount += 1;
|
||||
|
||||
@@ -11,7 +11,6 @@ public class CommonParameterContainer : MonoBehaviour
|
||||
|
||||
[Header("Env")]
|
||||
public bool lockMouse = false;
|
||||
|
||||
public float damage = 50; // damage to enemy
|
||||
public float fireRate = 0.5f;
|
||||
public int timeLimit = 30;
|
||||
@@ -21,6 +20,8 @@ public class CommonParameterContainer : MonoBehaviour
|
||||
public int spinRecordMax = 40;
|
||||
public float spinPenaltyThreshold = 10;
|
||||
public float facingInviewEnemyDisCOEF = 0.5f;
|
||||
public string group1Tag = "Player";
|
||||
public string group2Tag = "Enemy";
|
||||
|
||||
[Header("Dynamic Defaut Rewards")]
|
||||
//[Tooltip("Hit Enemy reward")]
|
||||
|
||||
@@ -8,11 +8,12 @@ using UnityEngine;
|
||||
public class MLAgentsCustomController : Agent
|
||||
{
|
||||
[SerializeField] private GameObject paramContainerObj;
|
||||
[SerializeField] private GameObject CommonParameterContainer;
|
||||
[SerializeField] private GameObject commonParameterContainer;
|
||||
[SerializeField] private GameObject targetControllerObj;
|
||||
[SerializeField] private GameObject environmentUIObj;
|
||||
[SerializeField] private GameObject sideChannelObj;
|
||||
[SerializeField] private GameObject hudUIObj;
|
||||
[SerializeField] private GameObject worldUIControllerObj;
|
||||
[SerializeField] private GameObject hudObj;
|
||||
|
||||
[Header("Env")]
|
||||
public bool oneHotRayTag = true;
|
||||
@@ -29,6 +30,8 @@ public class MLAgentsCustomController : Agent
|
||||
private RaySensors raySensors;
|
||||
private MessageBoxController messageBoxController;
|
||||
private AimBotSideChannelController sideChannelController;
|
||||
private WorldUIController worldUICon;
|
||||
private RewardFunction rewardFunction;
|
||||
|
||||
// observation
|
||||
private float[] myObserve = new float[4];
|
||||
@@ -40,29 +43,26 @@ public class MLAgentsCustomController : Agent
|
||||
private float remainTime;
|
||||
private float inAreaState;
|
||||
|
||||
private int finishedState;
|
||||
private int step = 0;
|
||||
private int EP = 0;
|
||||
private int endTypeInt;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
agentController = transform.GetComponent<AgentController>();
|
||||
raySensors = transform.GetComponent<RaySensors>();
|
||||
paramContainer = paramContainerObj.GetComponent<ParameterContainer>();
|
||||
commonParamCon = CommonParameterContainer.GetComponent<CommonParameterContainer>();
|
||||
commonParamCon = commonParameterContainer.GetComponent<CommonParameterContainer>();
|
||||
targetController = targetControllerObj.GetComponent<TargetController>();
|
||||
envUIController = environmentUIObj.GetComponent<EnvironmentUIControl>();
|
||||
hudController = hudUIObj.GetComponent<HUDController>();
|
||||
targetUIController = hudUIObj.GetComponent<TargetUIController>();
|
||||
messageBoxController = hudUIObj.GetComponent<MessageBoxController>();
|
||||
hudController = hudObj.GetComponent<HUDController>();
|
||||
targetUIController = hudObj.GetComponent<TargetUIController>();
|
||||
messageBoxController = worldUIControllerObj.GetComponent<MessageBoxController>();
|
||||
sideChannelController = sideChannelObj.GetComponent<AimBotSideChannelController>();
|
||||
rewardFunction = gameObject.GetComponent<RewardFunction>();
|
||||
worldUICon = worldUIControllerObj.GetComponent<WorldUIController>();
|
||||
}
|
||||
|
||||
#region On episode begin function
|
||||
|
||||
public override void OnEpisodeBegin()
|
||||
{
|
||||
step = 0;
|
||||
agentController.UpdateLockMouse();
|
||||
paramContainer.ResetTimeBonusReward();
|
||||
if (commonParamCon.gameMode == 0)
|
||||
@@ -88,10 +88,6 @@ public class MLAgentsCustomController : Agent
|
||||
raySensors.UpdateRayInfo(); // update raycast
|
||||
}
|
||||
|
||||
#endregion On episode begin function
|
||||
|
||||
#region Observation sensor function
|
||||
|
||||
public override void CollectObservations(VectorSensor sensor)
|
||||
{
|
||||
//List<float> enemyLDisList = RaySensors.enemyLDisList;// All Enemy Lside Distances
|
||||
@@ -139,10 +135,6 @@ public class MLAgentsCustomController : Agent
|
||||
//sensor.AddObservation(remainTime); // RemainTime int
|
||||
}
|
||||
|
||||
#endregion Observation sensor function
|
||||
|
||||
#region Action received function
|
||||
|
||||
public override void OnActionReceived(ActionBuffers actionBuffers)
|
||||
{
|
||||
//获取输入
|
||||
@@ -161,24 +153,24 @@ public class MLAgentsCustomController : Agent
|
||||
//判断结束
|
||||
float sceneReward = 0f;
|
||||
float endReward = 0f;
|
||||
(finishedState, sceneReward, endReward) = targetController.CheckOverAndRewards();
|
||||
float nowRoundReward = agentController.RewardCalculate(sceneReward + endReward, Mouse_X, Math.Abs(vertical) + Math.Abs(horizontal), mouseShoot);
|
||||
(endTypeInt, sceneReward, endReward) = rewardFunction.CheckOverAndRewards();
|
||||
float nowReward = rewardFunction.RewardCalculate(sceneReward + endReward, Mouse_X, Math.Abs(vertical) + Math.Abs(horizontal), mouseShoot);
|
||||
if (hudController.chartOn)
|
||||
{
|
||||
envUIController.UpdateChart(nowRoundReward);
|
||||
envUIController.UpdateChart(nowReward);
|
||||
}
|
||||
else
|
||||
{
|
||||
envUIController.RemoveChart();
|
||||
}
|
||||
//Debug.Log("reward = " + nowRoundReward);
|
||||
if (finishedState != (int)TargetController.EndType.Running)
|
||||
worldUICon.UpdateChart(targetController.targetTypeInt, endTypeInt);
|
||||
//Debug.Log("reward = " + nowReward);
|
||||
if (endTypeInt != (int)TargetController.EndType.Running)
|
||||
{
|
||||
// Win or lose Finished
|
||||
Debug.Log("Finish reward = " + nowRoundReward);
|
||||
EP += 1;
|
||||
Debug.Log("Finish reward = " + nowReward);
|
||||
string targetString = Enum.GetName(typeof(Targets), targetController.targetTypeInt);
|
||||
switch (finishedState)
|
||||
switch (endTypeInt)
|
||||
{
|
||||
case (int)TargetController.EndType.Win:
|
||||
sideChannelController.SendSideChannelMessage("Result", targetString + "|Win");
|
||||
@@ -198,21 +190,16 @@ public class MLAgentsCustomController : Agent
|
||||
Debug.LogWarning("TypeError");
|
||||
break;
|
||||
}
|
||||
SetReward(nowRoundReward);
|
||||
SetReward(nowReward);
|
||||
EndEpisode();
|
||||
}
|
||||
else
|
||||
{
|
||||
// game not over yet
|
||||
step += 1;
|
||||
}
|
||||
SetReward(nowRoundReward);
|
||||
SetReward(nowReward);
|
||||
}
|
||||
|
||||
#endregion Action received function
|
||||
|
||||
#region Heuristic function
|
||||
|
||||
public override void Heuristic(in ActionBuffers actionsOut)
|
||||
{
|
||||
//-------------------BUILD
|
||||
@@ -270,6 +257,4 @@ public class MLAgentsCustomController : Agent
|
||||
//continuousActions[2] = timeLimit;
|
||||
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^continuous-Control^^^^^^^^^^^^^^^^^^^^^^
|
||||
}
|
||||
|
||||
#endregion Heuristic function
|
||||
}
|
||||
@@ -5,24 +5,13 @@ using Random = UnityEngine.Random;
|
||||
|
||||
public class TargetController : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private GameObject environmentObj;
|
||||
[SerializeField]
|
||||
private GameObject agentObj;
|
||||
[SerializeField]
|
||||
private GameObject HUDObj;
|
||||
[SerializeField]
|
||||
private GameObject sceneBlockContainerObj;
|
||||
[SerializeField]
|
||||
private GameObject enemyContainerObj;
|
||||
[SerializeField]
|
||||
private GameObject parameterContainerObj;
|
||||
[SerializeField]
|
||||
private GameObject commonParameterContainerObj;
|
||||
[SerializeField]
|
||||
private GameObject environmentUIObj;
|
||||
[SerializeField]
|
||||
private GameObject worldUIObj;
|
||||
[SerializeField] private GameObject environmentObj;
|
||||
[SerializeField] private GameObject agentObj;
|
||||
[SerializeField] private GameObject HUDObj;
|
||||
[SerializeField] private GameObject sceneBlockContainerObj;
|
||||
[SerializeField] private GameObject enemyContainerObj;
|
||||
[SerializeField] private GameObject commonParameterContainerObj;
|
||||
[SerializeField] private GameObject environmentUIObj;
|
||||
|
||||
// area
|
||||
public GameObject edgeUp;
|
||||
@@ -32,11 +21,6 @@ public class TargetController : MonoBehaviour
|
||||
public GameObject edgeRight;
|
||||
public GameObject edgeAgent_Enemy;
|
||||
|
||||
//group
|
||||
public string group1Tag = "Player";
|
||||
|
||||
public string group2Tag = "Enemy";
|
||||
|
||||
public float minEnemyAreaX;
|
||||
[System.NonSerialized] public float maxEnemyAreaX;
|
||||
[System.NonSerialized] public float minEnemyAreaZ;
|
||||
@@ -63,23 +47,20 @@ public class TargetController : MonoBehaviour
|
||||
[System.NonSerialized] public int targetNum = 0;
|
||||
private Dictionary<int, float[]> oneHotRarget = new Dictionary<int, float[]>();
|
||||
|
||||
private int inArea = 0;
|
||||
private float freeProb;
|
||||
private float sceneBlockSize;
|
||||
private float lastDistance;
|
||||
private int randBlockType = 0;
|
||||
private int randLevel = 0;
|
||||
public int inArea = 0;
|
||||
public Vector3 targetPosition;
|
||||
private bool firstRewardFlag = true;
|
||||
private bool targetEnemySpawnFinish = false;
|
||||
public bool targetEnemySpawnFinish = false;
|
||||
|
||||
private SceneBlockContainer sceneBlockCon;
|
||||
private EnemyContainer enemyCon;
|
||||
private EnvironmentUIControl envUICon;
|
||||
private ParameterContainer paramCon;
|
||||
private CommonParameterContainer commonParamCon;
|
||||
private CharacterController agentCharaCon;
|
||||
private WorldUIController worldUICon;
|
||||
private HUDController hudCon;
|
||||
private MessageBoxController messageBoxCon;
|
||||
|
||||
@@ -94,8 +75,6 @@ public class TargetController : MonoBehaviour
|
||||
envUICon = environmentUIObj.GetComponent<EnvironmentUIControl>();
|
||||
enemyCon = enemyContainerObj.GetComponent<EnemyContainer>();
|
||||
agentCharaCon = agentObj.GetComponent<CharacterController>();
|
||||
paramCon = parameterContainerObj.GetComponent<ParameterContainer>();
|
||||
worldUICon = worldUIObj.GetComponent<WorldUIController>();
|
||||
hudCon = HUDObj.GetComponent<HUDController>();
|
||||
messageBoxCon = HUDObj.GetComponent<MessageBoxController>();
|
||||
|
||||
@@ -279,7 +258,7 @@ public class TargetController : MonoBehaviour
|
||||
|
||||
// init scene block
|
||||
sceneBlockCon.DestroyBlock();
|
||||
sceneBlockCon.CreateNewBlock(targetType, randLevel, randBlockType, targetPosition, group1Tag, group2Tag);
|
||||
sceneBlockCon.CreateNewBlock(targetType, randLevel, randBlockType, targetPosition, commonParamCon.group1Tag, commonParamCon.group2Tag);
|
||||
enemyCon.DestroyAllEnemys();
|
||||
enemyCon.RandomInitEnemysExcept(hudCon.enemyNum, targetPosition, sceneBlockSize);
|
||||
sceneBlockCon.nowBlock.InitBlock(environmentObj);
|
||||
@@ -287,260 +266,6 @@ public class TargetController : MonoBehaviour
|
||||
|
||||
#endregion Random SceneBlock Spawn Method
|
||||
|
||||
#region Reward function
|
||||
|
||||
/// <summary>
|
||||
/// Checks the game's end state and retrieves rewards.
|
||||
/// </summary>
|
||||
/// <returns>A tuple containing the game's end type, current reward, and final reward.
|
||||
/// 1 = success,2 = overtime,0 = notover</returns>
|
||||
public (int, float, float) CheckOverAndRewards()
|
||||
{
|
||||
int endTypeInt = 0;
|
||||
float nowReward = 0;
|
||||
float endReward = 0;
|
||||
float nowDistance = 0f;
|
||||
switch (targetTypeInt)
|
||||
{
|
||||
case (int)Targets.Go:
|
||||
// goto
|
||||
(nowDistance, inArea) = sceneBlockCon.GetAgentTargetDistanceAndInside(agentObj.transform.position);
|
||||
envUICon.UpdateTargetGauge(sceneBlockCon.nowBlock.firebasesBelong, sceneBlockCon.nowBlock.belongMaxPoint);
|
||||
float areaTargetReward = GetDistanceReward(nowDistance, inArea);
|
||||
//if(inArea != 0)
|
||||
if (sceneBlockCon.nowBlock.firebasesBelong >= sceneBlockCon.nowBlock.belongMaxPoint)
|
||||
{
|
||||
// win
|
||||
// let the area belongs to me
|
||||
nowReward = areaTargetReward;
|
||||
endReward = paramCon.goWinReward;
|
||||
//nowReward = (paramCon.inAreaReward * inArea) + getDistanceReward(nowDistance);
|
||||
endTypeInt = (int)EndType.Win;
|
||||
}
|
||||
else if (leftTime <= 0)
|
||||
{
|
||||
// time out lose
|
||||
nowReward = areaTargetReward;
|
||||
endReward = commonParamCon.loseReward;
|
||||
endTypeInt = (int)EndType.Lose;
|
||||
}
|
||||
else
|
||||
{
|
||||
// keep on keeping on!
|
||||
nowReward = areaTargetReward;
|
||||
endReward = 0;
|
||||
endTypeInt = (int)EndType.Running;
|
||||
}
|
||||
break;
|
||||
|
||||
case (int)Targets.Attack:
|
||||
// attack
|
||||
(nowDistance, inArea) = sceneBlockCon.GetAgentTargetDistanceAndInside(agentObj.transform.position);
|
||||
envUICon.UpdateTargetGauge(sceneBlockCon.nowBlock.firebasesBelong, sceneBlockCon.nowBlock.belongMaxPoint);
|
||||
if (sceneBlockCon.nowBlock.GetInAreaNumber(group2Tag) <= 0 && targetEnemySpawnFinish)
|
||||
{
|
||||
// win
|
||||
// let the area belongs to me and kill every enmy in this area.
|
||||
nowReward = 0;
|
||||
endReward = paramCon.attackWinReward;
|
||||
//nowReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
|
||||
endTypeInt = (int)EndType.Win;
|
||||
targetEnemySpawnFinish = false;
|
||||
}
|
||||
else if (leftTime <= 0 && targetEnemySpawnFinish)
|
||||
{
|
||||
// time out lose
|
||||
nowReward = 0;
|
||||
endReward = commonParamCon.loseReward;
|
||||
//nowReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
|
||||
endTypeInt = (int)EndType.Lose;
|
||||
targetEnemySpawnFinish = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// keep on keeping on!
|
||||
// nowReward = (paramCon.inAreaReward * inArea) + getDistanceReward(nowDistance);
|
||||
nowReward = 0;
|
||||
endReward = 0;
|
||||
targetEnemySpawnFinish = true;
|
||||
endTypeInt = (int)EndType.Running;
|
||||
}
|
||||
break;
|
||||
|
||||
case (int)Targets.Defence:
|
||||
//defence
|
||||
// !!! DIDN't FINISH!!!
|
||||
(nowDistance, inArea) = sceneBlockCon.GetAgentTargetDistanceAndInside(agentObj.transform.position);
|
||||
envUICon.UpdateTargetGauge(sceneBlockCon.nowBlock.firebasesBelong, sceneBlockCon.nowBlock.belongMaxPoint);
|
||||
if (leftTime <= 0 && sceneBlockCon.nowBlock.firebasesBelong >= 0f)
|
||||
{
|
||||
// win
|
||||
// time over and the area still mine
|
||||
nowReward = paramCon.defenceWinReward;
|
||||
//nowReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
|
||||
endTypeInt = (int)EndType.Win;
|
||||
}
|
||||
else if (sceneBlockCon.nowBlock.firebasesBelong <= sceneBlockCon.nowBlock.belongMaxPoint)
|
||||
{
|
||||
// lost area lose
|
||||
nowReward = commonParamCon.loseReward;
|
||||
//nowReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
|
||||
endTypeInt = (int)EndType.Lose;
|
||||
}
|
||||
else
|
||||
{
|
||||
// keep on keeping on!
|
||||
// nowReward = (paramCon.inAreaReward * inArea) + getDistanceReward(nowDistance);
|
||||
endTypeInt = (int)EndType.Running;
|
||||
}
|
||||
break;
|
||||
|
||||
case (int)Targets.Stay:
|
||||
// Stay
|
||||
// endless
|
||||
nowReward = 0;
|
||||
endReward = 0;
|
||||
endTypeInt = (int)EndType.Running;
|
||||
break;
|
||||
|
||||
default:
|
||||
//free kill
|
||||
if (enemyContainerObj.transform.childCount <= 0)
|
||||
{
|
||||
// win
|
||||
// nowReward = paramCon.winReward + (paramCon.timeBonusPerSecReward * leftTime);
|
||||
nowReward = 0;
|
||||
endReward = paramCon.freeWinReward;
|
||||
endTypeInt = (int)EndType.Win;
|
||||
}
|
||||
else if (leftTime <= 0)
|
||||
{
|
||||
// lose
|
||||
//nowReward = paramCon.loseReward;
|
||||
nowReward = 0;
|
||||
endReward = commonParamCon.loseReward;
|
||||
endTypeInt = (int)EndType.Lose;
|
||||
}
|
||||
else
|
||||
{
|
||||
// keep on keeping on!
|
||||
nowReward = 0;
|
||||
endReward = 0;
|
||||
endTypeInt = (int)EndType.Running;
|
||||
}
|
||||
break;
|
||||
}
|
||||
envUICon.ShowResult(endTypeInt);
|
||||
worldUICon.UpdateChart(targetTypeInt, endTypeInt);
|
||||
return (endTypeInt, nowReward, endReward);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates scene reward based on distance, granting higher rewards for being closer to the target.
|
||||
/// 根据距离计算场景奖励,靠近目标则获得更高奖励。
|
||||
/// </summary>
|
||||
/// <param name="nowDistance">The current distance.</param>
|
||||
/// <param name="inarea">Whether inside an area.</param>
|
||||
/// <returns>The reward value calculated based on distance.</returns>
|
||||
private float GetDistanceReward(float nowDistance, int inarea)
|
||||
{
|
||||
if (firstRewardFlag)
|
||||
{
|
||||
// first distance record
|
||||
(lastDistance, _) = sceneBlockCon.GetAgentTargetDistanceAndInside(agentObj.transform.position);
|
||||
firstRewardFlag = false;
|
||||
}
|
||||
float nowSeneReward = 0f;
|
||||
if (inarea != 0)
|
||||
{
|
||||
// in area
|
||||
nowSeneReward = paramCon.inAreaReward;
|
||||
}
|
||||
else
|
||||
{
|
||||
// out of area
|
||||
// nowSeneReward = paramCon.distanceReward * Math.Clamp(lastDistance - nowDistance, 0, 100);
|
||||
nowSeneReward = commonParamCon.distanceReward * (lastDistance - nowDistance);
|
||||
}
|
||||
lastDistance = nowDistance;
|
||||
return nowSeneReward;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates kill reward based on the position of the killed enemy.
|
||||
/// 根据击杀的敌人位置计算击杀奖励。
|
||||
/// </summary>
|
||||
/// <param name="enemyPosition">The position of the killed enemy.</param>
|
||||
/// <returns>The reward value calculated based on the kill position.</returns>
|
||||
public float KillReward(Vector3 enemyPosition)
|
||||
{
|
||||
float nowKillReward = 0f;
|
||||
if (targetTypeInt == (int)Targets.Attack)
|
||||
{
|
||||
// attack mode
|
||||
(_, int isInArea) = sceneBlockCon.nowBlock.GetDistInArea(enemyPosition);
|
||||
if (isInArea == 1)
|
||||
{
|
||||
// kill in area enemy
|
||||
nowKillReward = paramCon.killTargetEnemyReward;
|
||||
}
|
||||
else
|
||||
{
|
||||
nowKillReward = commonParamCon.killNonTargetReward;
|
||||
}
|
||||
}
|
||||
else if (targetTypeInt == (int)Targets.Free)
|
||||
{
|
||||
// free mode hit
|
||||
nowKillReward = paramCon.killTargetEnemyReward;
|
||||
}
|
||||
else
|
||||
{
|
||||
// goto & defence
|
||||
nowKillReward = commonParamCon.killNonTargetReward;
|
||||
}
|
||||
return nowKillReward;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates hit reward based on the position of the hit enemy and the current mode.
|
||||
/// 根据击中的敌人位置和当前模式计算击中Reward。
|
||||
/// </summary>
|
||||
/// <param name="enemyPosition">The position of the hit enemy.</param>
|
||||
/// <returns>The reward value calculated based on the hit position and mode.</returns>
|
||||
public float HitEnemyReward(Vector3 enemyPosition)
|
||||
{
|
||||
float nowHitReward = 0f;
|
||||
if (targetTypeInt == (int)Targets.Attack)
|
||||
{
|
||||
// attack mode
|
||||
(_, int isInArea) = sceneBlockCon.nowBlock.GetDistInArea(enemyPosition);
|
||||
if (isInArea == 1)
|
||||
{
|
||||
// hit in area enemy
|
||||
nowHitReward = paramCon.hitTargetReward;
|
||||
}
|
||||
else
|
||||
{
|
||||
// hit not in area enemy
|
||||
nowHitReward = commonParamCon.hitNonTargetReward;
|
||||
}
|
||||
}
|
||||
else if (targetTypeInt == (int)Targets.Free)
|
||||
{
|
||||
// free mode hit
|
||||
nowHitReward = paramCon.hitTargetReward;
|
||||
}
|
||||
else
|
||||
{
|
||||
// goto & defence
|
||||
nowHitReward = commonParamCon.hitNonTargetReward;
|
||||
}
|
||||
return nowHitReward;
|
||||
}
|
||||
|
||||
#endregion Reward function
|
||||
|
||||
#region Play Mode Method
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user