Aimbot-ParallelEnv/Assets/Script/PlayMode/MouseInMap.cs

252 lines
10 KiB
C#

using System.Collections.Generic;
using UnityEngine;
public class MouseInMap : MonoBehaviour
{
public float targetDistanceThreshold = 6f;
public float enemyDistanceThreshold = 1f;
[SerializeField]
private Camera playCamera;
[SerializeField]
private GameObject AgentObj;
[SerializeField]
private GameObject environmentObj;
[SerializeField]
private GameObject mousePreviewObj;
[SerializeField]
private GameObject enemyContainerObj;
[SerializeField]
private GameObject sceneBlockContainerObj;
[SerializeField]
private GameObject targetControllerObj;
[SerializeField]
private GameObject HUDObj;
private Vector3 nowHitPosition = Vector3.zero;
private Vector3 nowHitPositionRelative = Vector3.zero;
private LayerMask groundMask;
private int blockNum;
private CommonParameterContainer commonParamCon;
private GameObject previewModel;
private TargetController targetCon;
private MousePreview mousePreviewCon;
private EnemyContainer enemyCon;
private SceneBlockContainer sceneBlockCon;
private MessageBoxController messageCon;
private TargetUIController targetUICon;
private const string ErrorMessageColor = "#800000ff";
private const string LevelTooHighError = "[Error]MouseInMap:ChangeBlockLevelTo:";
private const string AttackLevelErrorMsg = "Attack Level is too high!";
private const string GotoLevelErrorMsg = "Goto Level is too high!";
public enum MouseMode
{
Default,
AttackSet,
GotoSet,
EnemySet
}
public MouseMode mouseMode = MouseMode.Default;
public int blockLevel = 0;
private void Start()
{
commonParamCon = CommonParameterContainer.Instance;
groundMask = LayerMask.GetMask("Ground");
targetCon = targetControllerObj.GetComponent<TargetController>();
mousePreviewCon = mousePreviewObj.GetComponent<MousePreview>();
enemyCon = enemyContainerObj.GetComponent<EnemyContainer>();
sceneBlockCon = sceneBlockContainerObj.GetComponent<SceneBlockContainer>();
targetUICon = HUDObj.GetComponent<TargetUIController>();
messageCon = HUDObj.GetComponent<MessageBoxController>();
}
private void Update()
{
nowHitPosition = GetMouseOnMapPosition();
nowHitPositionRelative = nowHitPosition - environmentObj.transform.position;
// if mouse position in area, update mouseInMapPosition as nowHitPosition
if (nowHitPositionRelative.x < targetCon.maxAgentAreaX && nowHitPositionRelative.x > targetCon.minAgentAreaX && nowHitPositionRelative.z < targetCon.maxEnemyAreaZ && nowHitPositionRelative.z > targetCon.minAgentAreaZ)
{
mousePreviewCon.UpdatePreviewPosition(nowHitPosition);
// Mouse button R pressed
if (Input.GetMouseButtonDown(1))
{
switch (mouseMode)
{
case MouseMode.AttackSet:
if (IsAgentorEnemyWithinDistance(targetDistanceThreshold))
{
// if agent or enemy is nearby, do not create new block
messageCon.PushMessage(new List<string> { "Agent or Enemy is too close!" },
new List<string> { messageCon.errorColor });
}
else
{
// if agent or enemy is not nearby, create new block
sceneBlockCon.CreateNewBlock(Targets.Attack, blockLevel, blockNum, nowHitPositionRelative);
sceneBlockCon.InitializeBlock(environmentObj);
targetCon.AttackModeChange(nowHitPositionRelative);
ChangeMouseMode(MouseMode.Default);
}
break;
case MouseMode.GotoSet:
if (IsAgentorEnemyWithinDistance(targetDistanceThreshold))
{
// if agent or enemy is nearby, do not create new block
messageCon.PushMessage(new List<string> { "Agent or Enemy is too close!" },
new List<string> { messageCon.errorColor });
}
else
{
// if agent or enemy is not nearby, create new block
sceneBlockCon.CreateNewBlock(Targets.Go, blockLevel, blockNum, nowHitPositionRelative);
sceneBlockCon.InitializeBlock(environmentObj);
targetCon.GotoModeChange(nowHitPositionRelative);
ChangeMouseMode(MouseMode.Default);
}
break;
case MouseMode.EnemySet:
if (IsAgentorEnemyWithinDistance(enemyDistanceThreshold))
{
messageCon.PushMessage(new List<string> { "Agent or Enemy is too close!" },
new List<string> { messageCon.errorColor });
}
else
{
enemyCon.InitEnemyAtHere(new Vector3(nowHitPositionRelative.x, 1, nowHitPositionRelative.z));
}
break;
default:
break;
}
}
}
}
// change mouse mode, level and PreviewModel
public void ChangeMouseMode(MouseMode mouseMode, int level = -1, int blockNum = -1)
{
this.mouseMode = mouseMode;
Targets nowTargetType;
switch (mouseMode)
{
case MouseMode.AttackSet:
case MouseMode.GotoSet:
// set target type
nowTargetType = GetTargetTypeByMouseMode(mouseMode);
// set blockLevel or send error message
if (level < 0)
{
// while blockLevel is not set, send error message
messageCon.PushMessage(new List<string> { "[ERROR]MouseInMap:ChangeMouseMode:", "Level not set!", "mouseMode=", mouseMode.ToString() },
new List<string> { messageCon.errorColor });
blockLevel = commonParamCon.scenePrefabSet.GetLevelNumber(nowTargetType);
}
else
{
// while blockLevel is set
blockLevel = level;
}
blockLevel = level;
// set blockNum or random choose attack scene block type
if (blockNum < 0)
{
// while blockNum is not set, random choose block type
this.blockNum = Random.Range(0, commonParamCon.scenePrefabSet.GetBlockNumber(blockLevel, nowTargetType));
}
else
{
// while blockNum is set
this.blockNum = blockNum;
}
// set previewModel
previewModel = commonParamCon.scenePrefabSet.GetPrefab(blockLevel, this.blockNum, nowTargetType);
mousePreviewCon.ChangePreviewTo(previewModel);
break;
case MouseMode.EnemySet:
// set enemy as preview
previewModel = enemyCon.enemyPrefab;
mousePreviewCon.ChangePreviewTo(previewModel, true);
break;
default:
// default mode, delete all preview model
mousePreviewCon.DeleteAllPreviewModele();
break;
}
}
// get mouse position on map, return an absolute Vector3 coordinate
public Vector3 GetMouseOnMapPosition()
{
// shoot raycast from mainCamera center to mousepositon
RaycastHit nowHit;
Ray ray = playCamera.ScreenPointToRay(Input.mousePosition);
// if raycast hit gameobject
if (Physics.Raycast(ray, out nowHit, Mathf.Infinity, groundMask))
{
//draw raycast
Debug.DrawRay(ray.origin, ray.direction * 100, Color.red);
return nowHit.point;
}
else
{
return Vector3.zero;
}
}
// check if agent or enemy is too close to nowHitPosition
private bool IsAgentorEnemyWithinDistance(float distance)
{
// check all child object in enemyContainerObj
// if any child object is near by nowHitPosition in 10, return true
Vector3 playerPosition = Vector3.zero;
for (int i = 0; i < enemyContainerObj.transform.childCount; i++)
{
//set enemy Position's y as 0
playerPosition = enemyContainerObj.transform.GetChild(i).position;
playerPosition.y = 0;
// check if enemy near by nowHitPositionRelative in distance, return true
if (Vector3.Distance(playerPosition, nowHitPosition) < distance)
{
return true;
}
}
// set agentObj position's y as 0
playerPosition = AgentObj.transform.position;
playerPosition.y = 0;
// check if agentObj near by nowHitPositionRelative in distance, return true
if (Vector3.Distance(playerPosition, nowHitPosition) < distance)
{
return true;
}
// if no enemy or agent near by, return false
return false;
}
// change to TargetType from MouseMode
private Targets GetTargetTypeByMouseMode(MouseMode mode)
{
switch (mode)
{
case MouseMode.AttackSet:
return Targets.Attack;
case MouseMode.GotoSet:
return Targets.Go;
default:
messageCon.PushMessage(new List<string> { "[Error]MouseInMap:GetTargetTypeByMouseMode:", "Mouse Mode not found!", "mode=", mode.ToString() },
new List<string> { messageCon.errorColor });
return Targets.Num;
}
}
}