2023-09-08 13:05:43 +00:00
|
|
|
|
using System;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using Random = UnityEngine.Random;
|
|
|
|
|
|
|
|
|
|
public class TargetController : MonoBehaviour
|
|
|
|
|
{
|
2023-06-30 09:30:12 +00:00
|
|
|
|
public GameObject environmentObj;
|
|
|
|
|
public GameObject agentObj;
|
2022-12-09 09:53:53 +00:00
|
|
|
|
public GameObject HUDObj;
|
2023-06-30 09:30:12 +00:00
|
|
|
|
public GameObject sceneBlockContainerObj;
|
|
|
|
|
public GameObject enemyContainerObj;
|
|
|
|
|
public GameObject parameterContainerObj;
|
|
|
|
|
public GameObject environmentUIObj;
|
|
|
|
|
public GameObject worldUIObj;
|
|
|
|
|
|
2022-11-28 22:54:08 +00:00
|
|
|
|
// area
|
|
|
|
|
public GameObject edgeUp;
|
2023-08-15 10:47:14 +00:00
|
|
|
|
|
2022-11-28 22:54:08 +00:00
|
|
|
|
public GameObject edgeDown;
|
|
|
|
|
public GameObject edgeLeft;
|
|
|
|
|
public GameObject edgeRight;
|
|
|
|
|
public GameObject edgeAgent_Enemy;
|
|
|
|
|
|
|
|
|
|
//group
|
|
|
|
|
public string group1Tag = "Player";
|
2023-08-15 10:47:14 +00:00
|
|
|
|
|
2022-11-28 22:54:08 +00:00
|
|
|
|
public string group2Tag = "Enemy";
|
|
|
|
|
|
|
|
|
|
public float minEnemyAreaX;
|
|
|
|
|
[System.NonSerialized] public float maxEnemyAreaX;
|
|
|
|
|
[System.NonSerialized] public float minEnemyAreaZ;
|
|
|
|
|
[System.NonSerialized] public float maxEnemyAreaZ;
|
|
|
|
|
[System.NonSerialized] public float minAgentAreaX;
|
|
|
|
|
[System.NonSerialized] public float maxAgentAreaX;
|
|
|
|
|
[System.NonSerialized] public float minAgentAreaZ;
|
|
|
|
|
[System.NonSerialized] public float maxAgentAreaZ;
|
|
|
|
|
[System.NonSerialized] public float startTime = 0f;
|
|
|
|
|
[System.NonSerialized] public float leftTime = 0f;
|
|
|
|
|
|
|
|
|
|
[SerializeField, Range(0f, 1f)] public float attackProb = 0.2f;
|
|
|
|
|
[SerializeField, Range(0f, 1f)] public float gotoProb = 0.2f;
|
|
|
|
|
[SerializeField, Range(0f, 1f)] public float defenceProb = 0.2f;
|
|
|
|
|
|
|
|
|
|
[System.NonSerialized] public int targetTypeInt;
|
2023-09-07 22:15:24 +00:00
|
|
|
|
[System.NonSerialized] public int gotoLevelNum;
|
|
|
|
|
[System.NonSerialized] public int attackLevelNum;
|
2022-12-03 08:42:51 +00:00
|
|
|
|
public float[] targetState = new float[6];
|
2023-06-30 09:30:12 +00:00
|
|
|
|
|
|
|
|
|
public enum EndType
|
|
|
|
|
{ Win, Lose, Running, Num };
|
|
|
|
|
|
2022-11-28 22:54:08 +00:00
|
|
|
|
[System.NonSerialized] public int targetNum = 0;
|
|
|
|
|
private Dictionary<int, float[]> oneHotRarget = new Dictionary<int, float[]>();
|
|
|
|
|
|
2022-12-03 23:40:23 +00:00
|
|
|
|
private int inArea = 0;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
private float freeProb;
|
2023-07-09 17:51:44 +00:00
|
|
|
|
private float sceneBlockSize;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
private float lastDistance;
|
2023-08-22 17:58:50 +00:00
|
|
|
|
private int randBlockType = 0;
|
|
|
|
|
private int randLevel = 0;
|
2022-12-05 05:56:18 +00:00
|
|
|
|
public Vector3 targetPosition;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
private bool firstRewardFlag = true;
|
2022-12-01 10:52:52 +00:00
|
|
|
|
private bool targetEnemySpawnFinish = false;
|
2023-07-28 10:44:02 +00:00
|
|
|
|
private SceneBlockContainer sceneBlockCon;
|
|
|
|
|
private EnemyContainer enemyCon;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
private EnvironmentUIControl envUICon;
|
|
|
|
|
private ParameterContainer paramCon;
|
|
|
|
|
private CharacterController agentCharaCon;
|
|
|
|
|
private WorldUIController worldUICon;
|
2022-12-09 09:53:53 +00:00
|
|
|
|
private HUDController hudCon;
|
2023-08-22 17:58:50 +00:00
|
|
|
|
private MessageBoxController messageBoxCon;
|
2023-06-30 09:30:12 +00:00
|
|
|
|
|
2023-06-29 06:18:10 +00:00
|
|
|
|
// start scene datas 0=train 1=play
|
|
|
|
|
private int gamemode;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
|
|
|
|
|
// Start is called before the first frame update
|
2023-06-30 09:30:12 +00:00
|
|
|
|
private void Start()
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
2023-07-28 10:44:02 +00:00
|
|
|
|
sceneBlockCon = sceneBlockContainerObj.GetComponent<SceneBlockContainer>();
|
2023-07-08 14:22:31 +00:00
|
|
|
|
envUICon = environmentUIObj.GetComponent<EnvironmentUIControl>();
|
2023-07-28 10:44:02 +00:00
|
|
|
|
enemyCon = enemyContainerObj.GetComponent<EnemyContainer>();
|
2023-07-08 14:22:31 +00:00
|
|
|
|
agentCharaCon = agentObj.GetComponent<CharacterController>();
|
|
|
|
|
paramCon = parameterContainerObj.GetComponent<ParameterContainer>();
|
|
|
|
|
worldUICon = worldUIObj.GetComponent<WorldUIController>();
|
|
|
|
|
hudCon = HUDObj.GetComponent<HUDController>();
|
2023-08-22 17:58:50 +00:00
|
|
|
|
messageBoxCon = HUDObj.GetComponent<MessageBoxController>();
|
2023-07-08 14:22:31 +00:00
|
|
|
|
|
|
|
|
|
// get parameter from ParameterContainer
|
|
|
|
|
gamemode = paramCon.gameMode;
|
|
|
|
|
attackProb = paramCon.attackProb;
|
|
|
|
|
gotoProb = paramCon.gotoProb;
|
|
|
|
|
defenceProb = paramCon.defenceProb;
|
|
|
|
|
|
|
|
|
|
// initialize spawn area
|
2022-11-28 22:54:08 +00:00
|
|
|
|
minEnemyAreaX = edgeLeft.transform.localPosition.x + 1.0f;
|
|
|
|
|
maxEnemyAreaX = edgeRight.transform.localPosition.x - 1.0f;
|
|
|
|
|
minEnemyAreaZ = edgeAgent_Enemy.transform.localPosition.z + 1.0f;
|
|
|
|
|
maxEnemyAreaZ = edgeUp.transform.localPosition.z - 1.0f;
|
|
|
|
|
|
|
|
|
|
minAgentAreaX = edgeLeft.transform.localPosition.x + 1.0f;
|
|
|
|
|
maxAgentAreaX = edgeRight.transform.localPosition.x - 1.0f;
|
|
|
|
|
minAgentAreaZ = edgeDown.transform.localPosition.z + 1.0f;
|
|
|
|
|
maxAgentAreaZ = edgeAgent_Enemy.transform.localPosition.z - 1.0f;
|
|
|
|
|
|
|
|
|
|
freeProb = 1 - attackProb - gotoProb - defenceProb;
|
2023-09-14 11:13:53 +00:00
|
|
|
|
targetNum = (int)Targets.Num;
|
2023-10-08 14:56:11 +00:00
|
|
|
|
gotoLevelNum = paramCon.scenePrefabSet.GetLevelNumber(Targets.Go);
|
|
|
|
|
attackLevelNum = paramCon.scenePrefabSet.GetLevelNumber(Targets.Attack);
|
2022-11-28 22:54:08 +00:00
|
|
|
|
if (freeProb < 0)
|
|
|
|
|
{
|
2023-07-28 10:44:02 +00:00
|
|
|
|
Debug.LogError("TargetController.Start: target percentage wrong");
|
2022-11-28 22:54:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// initialize a simple fake onehot encoder.
|
|
|
|
|
for (int i = 0; i < targetNum; i++)
|
|
|
|
|
{
|
|
|
|
|
float[] onehotList = new float[targetNum];
|
|
|
|
|
for (int j = 0; j < targetNum; j++)
|
|
|
|
|
{
|
|
|
|
|
onehotList[j] = 0;
|
|
|
|
|
}
|
|
|
|
|
onehotList[i] = 1;
|
|
|
|
|
oneHotRarget.Add(i, onehotList);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Update()
|
|
|
|
|
{
|
2023-06-29 06:18:10 +00:00
|
|
|
|
// if gamemode is play, then time will keep paramCon.timeLimit
|
|
|
|
|
if (gamemode == 1)
|
|
|
|
|
{
|
|
|
|
|
leftTime = paramCon.timeLimit;
|
|
|
|
|
// print out time
|
2023-07-28 10:44:02 +00:00
|
|
|
|
// Debug.Log("Playing Time: " + leftTime);
|
2023-06-29 06:18:10 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
leftTime = paramCon.timeLimit - Time.time + startTime;
|
|
|
|
|
}
|
2022-11-28 22:54:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 13:05:43 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Generates a new scene configuration by selecting a random target type and spawning related scene blocks.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// This method is responsible for creating a new scene configuration, which involves selecting a target type
|
|
|
|
|
/// (Go, Attack, Defence, or Free) based on predefined probabilities. Depending on the chosen target type,
|
|
|
|
|
/// the method spawns the associated scene blocks, updates various flags, and informs the user interface about
|
|
|
|
|
/// the selected target type.
|
|
|
|
|
/// </remarks>
|
2023-06-30 09:30:12 +00:00
|
|
|
|
public void RollNewScene()
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
|
|
|
|
startTime = Time.time;// Reset StartTime as now time
|
2022-11-29 21:39:56 +00:00
|
|
|
|
leftTime = paramCon.timeLimit - Time.time + startTime;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
float randTargetType = UnityEngine.Random.Range(0f, 1f);
|
|
|
|
|
if (randTargetType <= gotoProb)
|
|
|
|
|
{
|
|
|
|
|
// goto target spawn
|
|
|
|
|
Debug.Log("GOTO THIS TARGET!");
|
2023-09-14 11:13:53 +00:00
|
|
|
|
targetTypeInt = (int)Targets.Go;
|
|
|
|
|
RandomSpawnSceneBlock(Targets.Go);
|
2022-11-28 22:54:08 +00:00
|
|
|
|
// set startDistance
|
|
|
|
|
firstRewardFlag = true;
|
|
|
|
|
}
|
|
|
|
|
else if (randTargetType > gotoProb && randTargetType <= gotoProb + attackProb)
|
|
|
|
|
{
|
|
|
|
|
// attack target spawn
|
2023-10-08 14:56:11 +00:00
|
|
|
|
Debug.Log("ATTACK Mode Start");
|
2023-09-14 11:13:53 +00:00
|
|
|
|
targetTypeInt = (int)Targets.Attack;
|
|
|
|
|
RandomSpawnSceneBlock(Targets.Attack);
|
2022-11-28 22:54:08 +00:00
|
|
|
|
// set startDistance
|
|
|
|
|
firstRewardFlag = true;
|
2022-12-01 10:52:52 +00:00
|
|
|
|
targetEnemySpawnFinish = false;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
}
|
|
|
|
|
else if (randTargetType > gotoProb + attackProb && randTargetType <= gotoProb + attackProb + defenceProb)
|
|
|
|
|
{
|
|
|
|
|
// defence target spawn
|
2023-10-08 14:56:11 +00:00
|
|
|
|
Debug.Log("DEFENCE Mode Start");
|
2023-09-14 11:13:53 +00:00
|
|
|
|
targetTypeInt = (int)Targets.Defence;
|
|
|
|
|
RandomSpawnSceneBlock(Targets.Defence);
|
2022-11-28 22:54:08 +00:00
|
|
|
|
// set startDistance
|
|
|
|
|
firstRewardFlag = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-10-08 14:56:11 +00:00
|
|
|
|
Debug.Log("Free Mode Start");
|
2023-09-14 11:13:53 +00:00
|
|
|
|
targetTypeInt = (int)Targets.Free;
|
2023-07-28 10:44:02 +00:00
|
|
|
|
enemyCon.DestroyAllEnemys();
|
|
|
|
|
enemyCon.RandomInitEnemys(hudCon.enemyNum);
|
2023-06-30 09:30:12 +00:00
|
|
|
|
MoveAgentToSpwanArea();
|
2023-07-28 10:44:02 +00:00
|
|
|
|
sceneBlockCon.DestroyBlock();
|
2022-11-28 22:54:08 +00:00
|
|
|
|
}
|
2023-06-30 09:30:12 +00:00
|
|
|
|
UpdateTargetStates();
|
|
|
|
|
envUICon.UpdateTargetType(targetTypeInt);
|
2022-11-28 22:54:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-08-15 10:47:14 +00:00
|
|
|
|
#region Agent Move Method
|
2022-11-28 22:54:08 +00:00
|
|
|
|
|
2023-09-08 13:05:43 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Move the agent to the spawn area.
|
|
|
|
|
/// 将Agent移动到生成区域。
|
|
|
|
|
/// </summary>
|
2023-07-09 17:51:44 +00:00
|
|
|
|
private void MoveAgentToSpwanArea()
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
2022-12-07 21:24:51 +00:00
|
|
|
|
float randX = UnityEngine.Random.Range(minAgentAreaX, maxAgentAreaX); ;
|
|
|
|
|
float randZ = 0f;
|
|
|
|
|
if (paramCon.spawnAgentInAllMap)
|
|
|
|
|
{
|
|
|
|
|
// spawn agent in all around map
|
|
|
|
|
randZ = UnityEngine.Random.Range(minAgentAreaZ, maxEnemyAreaZ);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// spawn agent in only agent spawn area
|
|
|
|
|
randZ = UnityEngine.Random.Range(minAgentAreaZ, maxAgentAreaZ);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-28 22:54:08 +00:00
|
|
|
|
int Y = 1;
|
|
|
|
|
Vector3 initAgentLoc = new Vector3(randX, Y, randZ);
|
2023-06-30 09:30:12 +00:00
|
|
|
|
MoveAgentTo(initAgentLoc);
|
2022-11-28 22:54:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 13:05:43 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Move the agent to the specified position.
|
|
|
|
|
/// 将代理移动到指定位置。
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="position">要移动到的位置。</param>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// When moving the character using transform.localPosition,
|
|
|
|
|
/// must disable the character controller, or it won't work properly.
|
|
|
|
|
/// 使用 transform.localPosition 移动角色时,
|
|
|
|
|
/// 必须禁用角色控制器,否则它将无法正常工作。
|
|
|
|
|
/// </remarks>
|
2023-08-22 17:58:50 +00:00
|
|
|
|
public void MoveAgentTo(Vector3 position)
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
|
|
|
|
// while using transform.localPosition to move character
|
|
|
|
|
// u should turn off character Controller or it won't work
|
|
|
|
|
agentCharaCon.enabled = false;
|
2023-08-22 17:58:50 +00:00
|
|
|
|
agentObj.transform.localPosition = position;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
agentCharaCon.enabled = true;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-15 10:47:14 +00:00
|
|
|
|
#endregion Agent Move Method
|
|
|
|
|
|
|
|
|
|
#region Random SceneBlock Spawn Method
|
|
|
|
|
|
2023-09-08 13:05:43 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Randomly spawns a scene block based on the target type.
|
|
|
|
|
/// 根据目标类型随机生成场景块。
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="targetType">要生成的场景块的目标类型。The target type of the scene block to be generated.</param>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// This method generates a random scene block based on the target type and spawns enemies at the specified location.
|
|
|
|
|
/// 此方法根据目标类型生成一个随机场景块,并在指定位置生成敌人。
|
|
|
|
|
/// </remarks>
|
2023-09-14 11:13:53 +00:00
|
|
|
|
private void RandomSpawnSceneBlock(Targets targetType)
|
2023-08-15 10:47:14 +00:00
|
|
|
|
{
|
2023-09-09 12:04:57 +00:00
|
|
|
|
randLevel = RollRandomLevelIndex(targetType);
|
2023-10-08 14:56:11 +00:00
|
|
|
|
randBlockType = Random.Range(0, paramCon.scenePrefabSet.GetBlockNumber(randLevel,targetType));
|
|
|
|
|
sceneBlockSize = paramCon.scenePrefabSet.GetBlockSize(randLevel, randBlockType, targetType);
|
2023-08-15 10:47:14 +00:00
|
|
|
|
|
|
|
|
|
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();
|
2023-08-22 17:58:50 +00:00
|
|
|
|
sceneBlockCon.CreateNewBlock(targetType, randLevel, randBlockType, targetPosition, group1Tag, group2Tag);
|
2023-08-15 10:47:14 +00:00
|
|
|
|
enemyCon.DestroyAllEnemys();
|
|
|
|
|
enemyCon.RandomInitEnemysExcept(hudCon.enemyNum, targetPosition, sceneBlockSize);
|
2023-08-22 17:58:50 +00:00
|
|
|
|
sceneBlockCon.nowBlock.InitBlock(environmentObj);
|
2023-08-15 10:47:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion Random SceneBlock Spawn Method
|
|
|
|
|
|
|
|
|
|
#region Reward function
|
|
|
|
|
|
2023-09-08 13:05:43 +00:00
|
|
|
|
/// <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>
|
2023-06-30 09:30:12 +00:00
|
|
|
|
public (int, float, float) CheckOverAndRewards()
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
|
|
|
|
int endTypeInt = 0;
|
2023-08-22 17:58:50 +00:00
|
|
|
|
float nowReward = 0;
|
2022-12-03 08:42:51 +00:00
|
|
|
|
float endReward = 0;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
float nowDistance = 0f;
|
|
|
|
|
switch (targetTypeInt)
|
|
|
|
|
{
|
2023-09-14 11:13:53 +00:00
|
|
|
|
case (int)Targets.Go:
|
2022-11-28 22:54:08 +00:00
|
|
|
|
// goto
|
2023-07-28 10:44:02 +00:00
|
|
|
|
(nowDistance, inArea) = sceneBlockCon.GetAgentTargetDistanceAndInside(agentObj.transform.position);
|
2023-08-22 17:58:50 +00:00
|
|
|
|
envUICon.UpdateTargetGauge(sceneBlockCon.nowBlock.firebasesBelong, sceneBlockCon.nowBlock.belongMaxPoint);
|
2023-06-30 09:30:12 +00:00
|
|
|
|
float areaTargetReward = GetDistanceReward(nowDistance, inArea);
|
2023-02-15 12:06:57 +00:00
|
|
|
|
//if(inArea != 0)
|
2023-08-22 17:58:50 +00:00
|
|
|
|
if (sceneBlockCon.nowBlock.firebasesBelong >= sceneBlockCon.nowBlock.belongMaxPoint)
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
|
|
|
|
// win
|
|
|
|
|
// let the area belongs to me
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowReward = areaTargetReward;
|
2022-12-03 08:42:51 +00:00
|
|
|
|
endReward = paramCon.goWinReward;
|
2023-08-22 17:58:50 +00:00
|
|
|
|
//nowReward = (paramCon.inAreaReward * inArea) + getDistanceReward(nowDistance);
|
2022-11-28 22:54:08 +00:00
|
|
|
|
endTypeInt = (int)EndType.Win;
|
|
|
|
|
}
|
|
|
|
|
else if (leftTime <= 0)
|
|
|
|
|
{
|
|
|
|
|
// time out lose
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowReward = areaTargetReward;
|
2022-12-03 08:42:51 +00:00
|
|
|
|
endReward = paramCon.loseReward;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
endTypeInt = (int)EndType.Lose;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// keep on keeping on!
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowReward = areaTargetReward;
|
2022-12-03 08:42:51 +00:00
|
|
|
|
endReward = 0;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
endTypeInt = (int)EndType.Running;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2023-06-30 09:30:12 +00:00
|
|
|
|
|
2023-09-14 11:13:53 +00:00
|
|
|
|
case (int)Targets.Attack:
|
2022-11-28 22:54:08 +00:00
|
|
|
|
// attack
|
2023-07-28 10:44:02 +00:00
|
|
|
|
(nowDistance, inArea) = sceneBlockCon.GetAgentTargetDistanceAndInside(agentObj.transform.position);
|
2023-08-22 17:58:50 +00:00
|
|
|
|
envUICon.UpdateTargetGauge(sceneBlockCon.nowBlock.firebasesBelong, sceneBlockCon.nowBlock.belongMaxPoint);
|
|
|
|
|
if (sceneBlockCon.nowBlock.GetInAreaNumber(group2Tag) <= 0 && targetEnemySpawnFinish)
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
|
|
|
|
// win
|
|
|
|
|
// let the area belongs to me and kill every enmy in this area.
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowReward = 0;
|
2022-12-03 08:42:51 +00:00
|
|
|
|
endReward = paramCon.attackWinReward;
|
2023-08-22 17:58:50 +00:00
|
|
|
|
//nowReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
|
2022-11-28 22:54:08 +00:00
|
|
|
|
endTypeInt = (int)EndType.Win;
|
2023-06-29 06:18:10 +00:00
|
|
|
|
targetEnemySpawnFinish = false;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
}
|
2022-12-01 10:52:52 +00:00
|
|
|
|
else if (leftTime <= 0 && targetEnemySpawnFinish)
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
|
|
|
|
// time out lose
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowReward = 0;
|
2022-12-03 08:42:51 +00:00
|
|
|
|
endReward = paramCon.loseReward;
|
2023-08-22 17:58:50 +00:00
|
|
|
|
//nowReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
|
2022-11-28 22:54:08 +00:00
|
|
|
|
endTypeInt = (int)EndType.Lose;
|
2023-06-29 06:18:10 +00:00
|
|
|
|
targetEnemySpawnFinish = false;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// keep on keeping on!
|
2023-08-22 17:58:50 +00:00
|
|
|
|
// nowReward = (paramCon.inAreaReward * inArea) + getDistanceReward(nowDistance);
|
|
|
|
|
nowReward = 0;
|
2022-12-03 08:42:51 +00:00
|
|
|
|
endReward = 0;
|
2022-12-01 10:52:52 +00:00
|
|
|
|
targetEnemySpawnFinish = true;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
endTypeInt = (int)EndType.Running;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2023-06-30 09:30:12 +00:00
|
|
|
|
|
2023-09-14 11:13:53 +00:00
|
|
|
|
case (int)Targets.Defence:
|
2022-11-28 22:54:08 +00:00
|
|
|
|
//defence
|
2022-12-03 08:42:51 +00:00
|
|
|
|
// !!! DIDN't FINISH!!!
|
2023-07-28 10:44:02 +00:00
|
|
|
|
(nowDistance, inArea) = sceneBlockCon.GetAgentTargetDistanceAndInside(agentObj.transform.position);
|
2023-08-22 17:58:50 +00:00
|
|
|
|
envUICon.UpdateTargetGauge(sceneBlockCon.nowBlock.firebasesBelong, sceneBlockCon.nowBlock.belongMaxPoint);
|
|
|
|
|
if (leftTime <= 0 && sceneBlockCon.nowBlock.firebasesBelong >= 0f)
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
|
|
|
|
// win
|
|
|
|
|
// time over and the area still mine
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowReward = paramCon.defenceWinReward;
|
|
|
|
|
//nowReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
|
2022-11-28 22:54:08 +00:00
|
|
|
|
endTypeInt = (int)EndType.Win;
|
|
|
|
|
}
|
2023-08-22 17:58:50 +00:00
|
|
|
|
else if (sceneBlockCon.nowBlock.firebasesBelong <= sceneBlockCon.nowBlock.belongMaxPoint)
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
|
|
|
|
// lost area lose
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowReward = paramCon.loseReward;
|
|
|
|
|
//nowReward = (paramCon.inAreaReward * inArea) + getSceneReward(nowDistance);
|
2022-11-28 22:54:08 +00:00
|
|
|
|
endTypeInt = (int)EndType.Lose;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// keep on keeping on!
|
2023-08-22 17:58:50 +00:00
|
|
|
|
// nowReward = (paramCon.inAreaReward * inArea) + getDistanceReward(nowDistance);
|
2022-11-28 22:54:08 +00:00
|
|
|
|
endTypeInt = (int)EndType.Running;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2023-06-30 09:30:12 +00:00
|
|
|
|
|
2023-09-14 11:13:53 +00:00
|
|
|
|
case (int)Targets.Stay:
|
2023-06-29 06:18:10 +00:00
|
|
|
|
// Stay
|
|
|
|
|
// endless
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowReward = 0;
|
2023-06-29 06:18:10 +00:00
|
|
|
|
endReward = 0;
|
|
|
|
|
endTypeInt = (int)EndType.Running;
|
|
|
|
|
break;
|
2023-06-30 09:30:12 +00:00
|
|
|
|
|
2022-11-28 22:54:08 +00:00
|
|
|
|
default:
|
|
|
|
|
//free kill
|
2023-06-30 09:30:12 +00:00
|
|
|
|
if (enemyContainerObj.transform.childCount <= 0)
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
|
|
|
|
// win
|
2023-08-22 17:58:50 +00:00
|
|
|
|
// nowReward = paramCon.winReward + (paramCon.timeBonusPerSecReward * leftTime);
|
|
|
|
|
nowReward = 0;
|
2022-12-03 08:42:51 +00:00
|
|
|
|
endReward = paramCon.freeWinReward;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
endTypeInt = (int)EndType.Win;
|
|
|
|
|
}
|
2023-06-29 06:18:10 +00:00
|
|
|
|
else if (leftTime <= 0)
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
|
|
|
|
// lose
|
2023-08-22 17:58:50 +00:00
|
|
|
|
//nowReward = paramCon.loseReward;
|
|
|
|
|
nowReward = 0;
|
2022-12-03 08:42:51 +00:00
|
|
|
|
endReward = paramCon.loseReward;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
endTypeInt = (int)EndType.Lose;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// keep on keeping on!
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowReward = 0;
|
2022-12-03 08:42:51 +00:00
|
|
|
|
endReward = 0;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
endTypeInt = (int)EndType.Running;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2023-06-30 09:30:12 +00:00
|
|
|
|
envUICon.ShowResult(endTypeInt);
|
|
|
|
|
worldUICon.UpdateChart(targetTypeInt, endTypeInt);
|
2023-08-22 17:58:50 +00:00
|
|
|
|
return (endTypeInt, nowReward, endReward);
|
2022-11-28 22:54:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 13:05:43 +00:00
|
|
|
|
/// <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>
|
2023-07-09 17:51:44 +00:00
|
|
|
|
private float GetDistanceReward(float nowDistance, int inarea)
|
2022-12-01 10:52:52 +00:00
|
|
|
|
{
|
|
|
|
|
if (firstRewardFlag)
|
|
|
|
|
{
|
2022-12-07 21:24:51 +00:00
|
|
|
|
// first distance record
|
2023-07-28 10:44:02 +00:00
|
|
|
|
(lastDistance, _) = sceneBlockCon.GetAgentTargetDistanceAndInside(agentObj.transform.position);
|
2022-12-01 10:52:52 +00:00
|
|
|
|
firstRewardFlag = false;
|
|
|
|
|
}
|
2023-08-22 17:58:50 +00:00
|
|
|
|
float nowSeneReward = 0f;
|
2022-12-03 23:40:23 +00:00
|
|
|
|
if (inarea != 0)
|
|
|
|
|
{
|
2023-02-15 12:06:57 +00:00
|
|
|
|
// in area
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowSeneReward = paramCon.inAreaReward;
|
2022-12-03 23:40:23 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-03-07 08:29:47 +00:00
|
|
|
|
// out of area
|
2023-08-22 17:58:50 +00:00
|
|
|
|
// nowSeneReward = paramCon.distanceReward * Math.Clamp(lastDistance - nowDistance, 0, 100);
|
|
|
|
|
nowSeneReward = paramCon.distanceReward * (lastDistance - nowDistance);
|
2022-12-03 23:40:23 +00:00
|
|
|
|
}
|
2022-12-01 10:52:52 +00:00
|
|
|
|
lastDistance = nowDistance;
|
2023-08-22 17:58:50 +00:00
|
|
|
|
return nowSeneReward;
|
2022-12-01 10:52:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 13:05:43 +00:00
|
|
|
|
/// <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>
|
2023-06-30 09:30:12 +00:00
|
|
|
|
public float KillReward(Vector3 enemyPosition)
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
2023-08-22 17:58:50 +00:00
|
|
|
|
float nowKillReward = 0f;
|
2023-09-14 11:13:53 +00:00
|
|
|
|
if (targetTypeInt == (int)Targets.Attack)
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
2022-11-29 21:39:56 +00:00
|
|
|
|
// attack mode
|
2023-08-22 17:58:50 +00:00
|
|
|
|
(_, int isInArea) = sceneBlockCon.nowBlock.GetDistInArea(enemyPosition);
|
2022-11-28 22:54:08 +00:00
|
|
|
|
if (isInArea == 1)
|
|
|
|
|
{
|
2022-11-29 21:39:56 +00:00
|
|
|
|
// kill in area enemy
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowKillReward = paramCon.killTargetEnemyReward;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowKillReward = paramCon.killNonTargetReward;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-14 11:13:53 +00:00
|
|
|
|
else if (targetTypeInt == (int)Targets.Free)
|
2022-11-28 22:54:08 +00:00
|
|
|
|
{
|
2022-12-01 10:52:52 +00:00
|
|
|
|
// free mode hit
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowKillReward = paramCon.killTargetEnemyReward;
|
2022-12-01 10:52:52 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2022-11-29 21:39:56 +00:00
|
|
|
|
{
|
|
|
|
|
// goto & defence
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowKillReward = paramCon.killNonTargetReward;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
}
|
2023-08-22 17:58:50 +00:00
|
|
|
|
return nowKillReward;
|
2022-11-28 22:54:08 +00:00
|
|
|
|
}
|
2022-11-29 21:39:56 +00:00
|
|
|
|
|
2023-09-08 13:05:43 +00:00
|
|
|
|
/// <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>
|
2023-06-30 09:30:12 +00:00
|
|
|
|
public float HitEnemyReward(Vector3 enemyPosition)
|
2022-11-29 21:39:56 +00:00
|
|
|
|
{
|
2023-08-22 17:58:50 +00:00
|
|
|
|
float nowHitReward = 0f;
|
2023-09-14 11:13:53 +00:00
|
|
|
|
if (targetTypeInt == (int)Targets.Attack)
|
2022-11-29 21:39:56 +00:00
|
|
|
|
{
|
|
|
|
|
// attack mode
|
2023-08-22 17:58:50 +00:00
|
|
|
|
(_, int isInArea) = sceneBlockCon.nowBlock.GetDistInArea(enemyPosition);
|
2022-11-29 21:39:56 +00:00
|
|
|
|
if (isInArea == 1)
|
|
|
|
|
{
|
|
|
|
|
// hit in area enemy
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowHitReward = paramCon.hitTargetReward;
|
2022-11-29 21:39:56 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// hit not in area enemy
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowHitReward = paramCon.hitNonTargetReward;
|
2022-11-29 21:39:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-14 11:13:53 +00:00
|
|
|
|
else if (targetTypeInt == (int)Targets.Free)
|
2022-11-29 21:39:56 +00:00
|
|
|
|
{
|
|
|
|
|
// free mode hit
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowHitReward = paramCon.hitTargetReward;
|
2022-11-29 21:39:56 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// goto & defence
|
2023-08-22 17:58:50 +00:00
|
|
|
|
nowHitReward = paramCon.hitNonTargetReward;
|
2022-11-29 21:39:56 +00:00
|
|
|
|
}
|
2023-08-22 17:58:50 +00:00
|
|
|
|
return nowHitReward;
|
2022-11-29 21:39:56 +00:00
|
|
|
|
}
|
2022-12-03 23:40:23 +00:00
|
|
|
|
|
2023-08-15 10:47:14 +00:00
|
|
|
|
#endregion Reward function
|
|
|
|
|
|
|
|
|
|
#region Play Mode Method
|
2023-06-29 06:18:10 +00:00
|
|
|
|
|
2023-09-08 13:05:43 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes the game in play mode.
|
|
|
|
|
/// 初始化游戏playMode。
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// This method is used to initialize the game in play mode,
|
|
|
|
|
/// including setting the target type, updating target states,
|
|
|
|
|
/// updating UI display, moving the agent to the spawn area,
|
|
|
|
|
/// destroying all enemies, and scene blocks.
|
|
|
|
|
/// 该方法用于初始化游戏播放模式,包括设置目标类型、更新目标状态、更新UI显示、
|
|
|
|
|
/// 将代理移动到生成区域、销毁所有敌人和场景块。
|
|
|
|
|
/// </remarks>
|
2023-06-30 09:30:12 +00:00
|
|
|
|
public void PlayInitialize()
|
2023-06-29 06:18:10 +00:00
|
|
|
|
{
|
2023-09-14 11:13:53 +00:00
|
|
|
|
targetTypeInt = (int)Targets.Stay;
|
2023-07-28 10:44:02 +00:00
|
|
|
|
UpdateTargetStates();
|
2023-06-30 09:30:12 +00:00
|
|
|
|
envUICon.UpdateTargetType(targetTypeInt);
|
|
|
|
|
MoveAgentToSpwanArea();
|
2023-07-28 10:44:02 +00:00
|
|
|
|
enemyCon.DestroyAllEnemys();
|
|
|
|
|
sceneBlockCon.DestroyBlock();
|
2023-06-29 06:18:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// change to attack mode
|
2023-08-22 17:58:50 +00:00
|
|
|
|
public void AttackModeChange(Vector3 targetPosition)
|
2023-06-29 06:18:10 +00:00
|
|
|
|
{
|
2023-09-14 11:13:53 +00:00
|
|
|
|
targetTypeInt = (int)Targets.Attack;
|
2023-08-22 17:58:50 +00:00
|
|
|
|
UpdateTargetStates(targetPosition);
|
2023-06-30 09:30:12 +00:00
|
|
|
|
envUICon.UpdateTargetType(targetTypeInt);
|
2023-06-29 06:18:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// change to free mode
|
2023-06-30 09:30:12 +00:00
|
|
|
|
public void FreeModeChange()
|
2023-06-29 06:18:10 +00:00
|
|
|
|
{
|
2023-09-14 11:13:53 +00:00
|
|
|
|
targetTypeInt = (int)Targets.Free;
|
2023-07-28 10:44:02 +00:00
|
|
|
|
UpdateTargetStates();
|
2023-06-30 09:30:12 +00:00
|
|
|
|
envUICon.UpdateTargetType(targetTypeInt);
|
2023-06-29 06:18:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// change to goto mode
|
2023-08-22 17:58:50 +00:00
|
|
|
|
public void GotoModeChange(Vector3 targetPosition)
|
2023-06-29 06:18:10 +00:00
|
|
|
|
{
|
2023-09-14 11:13:53 +00:00
|
|
|
|
targetTypeInt = (int)Targets.Go;
|
2023-08-22 17:58:50 +00:00
|
|
|
|
UpdateTargetStates(targetPosition);
|
2023-06-30 09:30:12 +00:00
|
|
|
|
envUICon.UpdateTargetType(targetTypeInt);
|
2023-06-29 06:18:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// change to stay mode
|
2023-06-30 09:30:12 +00:00
|
|
|
|
public void StayModeChange()
|
2023-06-29 06:18:10 +00:00
|
|
|
|
{
|
2023-09-14 11:13:53 +00:00
|
|
|
|
targetTypeInt = (int)Targets.Stay;
|
2023-07-28 10:44:02 +00:00
|
|
|
|
UpdateTargetStates();
|
2023-06-30 09:30:12 +00:00
|
|
|
|
envUICon.UpdateTargetType(targetTypeInt);
|
2023-06-29 06:18:10 +00:00
|
|
|
|
}
|
2023-08-15 10:47:14 +00:00
|
|
|
|
|
|
|
|
|
#endregion Play Mode Method
|
|
|
|
|
|
2023-09-08 13:05:43 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the target observation states.
|
|
|
|
|
/// 获取目标观测状态。
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="targetPosition">The target position (optional).</param>
|
2023-08-22 17:58:50 +00:00
|
|
|
|
private void UpdateTargetStates(Vector3? targetPosition = null)
|
2023-08-15 10:47:14 +00:00
|
|
|
|
{
|
|
|
|
|
// targettype, x,y,z, firebasesAreaDiameter
|
|
|
|
|
targetState[0] = targetTypeInt;
|
2023-08-22 17:58:50 +00:00
|
|
|
|
if (targetPosition != null)
|
2023-08-15 10:47:14 +00:00
|
|
|
|
{
|
2023-08-22 17:58:50 +00:00
|
|
|
|
this.targetPosition = (Vector3)targetPosition;
|
2023-08-15 10:47:14 +00:00
|
|
|
|
}
|
2023-09-14 11:13:53 +00:00
|
|
|
|
if (targetTypeInt == (int)Targets.Free || targetTypeInt == (int)Targets.Stay)
|
2023-08-15 10:47:14 +00:00
|
|
|
|
{
|
|
|
|
|
for (int i = 1; i < targetState.Length; i++)
|
|
|
|
|
// set target position state to 0
|
|
|
|
|
targetState[i] = 0f;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-08-22 17:58:50 +00:00
|
|
|
|
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;
|
2023-08-15 10:47:14 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-08 13:05:43 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the in-area state.
|
|
|
|
|
/// 获取是否在区域内的State
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>The in-area state.</returns>
|
2023-08-15 10:47:14 +00:00
|
|
|
|
public int GetInAreaState()
|
|
|
|
|
{
|
2023-09-14 11:13:53 +00:00
|
|
|
|
if (targetTypeInt == (int)Targets.Go)
|
2023-08-15 10:47:14 +00:00
|
|
|
|
{
|
|
|
|
|
return inArea;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-08-22 17:58:50 +00:00
|
|
|
|
|
2023-09-08 13:05:43 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets a random level index based on the target type.
|
|
|
|
|
/// 根据目标类型获取随机关卡索引。
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="target">The target type.</param>
|
|
|
|
|
/// <returns>A random level index.</returns>
|
2023-09-14 11:13:53 +00:00
|
|
|
|
public int RollRandomLevelIndex(Targets target)
|
2023-08-22 17:58:50 +00:00
|
|
|
|
{
|
|
|
|
|
List<float> targetProbs;
|
|
|
|
|
|
|
|
|
|
switch (target)
|
|
|
|
|
{
|
2023-09-14 11:13:53 +00:00
|
|
|
|
case Targets.Attack:
|
2023-08-22 17:58:50 +00:00
|
|
|
|
targetProbs = paramCon.attackLevelProbs;
|
|
|
|
|
break;
|
2023-09-14 11:13:53 +00:00
|
|
|
|
case Targets.Go:
|
2023-08-22 17:58:50 +00:00
|
|
|
|
targetProbs = paramCon.gotoLevelProbs;
|
|
|
|
|
break;
|
2023-09-14 11:13:53 +00:00
|
|
|
|
case Targets.Defence:
|
2023-08-22 17:58:50 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
2023-06-30 09:30:12 +00:00
|
|
|
|
}
|