using System.Collections; using System.Collections.Generic; using UnityEngine; using Mapbox.Unity.Map; namespace Mapbox.Examples { public class AstronautMouseController : MonoBehaviour { [Header("Character")] [SerializeField] GameObject character; [SerializeField] float characterSpeed; [SerializeField] Animator characterAnimator; [Header("References")] [SerializeField] AstronautDirections directions; [SerializeField] Transform startPoint; [SerializeField] Transform endPoint; [SerializeField] AbstractMap map; [SerializeField] GameObject rayPlane; [SerializeField] Transform _movementEndPoint; [SerializeField] LayerMask layerMask; Ray ray; RaycastHit hit; LayerMask raycastPlane; float clicktime; bool moving; bool characterDisabled; void Start() { characterAnimator = GetComponentInChildren(); //if (!Application.isEditor) //{ // this.enabled = false; // return; //} } void Update() { if (characterDisabled) return; CamControl(); bool click = false; if (Input.GetMouseButtonDown(0)) { clicktime = Time.time; } if (Input.GetMouseButtonUp(0)) { if (Time.time - clicktime < 0.15f) { click = true; } } if (click) { ray = cam.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hit, Mathf.Infinity, layerMask)) { startPoint.position = transform.localPosition; endPoint.position = hit.point; MovementEndpointControl(hit.point, true); directions.Query(GetPositions, startPoint, endPoint, map); } } } #region Character : Movement List futurePositions; bool interruption; void GetPositions(List vecs) { futurePositions = vecs; if (futurePositions != null && moving) { interruption = true; } if (!moving) { interruption = false; MoveToNextPlace(); } } Vector3 nextPos; void MoveToNextPlace() { if (futurePositions.Count > 0) { nextPos = futurePositions[0]; futurePositions.Remove(nextPos); moving = true; characterAnimator.SetBool("IsWalking", true); StartCoroutine(MoveTo()); } else if (futurePositions.Count <= 0) { moving = false; characterAnimator.SetBool("IsWalking", false); } } Vector3 prevPos; IEnumerator MoveTo() { prevPos = transform.localPosition; float time = CalculateTime(); float t = 0; StartCoroutine(LookAtNextPos()); while (t < 1 && !interruption) { t += Time.deltaTime / time; transform.localPosition = Vector3.Lerp(prevPos, nextPos, t); yield return null; } interruption = false; MoveToNextPlace(); } float CalculateTime() { float timeToMove = 0; timeToMove = Vector3.Distance(prevPos, nextPos) / characterSpeed; return timeToMove; } #endregion #region Character : Rotation IEnumerator LookAtNextPos() { Quaternion neededRotation = Quaternion.LookRotation(nextPos - character.transform.position); Quaternion thisRotation = character.transform.localRotation; float t = 0; while (t < 1.0f) { t += Time.deltaTime / 0.25f; var rotationValue = Quaternion.Slerp(thisRotation, neededRotation, t); character.transform.rotation = Quaternion.Euler(0, rotationValue.eulerAngles.y, 0); yield return null; } } #endregion #region CameraControl [Header("CameraSettings")] [SerializeField] Camera cam; Vector3 previousPos = Vector3.zero; Vector3 deltaPos = Vector3.zero; void CamControl() { deltaPos = transform.position - previousPos; deltaPos.y = 0; cam.transform.position = Vector3.Lerp(cam.transform.position, cam.transform.position + deltaPos, Time.time); previousPos = transform.position; } #endregion #region Utility public void DisableCharacter() { characterDisabled = true; moving = false; StopAllCoroutines(); character.SetActive(false); } public void EnableCharacter() { characterDisabled = false; character.SetActive(true); } public void LayerChangeOn() { Debug.Log("OPEN"); } public void LayerChangeOff() { Debug.Log("CLOSE"); } void MovementEndpointControl(Vector3 pos, bool active) { _movementEndPoint.position = new Vector3(pos.x, 0.2f, pos.z); _movementEndPoint.gameObject.SetActive(active); } #endregion } }