V3.2.2 开始创建MultiLevel

使用Multi level使AI适应更复杂环境
基本Level创建完成
UI逻辑创建中
This commit is contained in:
2023-08-23 02:58:50 +09:00
parent 3381c83604
commit 5226f1dbbf
160 changed files with 43551 additions and 43731 deletions
+33 -33
View File
@@ -12,14 +12,14 @@ public class AgentController : MonoBehaviour
public GameObject environmentUIControlObj;
public GameObject targetControllerObj;
public GameObject HUDObj;
public Camera thisCam;
public Camera nowCam;
[Header("GetAxis() Simulate")]
public float moveSpeed = 9.0f;
public float vX = 0f;
public float vZ = 0f;
public Vector3 thisMovement;
public Vector3 nowMovement;
public float acceleration = 0.9f; // 加速度
public float mouseXSensitivity = 100;
public float mouseYSensitivity = 200;
@@ -77,7 +77,7 @@ public class AgentController : MonoBehaviour
public void MoveAgent(int vertical, int horizontal)
{
// Vector3 thisMovement;
// Vector3 nowMovement;
if (horizontal != 0)//当按下按键(水平方向)
{
if (vX < moveSpeed && vX > -moveSpeed)//当前速度小于最大速度
@@ -138,14 +138,14 @@ public class AgentController : MonoBehaviour
vZ = 0;
}
}
thisMovement = (transform.forward * vZ + transform.right * vX);
nowMovement = (transform.forward * vZ + transform.right * vX);
//PlayerController下的.Move为实现物体运动的函数
//Move()括号内放入一个Vector3类型的量,本例中为Player_Move
if (thisMovement.magnitude > moveSpeed)
if (nowMovement.magnitude > moveSpeed)
{
thisMovement = thisMovement.normalized * moveSpeed;
nowMovement = nowMovement.normalized * moveSpeed;
}
playerController.Move(thisMovement * Time.deltaTime);
playerController.Move(nowMovement * Time.deltaTime);
// update Key Viewer
}
@@ -182,7 +182,7 @@ public class AgentController : MonoBehaviour
//相机在上下旋转移动时,相机方向不会随着移动,类似于低头和抬头,左右移动时,相机方向会随着向左向右移动,类似于向左向右看
//所以在控制相机向左向右旋转时,要保证和父物体一起转动
thisCam.transform.localRotation = Quaternion.Euler(yRotation, 0, 0);
nowCam.transform.localRotation = Quaternion.Euler(yRotation, 0, 0);
//this.transform指这个CameraRotation的位置,localRotation指的是旋转轴
//transform.localRotation = Quaternion.Eular(x,y,z)控制旋转的时候,按照X-Y-Z轴的旋转顺规
//即以围绕X轴旋转x度,围绕Y轴旋转y度,围绕Z轴旋转z度
@@ -196,8 +196,8 @@ public class AgentController : MonoBehaviour
// ballistic 射击弹道处理,并返回获得reward
private float Ballistic(int shootState)
{
Vector3 point = new Vector3(thisCam.pixelWidth / 2, thisCam.pixelHeight / 2, 0);//发射位置
Ray ray = thisCam.ScreenPointToRay(point);
Vector3 point = new Vector3(nowCam.pixelWidth / 2, nowCam.pixelHeight / 2, 0);//发射位置
Ray ray = nowCam.ScreenPointToRay(point);
RaycastHit hit;
// Debug.DrawRay(ray.origin, ray.direction * 100, Color.blue);
//按下鼠标左键
@@ -218,11 +218,11 @@ public class AgentController : MonoBehaviour
if (targetCon.targetTypeInt == (int)SceneBlockContainer.Targets.Attack)
{
// while if attack mode
float targetDis = Vector3.Distance(blockContainer.thisBlock.transform.position, transform.position);
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.thisBlock.transform.position) <= blockContainer.thisBlock.firebasesAreaDiameter / 2)
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(ray.origin, viewPoint-ray.origin, Color.blue);
@@ -249,10 +249,10 @@ public class AgentController : MonoBehaviour
private float FacingReward()
{
float thisReward = 0;
float nowReward = 0;
bool isFacingtoEnemy = false;
float enemyFacingDistance = 0f;
Ray ray = thisCam.ScreenPointToRay(new Vector3(thisCam.pixelWidth / 2, thisCam.pixelHeight / 2, 0));
Ray ray = nowCam.ScreenPointToRay(new Vector3(nowCam.pixelWidth / 2, nowCam.pixelHeight / 2, 0));
if (targetCon.targetTypeInt == (int)SceneBlockContainer.Targets.Free)
{
//free mode
@@ -262,7 +262,7 @@ public class AgentController : MonoBehaviour
// facing to an enemy
if (hit.collider.tag != myTag && hit.collider.tag != "Wall")
{
thisReward = paramContainer.facingReward;
nowReward = paramContainer.facingReward;
isFacingtoEnemy = true;
}
}
@@ -270,63 +270,63 @@ public class AgentController : MonoBehaviour
{
// have enemy in view
List<float> projectionDis = new List<float>();
foreach (GameObject thisEnemy in raySensors.inViewEnemies)
foreach (GameObject theEnemy in raySensors.inViewEnemies)
{
// for each enemy in view
Vector3 projection = Vector3.Project(thisEnemy.transform.position - transform.position, (ray.direction * 10));
Vector3 verticalToRay = transform.position + projection - thisEnemy.transform.position;
Vector3 projection = Vector3.Project(theEnemy.transform.position - transform.position, (ray.direction * 10));
Vector3 verticalToRay = transform.position + projection - theEnemy.transform.position;
projectionDis.Add(verticalToRay.magnitude);
// Debug.Log("enemy!" + verticalToRay.magnitude);
// Debug.DrawRay(transform.position, (ray.direction * 100), Color.cyan);
// Debug.DrawRay(transform.position, thisEnemy.transform.position - transform.position, Color.yellow);
// Debug.DrawRay(transform.position, theEnemy.transform.position - transform.position, Color.yellow);
// Debug.DrawRay(transform.position, projection, Color.blue);
// Debug.DrawRay(thisEnemy.transform.position, verticalToRay, Color.magenta);
// Debug.DrawRay(theEnemy.transform.position, verticalToRay, Color.magenta);
}
enemyFacingDistance = projectionDis.Min();
if (enemyFacingDistance <= lastEnemyFacingDistance)
{
// closing to enemy
thisReward = 1 / MathF.Sqrt(paramContainer.facingInviewEnemyDisCOEF * enemyFacingDistance + 0.00001f);
nowReward = 1 / MathF.Sqrt(paramContainer.facingInviewEnemyDisCOEF * enemyFacingDistance + 0.00001f);
}
else
{
thisReward = 0;
nowReward = 0;
}
// enemy in view Reward
lastEnemyFacingDistance = enemyFacingDistance;
if (thisReward >= paramContainer.facingReward) thisReward = paramContainer.facingReward; // limit
if (thisReward <= -paramContainer.facingReward) thisReward = -paramContainer.facingReward; // limit
// Debug.Log("ninimum = " + thisReward);
if (nowReward >= paramContainer.facingReward) nowReward = paramContainer.facingReward; // limit
if (nowReward <= -paramContainer.facingReward) nowReward = -paramContainer.facingReward; // limit
// Debug.Log("ninimum = " + nowReward);
}
}
else if (targetCon.targetTypeInt == (int)SceneBlockContainer.Targets.Attack)
{
// attack mode
// Target to Agent distance
float targetDis = Vector3.Distance(blockContainer.thisBlock.transform.position, transform.position);
float targetDis = Vector3.Distance(blockContainer.nowBlock.transform.position, transform.position);
// center of screen between target's distance
float camCenterToTarget = Vector3.Distance(ray.origin + (ray.direction * targetDis), blockContainer.thisBlock.transform.position);
float camCenterToTarget = Vector3.Distance(ray.origin + (ray.direction * targetDis), blockContainer.nowBlock.transform.position);
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.thisBlock.firebasesAreaDiameter / 2)
if (camCenterToTarget <= blockContainer.nowBlock.firebasesAreaDiameter / 2)
{
// Debug.DrawRay(ray.origin, viewPoint-ray.origin, Color.blue);
thisReward = paramContainer.facingReward;
nowReward = paramContainer.facingReward;
}
else
{
// while not facing to target
thisReward = (lastTargetFacingDistance - camCenterToTarget) * paramContainer.facingTargetReward;
nowReward = (lastTargetFacingDistance - camCenterToTarget) * paramContainer.facingTargetReward;
}
}
// update lastTargetFacingDistance
lastTargetFacingDistance = camCenterToTarget;
}
return thisReward;
return nowReward;
}
public float RewardCalculate(float sceneReward, float mouseX, float movement, int shootState)
@@ -377,10 +377,10 @@ public class AgentController : MonoBehaviour
#endregion Reward Functions
// GotKill 获得击杀时用于被呼出
public void KillRecord(Vector3 thiskillEnemyPosition)
public void KillRecord(Vector3 killEnemyPosition)
{
enemyKillCount += 1;
killEnemyPosition = thiskillEnemyPosition;
this.killEnemyPosition = killEnemyPosition;
}
public void UpdateLockMouse()
+3 -3
View File
@@ -49,10 +49,10 @@ public class EnemyContainer : MonoBehaviour
}
}
// initialize enemy to thisPosition
public void InitEnemyAtHere(Vector3 thisPosition)
// initialize enemy to position
public void InitEnemyAtHere(Vector3 position)
{
Instantiate(enemyPrefab, thisPosition + environmentObj.transform.position, Quaternion.identity, this.transform);
Instantiate(enemyPrefab, position + environmentObj.transform.position, Quaternion.identity, this.transform);
}
// destroyEnemy delete enemyContainer's all enemy
@@ -59,7 +59,6 @@ public class MLAgentsCustomController : Agent
step = 0;
agentController.UpdateLockMouse();
paramContainer.ResetTimeBonusReward();
//thisAgentObj.name = thisAgentObj.GetInstanceID().ToString();
if (paramContainer.gameMode == 0)
{
// train mode
@@ -157,20 +156,20 @@ public class MLAgentsCustomController : Agent
float sceneReward = 0f;
float endReward = 0f;
(finishedState, sceneReward, endReward) = targetController.CheckOverAndRewards();
float thisRoundReward = agentController.RewardCalculate(sceneReward + endReward, Mouse_X, Math.Abs(vertical) + Math.Abs(horizontal), mouseShoot);
float nowRoundReward = agentController.RewardCalculate(sceneReward + endReward, Mouse_X, Math.Abs(vertical) + Math.Abs(horizontal), mouseShoot);
if (hudController.chartOn)
{
envUIController.UpdateChart(thisRoundReward);
envUIController.UpdateChart(nowRoundReward);
}
else
{
envUIController.RemoveChart();
}
//Debug.Log("reward = " + thisRoundReward);
//Debug.Log("reward = " + nowRoundReward);
if (finishedState != (int)TargetController.EndType.Running)
{
// Win or lose Finished
Debug.Log("Finish reward = " + thisRoundReward);
Debug.Log("Finish reward = " + nowRoundReward);
EP += 1;
string targetString = Enum.GetName(typeof(SceneBlockContainer.Targets), targetController.targetTypeInt);
switch (finishedState)
@@ -193,7 +192,7 @@ public class MLAgentsCustomController : Agent
Debug.LogWarning("TypeError");
break;
}
SetReward(thisRoundReward);
SetReward(nowRoundReward);
EndEpisode();
}
else
@@ -201,7 +200,7 @@ public class MLAgentsCustomController : Agent
// game not over yet
step += 1;
}
SetReward(thisRoundReward);
SetReward(nowRoundReward);
}
#endregion Action received function
+6 -6
View File
@@ -13,10 +13,10 @@ public class Onehot
totalNum = tags.Count;
for (int i = 0; i < totalNum; i++)
{
List<float> thisOnehot = new List<float>();
for (int j = 0; j < totalNum; j++) thisOnehot.Add(0f);
thisOnehot[i] = 1f;
onehot.Add(thisOnehot);
List<float> oneHot = new List<float>();
for (int j = 0; j < totalNum; j++) oneHot.Add(0f);
oneHot[i] = 1f;
onehot.Add(oneHot);
}
}
@@ -43,8 +43,8 @@ public class Onehot
}
}
public string Decoder(List<float> thisOnehot)
public string Decoder(List<float> oneHot)
{
return tags[onehot.IndexOf(thisOnehot)];
return tags[onehot.IndexOf(oneHot)];
}
}
+7 -1
View File
@@ -138,8 +138,11 @@ public class ParameterContainer : MonoBehaviour
[System.NonSerialized] public int gameMode; // 0 = trainning mode, 1 = play mode
[System.NonSerialized] public float attackProb = 0f;
[System.NonSerialized] public List<float> attackLevelProbs = new List<float>();
[System.NonSerialized] public float gotoProb = 0f;
[System.NonSerialized] public List<float> gotoLevelProbs = new List<float>();
[System.NonSerialized] public float defenceProb = 0f;
[System.NonSerialized] public List<float> defenceLevelProbs = new List<float>();
private void Start()
{
@@ -162,13 +165,16 @@ public class ParameterContainer : MonoBehaviour
// if not found, find dummy StartSeneData
startSceneData = GameObject.Find("StartSceneDataTransferDummy").GetComponent<StartSeneData>();
messageCon.PushMessage(
new List<string> { "ParameterContainer:", "StartSceneDataTransfer not found!" },
new List<string> { "ParameterContainer:", "StartSceneDataTransfer not found!Use Dummy." },
new List<string> { "orange" });
}
gameMode = startSceneData.gameMode;
attackProb = startSceneData.attackProb;
attackLevelProbs = startSceneData.attackLevelProbs;
gotoProb = startSceneData.gotoProb;
gotoLevelProbs = startSceneData.gotoLevelProbs;
defenceProb = startSceneData.defenceProb;
defenceLevelProbs = startSceneData.defenceLevelProbs;
}
private void Update()
+34 -34
View File
@@ -86,20 +86,20 @@ public class RaySensors : MonoBehaviour
}
}
private void SingleRaycastUpdate(Ray ray, LineRenderer thisLineRenderer, RayInfoUI thisRayInfoUI, out float rayTagResult, out float rayDisResult)
private void SingleRaycastUpdate(Ray ray, LineRenderer lineRenderer, RayInfoUI rayInfoUI, out float rayTagResult, out float rayDisResult)
{
// get Raycast hit infomation and return Tag and distance
RaycastHit thisHit;
RaycastHit nowHit;
Color rayColor = Color.cyan;
float lineLength = viewDistance;
string rayInfoText = "";
Vector3 rayInfoPosition;
if (Physics.Raycast(ray, out thisHit, viewDistance)) // 若在viewDistance范围内有碰撞
if (Physics.Raycast(ray, out nowHit, viewDistance)) // 若在viewDistance范围内有碰撞
{
rayInfoText = thisHit.collider.tag;
rayInfoText = nowHit.collider.tag;
rayTagResult = TagToInt(rayInfoText);
rayTagResultOneHot.AddRange(oneHotTags.Encoder(rayInfoText));
rayDisResult = thisHit.distance;
rayDisResult = nowHit.distance;
lineLength = rayDisResult;
rayInfoText += "\n" + Convert.ToString(rayDisResult);
// rayDisResult = rayDisResult / viewDistance; // Normalization!
@@ -112,7 +112,7 @@ public class RaySensors : MonoBehaviour
case 2: // Enemy
rayColor = Color.red;
inViewEnemies.Add(thisHit.transform.gameObject);
inViewEnemies.Add(nowHit.transform.gameObject);
break;
case -1: // Hit Nothing
@@ -136,65 +136,65 @@ public class RaySensors : MonoBehaviour
rayInfoPosition = ray.origin + (ray.direction * lineLength);
if (showInGameRay)
{
DrawLine(ray, lineLength, thisLineRenderer, rayColor);
DrawLine(ray, lineLength, lineRenderer, rayColor);
}
else
{
TurnOffLine(thisLineRenderer, rayColor);
TurnOffLine(lineRenderer, rayColor);
}
// drawRay in game
if (showInGameRayInfo) thisRayInfoUI.UpdateInfo(rayInfoText, rayInfoPosition, rayColor, TPSCam);
if (showInGameRayInfo) rayInfoUI.UpdateInfo(rayInfoText, rayInfoPosition, rayColor, TPSCam);
// Show log
if (showDebugRay) Debug.DrawRay(ray.origin, ray.direction * viewDistance, rayColor); // drawRay in debug
// Debug.Log(ray.origin + ray.direction);
// Debug.Log(rayTagResult);
// Debug.Log(tagToInt(thisHit.collider.tag));
// Debug.Log(tagToInt(nowHit.collider.tag));
}
private void DrawLine(Ray ray, float lineLength, LineRenderer thisLineRenderer, Color lineColor)
private void DrawLine(Ray ray, float lineLength, LineRenderer lineRenderer, Color lineColor)
{
thisLineRenderer.startColor = lineColor;
thisLineRenderer.endColor = lineColor;
thisLineRenderer.startWidth = lineWidth;
thisLineRenderer.endWidth = lineWidth;
thisLineRenderer.SetPosition(0, ray.origin);
thisLineRenderer.SetPosition(1, ray.origin + (ray.direction * lineLength));
lineRenderer.startColor = lineColor;
lineRenderer.endColor = lineColor;
lineRenderer.startWidth = lineWidth;
lineRenderer.endWidth = lineWidth;
lineRenderer.SetPosition(0, ray.origin);
lineRenderer.SetPosition(1, ray.origin + (ray.direction * lineLength));
}
private void TurnOffLine(LineRenderer thisLineRenderer, Color lineColor)
private void TurnOffLine(LineRenderer lineRenderer, Color lineColor)
{
thisLineRenderer.startColor = lineColor;
thisLineRenderer.endColor = lineColor;
thisLineRenderer.startWidth = 0f;
thisLineRenderer.endWidth = 0f;
thisLineRenderer.SetPosition(0, new Vector3(0, 0, 0));
thisLineRenderer.SetPosition(1, new Vector3(0, 0, 0));
lineRenderer.startColor = lineColor;
lineRenderer.endColor = lineColor;
lineRenderer.startWidth = 0f;
lineRenderer.endWidth = 0f;
lineRenderer.SetPosition(0, new Vector3(0, 0, 0));
lineRenderer.SetPosition(1, new Vector3(0, 0, 0));
}
public void UpdateRayInfo()
{
float focusLEdge = agentCam.pixelWidth * (1 - focusRange) / 2;
float focusREdge = agentCam.pixelWidth * (1 + focusRange) / 2;
float thisCamPixelHeight = agentCam.pixelHeight;
float camPixelHeight = agentCam.pixelHeight;
inViewEnemies.Clear();
rayTagResultOneHot.Clear();
for (int i = 0; i < halfOuterRayNum; i++) // create left outside rays; 0 ~ focusLeftEdge
{
Vector3 point = new Vector3(i * focusLEdge / (halfOuterRayNum - 1), thisCamPixelHeight / 2, 0);
Ray thisRay = agentCam.ScreenPointToRay(point);
SingleRaycastUpdate(thisRay, lineRenderers[i], rayInfoUIs[i], out rayTagResult[i], out rayDisResult[i]);
Vector3 point = new Vector3(i * focusLEdge / (halfOuterRayNum - 1), camPixelHeight / 2, 0);
Ray nowRay = agentCam.ScreenPointToRay(point);
SingleRaycastUpdate(nowRay, lineRenderers[i], rayInfoUIs[i], out rayTagResult[i], out rayDisResult[i]);
}
for (int i = 0; i < halfOuterRayNum; i++) // create right outside rays; focusRightEdge ~ MaxPixelHeight
{
Vector3 point = new Vector3(focusREdge + (i * focusLEdge / (halfOuterRayNum - 1)), thisCamPixelHeight / 2, 0);
Ray thisRay = agentCam.ScreenPointToRay(point);
SingleRaycastUpdate(thisRay, lineRenderers[halfOuterRayNum + i], rayInfoUIs[halfOuterRayNum + i], out rayTagResult[halfOuterRayNum + i], out rayDisResult[halfOuterRayNum + i]);
Vector3 point = new Vector3(focusREdge + (i * focusLEdge / (halfOuterRayNum - 1)), camPixelHeight / 2, 0);
Ray nowRay = agentCam.ScreenPointToRay(point);
SingleRaycastUpdate(nowRay, lineRenderers[halfOuterRayNum + i], rayInfoUIs[halfOuterRayNum + i], out rayTagResult[halfOuterRayNum + i], out rayDisResult[halfOuterRayNum + i]);
}
for (int i = 0; i < focusRayNum; i++) // create center focus rays; focusLeftEdge ~ focusLeftEdge
{
Vector3 point = new Vector3(focusLEdge + ((i + 1) * (focusREdge - focusLEdge) / (focusRayNum + 1)), thisCamPixelHeight / 2, 0);
Ray thisRay = agentCam.ScreenPointToRay(point);
SingleRaycastUpdate(thisRay, lineRenderers[halfOuterRayNum * 2 + i], rayInfoUIs[halfOuterRayNum * 2 + i], out rayTagResult[halfOuterRayNum * 2 + i], out rayDisResult[halfOuterRayNum * 2 + i]);
Vector3 point = new Vector3(focusLEdge + ((i + 1) * (focusREdge - focusLEdge) / (focusRayNum + 1)), camPixelHeight / 2, 0);
Ray nowRay = agentCam.ScreenPointToRay(point);
SingleRaycastUpdate(nowRay, lineRenderers[halfOuterRayNum * 2 + i], rayInfoUIs[halfOuterRayNum * 2 + i], out rayTagResult[halfOuterRayNum * 2 + i], out rayDisResult[halfOuterRayNum * 2 + i]);
}
}
}
+6 -6
View File
@@ -124,13 +124,13 @@ public class SceneBlock : MonoBehaviour
}
// get in area player number by tag
public float GetInAreaNumber(string thisTag)
public float GetInAreaNumber(string tag)
{
float inAreaNum = 0;
float dist = 0f;
float isInarea = 0f;
int index = 0;
if (thisTag == group1Tag)
if (tag == group1Tag)
{
foreach (GameObject obj in group1Objs)
{
@@ -153,7 +153,7 @@ public class SceneBlock : MonoBehaviour
index++;
}
}
else if (thisTag == group2Tag)
else if (tag == group2Tag)
{
foreach (GameObject obj in group2Objs)
{
@@ -184,10 +184,10 @@ public class SceneBlock : MonoBehaviour
}
// get this position and target's distance and is in firebase area
public (float, int) GetDistInArea(Vector3 thisPosition)
public (float, int) GetDistInArea(Vector3 position)
{
thisPosition.y = fireBasesAreaObj.transform.position.y;
float dist = Vector3.Distance(thisPosition, fireBasesAreaObj.transform.position) - (firebasesAreaDiameter / 2);
position.y = fireBasesAreaObj.transform.position.y;
float dist = Vector3.Distance(position, fireBasesAreaObj.transform.position) - (firebasesAreaDiameter / 2);
int isinarea = 0;
if (dist <= 0)
{
+27 -51
View File
@@ -7,81 +7,57 @@ public class SceneBlockContainer : MonoBehaviour
public float sceneSize = 10f;
public GameObject environmentObj;
public GameObject[] attackBlockPrefabs = new GameObject[1];
public GameObject[] goBlockPrefabs = new GameObject[1];
public GameObject[] defencePrefabs = new GameObject[1];
public GameObject hudObj;
// public GameObject[] attackBlockPrefabs = new GameObject[1];
// public GameObject[] goBlockPrefabs = new GameObject[1];
// public GameObject[] defencePrefabs = new GameObject[1];
public SceneBlocksSet scenePrefabSet;
private GameObject thisBlockObj;
public SceneBlock thisBlock;
private GameObject nowBlockObj;
public SceneBlock nowBlock;
private void Start()
{
// initialize scene prefab set
scenePrefabSet.InitializeSceneBlocksSet(hudObj);
}
// create block random
public void CreateNewBlock(Targets targetType, int blockType, Vector3 blockPosition, string tag1 = "Player", string tag2 = "Enemy")
// create appointed block at appointed position
public void CreateNewBlock(Targets targetType, int level, int blockType, Vector3 blockPosition, string tag1 = "Player", string tag2 = "Enemy")
{
// check if thisBlock is deleted
if (thisBlockObj != null)
// check if nowBlock is deleted
if (nowBlockObj != null)
{
// delete thisBlock
Debug.LogWarning("SceneBlockContainer.CreateNewBlock: Block not clear!");
// delete nowBlock
// Debug.LogWarning("SceneBlockContainer.CreateNewBlock: Block not clear!");
DestroyBlock();
}
// choose target type
switch (targetType)
{
case Targets.Go:
// goto
thisBlockObj = Instantiate(goBlockPrefabs[blockType], blockPosition + environmentObj.transform.position, Quaternion.identity, transform);
thisBlock = thisBlockObj.GetComponent<SceneBlock>();
thisBlock.group1Tag = tag1;
thisBlock.group2Tag = tag2;
sceneSize = thisBlock.blockSize;
break;
case Targets.Attack:
// attack
thisBlockObj = Instantiate(attackBlockPrefabs[blockType], blockPosition + environmentObj.transform.position, Quaternion.identity, transform);
thisBlock = thisBlockObj.GetComponent<SceneBlock>();
thisBlock.group1Tag = tag1;
thisBlock.group2Tag = tag2;
sceneSize = thisBlock.blockSize;
break;
case Targets.Defence:
// defence
thisBlockObj = Instantiate(defencePrefabs[blockType], blockPosition + environmentObj.transform.position, Quaternion.identity, transform);
thisBlock = thisBlockObj.GetComponent<SceneBlock>();
thisBlock.group1Tag = tag1;
thisBlock.group2Tag = tag2;
sceneSize = thisBlock.blockSize;
break;
default:
Debug.LogWarning("SceneBlockContainer.CreateNewBlock: targetType not found!");
break;
}
nowBlockObj = Instantiate(scenePrefabSet.GetPrefab(targetType, level, blockType), blockPosition + environmentObj.transform.position, Quaternion.identity, transform);
nowBlock = nowBlockObj.GetComponent<SceneBlock>();
nowBlock.group1Tag = tag1;
nowBlock.group2Tag = tag2;
sceneSize = nowBlock.blockSize;
}
// delete thisBlock
// delete nowBlock
public void DestroyBlock()
{
if (thisBlock != null)
if (nowBlock != null)
{
thisBlock.DestroyMe();
nowBlock.DestroyMe();
}
thisBlockObj = null;
thisBlock = null;
nowBlockObj = null;
nowBlock = null;
}
public (float, int) GetAgentTargetDistanceAndInside(Vector3 agentPosition)
{
return thisBlock.GetDistInArea(agentPosition);
return nowBlock.GetDistInArea(agentPosition);
}
public void InitializeBlock(GameObject envObj)
{
thisBlock.InitBlock(envObj);
nowBlock.InitBlock(envObj);
}
}
+116 -88
View File
@@ -55,6 +55,8 @@ public class TargetController : MonoBehaviour
private float freeProb;
private float sceneBlockSize;
private float lastDistance;
private int randBlockType = 0;
private int randLevel = 0;
public Vector3 targetPosition;
private bool firstRewardFlag = true;
private bool targetEnemySpawnFinish = false;
@@ -65,6 +67,7 @@ public class TargetController : MonoBehaviour
private CharacterController agentCharaCon;
private WorldUIController worldUICon;
private HUDController hudCon;
private MessageBoxController messageBoxCon;
// start scene datas 0=train 1=play
private int gamemode;
@@ -79,6 +82,7 @@ public class TargetController : MonoBehaviour
paramCon = parameterContainerObj.GetComponent<ParameterContainer>();
worldUICon = worldUIObj.GetComponent<WorldUIController>();
hudCon = HUDObj.GetComponent<HUDController>();
messageBoxCon = HUDObj.GetComponent<MessageBoxController>();
// get parameter from ParameterContainer
gamemode = paramCon.gameMode;
@@ -206,12 +210,12 @@ public class TargetController : MonoBehaviour
}
// move Agent to this position
public void MoveAgentTo(Vector3 thisPosition)
public void MoveAgentTo(Vector3 position)
{
// while using transform.localPosition to move character
// u should turn off character Controller or it won't work
agentCharaCon.enabled = false;
agentObj.transform.localPosition = thisPosition;
agentObj.transform.localPosition = position;
agentCharaCon.enabled = true;
}
@@ -220,41 +224,22 @@ public class TargetController : MonoBehaviour
#region Random SceneBlock Spawn Method
// initialize scene block by target type
private void RandomSpawnSceneBlock(SceneBlockContainer.Targets thisTargetType)
private void RandomSpawnSceneBlock(SceneBlockContainer.Targets targetType)
{
int randBlockType = 0;
switch (thisTargetType)
{
case SceneBlockContainer.Targets.Go:
randBlockType = Random.Range(0, sceneBlockCon.goBlockPrefabs.Length);
sceneBlockSize = sceneBlockCon.goBlockPrefabs[randBlockType].GetComponent<SceneBlock>().blockSize;
break;
randLevel = GetRandomLevelIndex(targetType);
randBlockType = Random.Range(0, sceneBlockCon.scenePrefabSet.GetBlockNumber(targetType,randLevel));
sceneBlockSize = sceneBlockCon.scenePrefabSet.GetBlockSize(targetType, randLevel, randBlockType);
case SceneBlockContainer.Targets.Attack:
randBlockType = Random.Range(0, sceneBlockCon.attackBlockPrefabs.Length);
sceneBlockSize = sceneBlockCon.attackBlockPrefabs[randBlockType].GetComponent<SceneBlock>().blockSize;
break;
case SceneBlockContainer.Targets.Defence:
// randBlockType = Random.Range(0, blockCont.defenceBlockPrefabs.Length);
// sceneBlockSize = blockCont.defenceBlockPrefabs[randBlockType].GetComponent<SceneBlock>().blockSize;
Debug.LogWarning("Defence Block Not Ready");
break;
default:
Debug.LogWarning("TargetController: InitializeSceneBlock: Wrong TargetType");
break;
}
float randX = UnityEngine.Random.Range(minEnemyAreaX + sceneBlockSize / 2 + 1f, maxEnemyAreaX - sceneBlockSize / 2 - 1f);
float randZ = UnityEngine.Random.Range(minEnemyAreaZ + sceneBlockSize / 2 + 1f, maxEnemyAreaZ - sceneBlockSize / 2 - 1f);
targetPosition = new Vector3(randX, 0, randZ);
// init scene block
sceneBlockCon.DestroyBlock();
sceneBlockCon.CreateNewBlock(thisTargetType, randBlockType, targetPosition, group1Tag, group2Tag);
sceneBlockCon.CreateNewBlock(targetType, randLevel, randBlockType, targetPosition, group1Tag, group2Tag);
enemyCon.DestroyAllEnemys();
enemyCon.RandomInitEnemysExcept(hudCon.enemyNum, targetPosition, sceneBlockSize);
sceneBlockCon.thisBlock.InitBlock(environmentObj);
sceneBlockCon.nowBlock.InitBlock(environmentObj);
}
#endregion Random SceneBlock Spawn Method
@@ -266,7 +251,7 @@ public class TargetController : MonoBehaviour
public (int, float, float) CheckOverAndRewards()
{
int endTypeInt = 0;
float thisReward = 0;
float nowReward = 0;
float endReward = 0;
float nowDistance = 0f;
switch (targetTypeInt)
@@ -274,29 +259,29 @@ public class TargetController : MonoBehaviour
case (int)SceneBlockContainer.Targets.Go:
// goto
(nowDistance, inArea) = sceneBlockCon.GetAgentTargetDistanceAndInside(agentObj.transform.position);
envUICon.UpdateTargetGauge(sceneBlockCon.thisBlock.firebasesBelong, sceneBlockCon.thisBlock.belongMaxPoint);
envUICon.UpdateTargetGauge(sceneBlockCon.nowBlock.firebasesBelong, sceneBlockCon.nowBlock.belongMaxPoint);
float areaTargetReward = GetDistanceReward(nowDistance, inArea);
//if(inArea != 0)
if (sceneBlockCon.thisBlock.firebasesBelong >= sceneBlockCon.thisBlock.belongMaxPoint)
if (sceneBlockCon.nowBlock.firebasesBelong >= sceneBlockCon.nowBlock.belongMaxPoint)
{
// win
// let the area belongs to me
thisReward = areaTargetReward;
nowReward = areaTargetReward;
endReward = paramCon.goWinReward;
//thisReward = (paramCon.inAreaReward * inArea) + getDistanceReward(nowDistance);
//nowReward = (paramCon.inAreaReward * inArea) + getDistanceReward(nowDistance);
endTypeInt = (int)EndType.Win;
}
else if (leftTime <= 0)
{
// time out lose
thisReward = areaTargetReward;
nowReward = areaTargetReward;
endReward = paramCon.loseReward;
endTypeInt = (int)EndType.Lose;
}
else
{
// keep on keeping on!
thisReward = areaTargetReward;
nowReward = areaTargetReward;
endReward = 0;
endTypeInt = (int)EndType.Running;
}
@@ -305,31 +290,31 @@ public class TargetController : MonoBehaviour
case (int)SceneBlockContainer.Targets.Attack:
// attack
(nowDistance, inArea) = sceneBlockCon.GetAgentTargetDistanceAndInside(agentObj.transform.position);
envUICon.UpdateTargetGauge(sceneBlockCon.thisBlock.firebasesBelong, sceneBlockCon.thisBlock.belongMaxPoint);
if (sceneBlockCon.thisBlock.GetInAreaNumber(group2Tag) <= 0 && targetEnemySpawnFinish)
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.
thisReward = 0;
nowReward = 0;
endReward = paramCon.attackWinReward;
//thisReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
//nowReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
endTypeInt = (int)EndType.Win;
targetEnemySpawnFinish = false;
}
else if (leftTime <= 0 && targetEnemySpawnFinish)
{
// time out lose
thisReward = 0;
nowReward = 0;
endReward = paramCon.loseReward;
//thisReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
//nowReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
endTypeInt = (int)EndType.Lose;
targetEnemySpawnFinish = false;
}
else
{
// keep on keeping on!
// thisReward = (paramCon.inAreaReward * inArea) + getDistanceReward(nowDistance);
thisReward = 0;
// nowReward = (paramCon.inAreaReward * inArea) + getDistanceReward(nowDistance);
nowReward = 0;
endReward = 0;
targetEnemySpawnFinish = true;
endTypeInt = (int)EndType.Running;
@@ -340,26 +325,26 @@ public class TargetController : MonoBehaviour
//defence
// !!! DIDN't FINISH!!!
(nowDistance, inArea) = sceneBlockCon.GetAgentTargetDistanceAndInside(agentObj.transform.position);
envUICon.UpdateTargetGauge(sceneBlockCon.thisBlock.firebasesBelong, sceneBlockCon.thisBlock.belongMaxPoint);
if (leftTime <= 0 && sceneBlockCon.thisBlock.firebasesBelong >= 0f)
envUICon.UpdateTargetGauge(sceneBlockCon.nowBlock.firebasesBelong, sceneBlockCon.nowBlock.belongMaxPoint);
if (leftTime <= 0 && sceneBlockCon.nowBlock.firebasesBelong >= 0f)
{
// win
// time over and the area still mine
thisReward = paramCon.defenceWinReward;
//thisReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
nowReward = paramCon.defenceWinReward;
//nowReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
endTypeInt = (int)EndType.Win;
}
else if (sceneBlockCon.thisBlock.firebasesBelong <= sceneBlockCon.thisBlock.belongMaxPoint)
else if (sceneBlockCon.nowBlock.firebasesBelong <= sceneBlockCon.nowBlock.belongMaxPoint)
{
// lost area lose
thisReward = paramCon.loseReward;
//thisReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
nowReward = paramCon.loseReward;
//nowReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
endTypeInt = (int)EndType.Lose;
}
else
{
// keep on keeping on!
// thisReward = (paramCon.inAreaReward * inArea) + getDistanceReward(nowDistance);
// nowReward = (paramCon.inAreaReward * inArea) + getDistanceReward(nowDistance);
endTypeInt = (int)EndType.Running;
}
break;
@@ -367,7 +352,7 @@ public class TargetController : MonoBehaviour
case (int)SceneBlockContainer.Targets.Stay:
// Stay
// endless
thisReward = 0;
nowReward = 0;
endReward = 0;
endTypeInt = (int)EndType.Running;
break;
@@ -377,23 +362,23 @@ public class TargetController : MonoBehaviour
if (enemyContainerObj.transform.childCount <= 0)
{
// win
// thisReward = paramCon.winReward + (paramCon.timeBonusPerSecReward * leftTime);
thisReward = 0;
// nowReward = paramCon.winReward + (paramCon.timeBonusPerSecReward * leftTime);
nowReward = 0;
endReward = paramCon.freeWinReward;
endTypeInt = (int)EndType.Win;
}
else if (leftTime <= 0)
{
// lose
//thisReward = paramCon.loseReward;
thisReward = 0;
//nowReward = paramCon.loseReward;
nowReward = 0;
endReward = paramCon.loseReward;
endTypeInt = (int)EndType.Lose;
}
else
{
// keep on keeping on!
thisReward = 0;
nowReward = 0;
endReward = 0;
endTypeInt = (int)EndType.Running;
}
@@ -401,7 +386,7 @@ public class TargetController : MonoBehaviour
}
envUICon.ShowResult(endTypeInt);
worldUICon.UpdateChart(targetTypeInt, endTypeInt);
return (endTypeInt, thisReward, endReward);
return (endTypeInt, nowReward, endReward);
}
// caulculate sceneReward if close to target then get great reward
@@ -413,83 +398,83 @@ public class TargetController : MonoBehaviour
(lastDistance, _) = sceneBlockCon.GetAgentTargetDistanceAndInside(agentObj.transform.position);
firstRewardFlag = false;
}
float thisSceneReward = 0f;
float nowSeneReward = 0f;
if (inarea != 0)
{
// in area
thisSceneReward = paramCon.inAreaReward;
nowSeneReward = paramCon.inAreaReward;
}
else
{
// out of area
// thisSceneReward = paramCon.distanceReward * Math.Clamp(lastDistance - nowDistance, 0, 100);
thisSceneReward = paramCon.distanceReward * (lastDistance - nowDistance);
// nowSeneReward = paramCon.distanceReward * Math.Clamp(lastDistance - nowDistance, 0, 100);
nowSeneReward = paramCon.distanceReward * (lastDistance - nowDistance);
}
lastDistance = nowDistance;
return thisSceneReward;
return nowSeneReward;
}
// calculate kill reward base on killed enemy's position
public float KillReward(Vector3 enemyPosition)
{
float thisKillReward = 0f;
float nowKillReward = 0f;
if (targetTypeInt == (int)SceneBlockContainer.Targets.Attack)
{
// attack mode
(_, int isInArea) = sceneBlockCon.thisBlock.GetDistInArea(enemyPosition);
(_, int isInArea) = sceneBlockCon.nowBlock.GetDistInArea(enemyPosition);
if (isInArea == 1)
{
// kill in area enemy
thisKillReward = paramCon.killTargetEnemyReward;
nowKillReward = paramCon.killTargetEnemyReward;
}
else
{
thisKillReward = paramCon.killNonTargetReward;
nowKillReward = paramCon.killNonTargetReward;
}
}
else if (targetTypeInt == (int)SceneBlockContainer.Targets.Free)
{
// free mode hit
thisKillReward = paramCon.killTargetEnemyReward;
nowKillReward = paramCon.killTargetEnemyReward;
}
else
{
// goto & defence
thisKillReward = paramCon.killNonTargetReward;
nowKillReward = paramCon.killNonTargetReward;
}
return thisKillReward;
return nowKillReward;
}
// calculate hit reward base on killed enemy's position and now mode
public float HitEnemyReward(Vector3 enemyPosition)
{
float thisHitReward = 0f;
float nowHitReward = 0f;
if (targetTypeInt == (int)SceneBlockContainer.Targets.Attack)
{
// attack mode
(_, int isInArea) = sceneBlockCon.thisBlock.GetDistInArea(enemyPosition);
(_, int isInArea) = sceneBlockCon.nowBlock.GetDistInArea(enemyPosition);
if (isInArea == 1)
{
// hit in area enemy
thisHitReward = paramCon.hitTargetReward;
nowHitReward = paramCon.hitTargetReward;
}
else
{
// hit not in area enemy
thisHitReward = paramCon.hitNonTargetReward;
nowHitReward = paramCon.hitNonTargetReward;
}
}
else if (targetTypeInt == (int)SceneBlockContainer.Targets.Free)
{
// free mode hit
thisHitReward = paramCon.hitTargetReward;
nowHitReward = paramCon.hitTargetReward;
}
else
{
// goto & defence
thisHitReward = paramCon.hitNonTargetReward;
nowHitReward = paramCon.hitNonTargetReward;
}
return thisHitReward;
return nowHitReward;
}
#endregion Reward function
@@ -508,10 +493,10 @@ public class TargetController : MonoBehaviour
}
// change to attack mode
public void AttackModeChange(Vector3 thisTargetPosition)
public void AttackModeChange(Vector3 targetPosition)
{
targetTypeInt = (int)SceneBlockContainer.Targets.Attack;
UpdateTargetStates(thisTargetPosition);
UpdateTargetStates(targetPosition);
envUICon.UpdateTargetType(targetTypeInt);
}
@@ -524,10 +509,10 @@ public class TargetController : MonoBehaviour
}
// change to goto mode
public void GotoModeChange(Vector3 thisTargetPosition)
public void GotoModeChange(Vector3 targetPosition)
{
targetTypeInt = (int)SceneBlockContainer.Targets.Go;
UpdateTargetStates(thisTargetPosition);
UpdateTargetStates(targetPosition);
envUICon.UpdateTargetType(targetTypeInt);
}
@@ -542,13 +527,13 @@ public class TargetController : MonoBehaviour
#endregion Play Mode Method
// get target observation states
private void UpdateTargetStates(Vector3? thisTargetPosition = null)
private void UpdateTargetStates(Vector3? targetPosition = null)
{
// targettype, x,y,z, firebasesAreaDiameter
targetState[0] = targetTypeInt;
if (thisTargetPosition != null)
if (targetPosition != null)
{
targetPosition = (Vector3)thisTargetPosition;
this.targetPosition = (Vector3)targetPosition;
}
if (targetTypeInt == (int)SceneBlockContainer.Targets.Free || targetTypeInt == (int)SceneBlockContainer.Targets.Stay)
{
@@ -558,11 +543,11 @@ public class TargetController : MonoBehaviour
}
else
{
targetState[1] = targetPosition.x;
targetState[2] = targetPosition.y;
targetState[3] = targetPosition.z;
targetState[4] = sceneBlockCon.thisBlock.firebasesAreaDiameter;
targetState[5] = sceneBlockCon.thisBlock.belongRatio;
targetState[1] = this.targetPosition.x;
targetState[2] = this.targetPosition.y;
targetState[3] = this.targetPosition.z;
targetState[4] = sceneBlockCon.nowBlock.firebasesAreaDiameter;
targetState[5] = sceneBlockCon.nowBlock.belongRatio;
}
}
@@ -578,4 +563,47 @@ public class TargetController : MonoBehaviour
return 0;
}
}
// get random Level by target type
public int GetRandomLevelIndex(SceneBlockContainer.Targets target)
{
List<float> targetProbs;
switch (target)
{
case SceneBlockContainer.Targets.Attack:
targetProbs = paramCon.attackLevelProbs;
break;
case SceneBlockContainer.Targets.Go:
targetProbs = paramCon.gotoLevelProbs;
break;
case SceneBlockContainer.Targets.Defence:
targetProbs = paramCon.defenceLevelProbs;
break;
default:
messageBoxCon.PushMessage(
new List<string> { "[ERROR]TargetController:RandomLevel", "target type error" },
new List<string> { "#800000ff" });
Debug.LogWarning("[ERROR]TargetController:RandomLevel:target type error");
return -1; // Exit early on default case
}
// sample random level depends on the target probabilities
float randomNum = UnityEngine.Random.Range(0f, 1f);
float sumProb = 0f;
for (int i = 0; i < targetProbs.Count; i++)
{
sumProb += targetProbs[i];
if (randomNum < sumProb)
{
return i;
}
}
// If no level was returned, log an error and return -1
messageBoxCon.PushMessage(
new List<string> { "[ERROR]TargetController:RandomLevel", "level index out of range" },
new List<string> { "orange" });
return -1;
}
}