using UnityEngine; public class MouseInMap : MonoBehaviour { public float targetDistanceThreshold = 6f; public float enemyDistanceThreshold = 1f; public Camera playCamera; public GameObject AgentObj; public GameObject environmentObj; public GameObject mousePreviewObj; public GameObject enemyContainerObj; public GameObject sceneBlockContainerObj; public GameObject targetControllerObj; public GameObject HUDObj; private Vector3 nowHitPosition = Vector3.zero; private Vector3 nowHitPositionRelative = Vector3.zero; private LayerMask groundMask; private int randBlockNum; private GameObject preSet; private TargetController targetCon; private MousePreview mousePreviewCon; private EnemyContainer enemyCon; private SceneBlockContainer sceneBlockCon; private MessageBoxController messageCon; private TargetUIController targetUICon; public enum MouseMode { Default, AttackSet, GotoSet, EnemySet } public MouseMode mouseMode = MouseMode.Default; private void Start() { groundMask = LayerMask.GetMask("Ground"); targetCon = targetControllerObj.GetComponent(); mousePreviewCon = mousePreviewObj.GetComponent(); enemyCon = enemyContainerObj.GetComponent(); sceneBlockCon = sceneBlockContainerObj.GetComponent(); targetUICon = HUDObj.GetComponent(); messageCon = HUDObj.GetComponent(); } 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("Agent or Enemy is too close!"); } else { // if agent or enemy is not nearby, create new block sceneBlockCon.CreateNewBlock(SceneBlockContainer.Targets.Attack, randBlockNum, nowHitPositionRelative); sceneBlockCon.InitializeBlock(environmentObj); targetCon.AttackModeChange(nowHitPositionRelative); ChangeMouseModeTo(MouseMode.Default); } break; case MouseMode.GotoSet: if (IsAgentorEnemyWithinDistance(targetDistanceThreshold)) { // if agent or enemy is nearby, do not create new block messageCon.PushMessage("Agent or Enemy is too close!"); } else { // if agent or enemy is not nearby, create new block sceneBlockCon.CreateNewBlock(SceneBlockContainer.Targets.Go, randBlockNum, nowHitPositionRelative); sceneBlockCon.InitializeBlock(environmentObj); targetCon.GotoModeChange(nowHitPositionRelative); ChangeMouseModeTo(MouseMode.Default); } break; case MouseMode.EnemySet: if (IsAgentorEnemyWithinDistance(enemyDistanceThreshold)) { messageCon.PushMessage("Agent or Enemy is too close!"); } else { enemyCon.InitEnemyAtHere(new Vector3(nowHitPositionRelative.x, 1, nowHitPositionRelative.z)); } break; default: break; } } } } public void ChangeMouseModeTo(MouseMode thisMouseMode) { mouseMode = thisMouseMode; switch (thisMouseMode) { case MouseMode.AttackSet: // random choose attack scene block type and set as preview randBlockNum = Random.Range(0, sceneBlockCon.attackBlockPrefabs.Length); preSet = sceneBlockCon.attackBlockPrefabs[randBlockNum]; mousePreviewCon.ChangePreviewTo(preSet); break; case MouseMode.GotoSet: // random choose Goto scene block type and set as preview randBlockNum = Random.Range(0, sceneBlockCon.goBlockPrefabs.Length); preSet = sceneBlockCon.goBlockPrefabs[randBlockNum]; mousePreviewCon.ChangePreviewTo(preSet); break; case MouseMode.EnemySet: preSet = enemyCon.enemyPrefab; mousePreviewCon.ChangePreviewTo(preSet,true); break; default: mousePreviewCon.DeleteAllPreviewModele(); break; } } // get mouse position on map, return an absolute Vector3 coordinate public Vector3 GetMouseOnMapPosition() { // shoot raycast from mainCamera center to mousepositon RaycastHit thisHit; Ray ray = playCamera.ScreenPointToRay(Input.mousePosition); // if raycast hit gameobject if (Physics.Raycast(ray, out thisHit, Mathf.Infinity, groundMask)) { //draw raycast Debug.DrawRay(ray.origin, ray.direction * 100, Color.red); return thisHit.point; } else { return Vector3.zero; } } 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; } }