You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

281 lines
9.8 KiB

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using UnityEngine.SceneManagement;
  6. public class Character : MonoBehaviour
  7. {
  8. public string nextScene;
  9. Animator characterAnimator;
  10. #region Inspector Fields
  11. [SerializeField]
  12. private Inventory startingInventory;
  13. [SerializeField]
  14. [Tooltip("Will move to this block at start, else will try and find a block below")]
  15. private Block CurrentBlock;
  16. [SerializeField]
  17. [Tooltip("Layers to ignore when checking for blocks")]
  18. private LayerMask Ignore;
  19. [Tooltip("Current Inventory of the player")]
  20. public Inventory Inventory;
  21. #endregion Inspector Fields
  22. #region Unity Functions
  23. private void Awake()
  24. {
  25. if (Inventory != null || startingInventory != null)
  26. Inventory.Clone(startingInventory);
  27. //If no starting block find one below it
  28. if (CurrentBlock == null)
  29. Block.isBlockAtPosition(transform.position + Vector3.down / 2, 1, ~Ignore, out CurrentBlock);
  30. //move to starting block
  31. transform.position = CurrentBlock.VisualPosition;
  32. characterAnimator = GetComponentInChildren<Animator>();
  33. characterAnimator.Play("Idle");
  34. }
  35. #endregion Unity Functions
  36. #region Class Implementation
  37. public Vector3 yValue(float time, float heightMultiplier)
  38. {
  39. float y = Mathf.Sin((Mathf.PI*time)) * heightMultiplier;
  40. return new Vector3(0, y, 0);
  41. }
  42. IEnumerator JumpCoroutine(Block Target, Transform Current, float time, float heightMax)
  43. {
  44. float elapsedTime = 0;
  45. Vector3 startPosition = Current.position;
  46. time *= 0.8f;
  47. while (elapsedTime < time)
  48. {
  49. transform.position = Vector3.Lerp(startPosition, Target.VisualPosition, (elapsedTime / time));
  50. transform.position += yValue((elapsedTime / time), heightMax);
  51. yield return new WaitForEndOfFrame();
  52. elapsedTime += Time.deltaTime;
  53. }
  54. transform.position = Target.VisualPosition;
  55. characterAnimator.Play("Idle");
  56. }
  57. IEnumerator MoveCoroutine(Block Target, Transform Current, float time, float heightMax)
  58. {
  59. float elapsedTime = 0;
  60. Vector3 startPosition = Current.position;
  61. time *= 0.8f;
  62. while (elapsedTime < 1.5f)
  63. {
  64. characterAnimator.Play("Walk");
  65. transform.position = Vector3.Lerp(startPosition, Target.VisualPosition, (elapsedTime / 1.5f));
  66. //transform.position += yValue((elapsedTime / time), heightMax);
  67. //characterAnimator.Play("Walk");
  68. yield return new WaitForEndOfFrame();
  69. elapsedTime += Time.deltaTime;
  70. }
  71. transform.position = Target.VisualPosition;
  72. characterAnimator.Play("Idle");
  73. }
  74. IEnumerator MoveDownCoroutine(Block Target, Transform Current, float time, float heightMax)
  75. {
  76. float elapsedTime = 0;
  77. Vector3 startPosition = Current.position;
  78. time *= 0.8f;
  79. while (elapsedTime < time)
  80. {
  81. characterAnimator.Play("Walk");
  82. transform.position = Vector3.Lerp(startPosition, Target.VisualPosition, (elapsedTime / time));
  83. transform.position += yValue((elapsedTime / time), heightMax);
  84. yield return new WaitForEndOfFrame();
  85. elapsedTime += Time.deltaTime;
  86. }
  87. transform.position = Target.VisualPosition;
  88. characterAnimator.Play("Idle");
  89. }
  90. IEnumerator rotateCoroutine(Direction direction, Transform Current, float time, float heightMax)
  91. {
  92. float elapsedTime = 0;
  93. time *= 0.8f;
  94. Vector3 endDirection = direction.ToVector(Current);
  95. Vector3 startDirection = Current.forward;
  96. Vector3 startPosition = transform.position;
  97. while (elapsedTime < time)
  98. {
  99. characterAnimator.Play("Jump");
  100. transform.forward = Vector3.Slerp(startDirection, endDirection, (elapsedTime / time));
  101. //transform.position = startPosition +yValue((elapsedTime / time), heightMax);
  102. yield return new WaitForEndOfFrame();
  103. elapsedTime += Time.deltaTime;
  104. }
  105. transform.forward = endDirection;
  106. characterAnimator.Play("Idle");
  107. }
  108. /// <summary>
  109. /// Moves one block in specefied direction, Can walk off obstacles
  110. /// </summary>
  111. /// <param name="direction">direction to walk</param>
  112. /// <remarks>Technically is same as JumpLong(1) but kept seperate to avoid confusion</remarks>
  113. public void Move(Direction direction, float speed)
  114. {
  115. //setting up variables
  116. Vector3 position = CurrentBlock.position + direction.ToVector(transform); // position wanted
  117. Block hit; //output of block detection
  118. Block moveTo = CurrentBlock; //block we'll actually move to
  119. //if move is obstucted no where to move
  120. if (Block.isBlockAtPosition(position + Vector3.up, 1, ~Ignore))
  121. return;
  122. //If block at Position is walkable set it to moveTo
  123. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore)){
  124. moveTo = hit;
  125. CurrentBlock = moveTo;
  126. StartCoroutine(MoveCoroutine(CurrentBlock, transform, speed, 0.3f));
  127. characterAnimator.Play("Idle");
  128. }
  129. //else if block down one is walkable
  130. else if (Block.isBlockAtPosition(position + Vector3.down, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore)){
  131. moveTo = hit;
  132. CurrentBlock = moveTo;
  133. StartCoroutine(MoveDownCoroutine(CurrentBlock, transform, speed, 0.3f));
  134. characterAnimator.Play("Idle");
  135. }
  136. //set current block && move
  137. //CurrentBlock = moveTo;
  138. //StartCoroutine(MoveCoroutine(CurrentBlock, transform, speed, 0.3f));
  139. //characterAnimator.Play("Idle");
  140. //transform.position = CurrentBlock.VisualPosition;
  141. }
  142. /// <summary>
  143. /// Upon collision with a floating block, collect its
  144. /// Upon collision with the end portal, end of level
  145. /// </summary>
  146. /// <param name="other">name of collided object</param>
  147. void OnTriggerEnter(Collider other)
  148. {
  149. Collectable collectable = other.GetComponentInChildren<Collectable>();
  150. if (collectable != null)
  151. {
  152. collectable.OnCollect(this);
  153. }
  154. if (other.gameObject.name == "End Portal")
  155. {
  156. other.GetComponent<Collider>().enabled = false;
  157. SceneManager.LoadScene(nextScene);
  158. }
  159. }
  160. /// <summary>
  161. /// Rotates to point in specific direction based on current direction
  162. /// </summary>
  163. /// <param name="direction">Local direction to point</param>
  164. public void Rotate(Direction direction, float speed)
  165. {
  166. StartCoroutine(rotateCoroutine(direction, transform, speed, 0.15f));
  167. //transform.forward = direction.ToVector(transform);
  168. }
  169. /// <summary>
  170. /// Jumps in specefied direction, picks between Long Jump and Jumping up
  171. /// </summary>
  172. /// <param name="direction">Direction to Jump</param>
  173. public void Jump(Direction direction, float speed)
  174. {
  175. //if there is a block infront JumpUp else LongJump
  176. if (Block.isBlockAtPosition(CurrentBlock.position + direction.ToVector(transform) + Vector3.up, 1, ~Ignore))
  177. JumpUp(direction, speed);
  178. else
  179. JumpLong(direction, speed);
  180. }
  181. #endregion Class Implementation
  182. #region Private Functions
  183. /// <summary>
  184. /// Jumps up obstacle of specific height. Jumps as high as possible
  185. /// </summary>
  186. /// <param name="direction">Direction of obstacle</param>
  187. /// <param name="height">max height</param>
  188. private void JumpUp(Direction direction, float speed, int height = 1)
  189. {
  190. //setting up variables
  191. Vector3 position; // position wanted
  192. Block hit; //output of block detection
  193. Block moveTo = CurrentBlock; //block we'll actually move to
  194. //Check blocks in going up then move to the heighest walkable one
  195. for (int i = 0; i <= height; i++)
  196. {
  197. //next position up the tower
  198. position = CurrentBlock.position + direction.ToVector(transform) + (Vector3.up * i);
  199. //if block is walkable set it to last known position
  200. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  201. moveTo = hit;
  202. }
  203. //set current block && move
  204. CurrentBlock = moveTo;
  205. StartCoroutine(JumpCoroutine(CurrentBlock, transform, speed, 0.5f));
  206. //transform.position = CurrentBlock.VisualPosition;
  207. }
  208. /// <summary>
  209. /// Long jumps forward a specified distance. Can Jump gaps. Stops at obstruction
  210. /// </summary>
  211. /// <param name="direction">Direction to Jump</param>
  212. /// <param name="Distance">Max distance</param>
  213. private void JumpLong(Direction direction, float speed, int Distance = 2)
  214. {
  215. //setting up variables
  216. Vector3 position; // position wanted
  217. Block hit; //output of block detection
  218. Block moveTo = CurrentBlock; //block we'll actually move to
  219. //Check blocks in front until we hit an obstruction or went the distance
  220. for (int i = 1; i <= Distance; i++)
  221. {
  222. //Next position to MoveTo
  223. position = CurrentBlock.position + (direction.ToVector(transform) * i);
  224. //if jump is obstructed, stop and go to last known block
  225. if (Block.isBlockAtPosition(position + Vector3.up, 1, ~Ignore))
  226. break;
  227. //If block at Position is walkable set it to last known position
  228. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  229. moveTo = hit;
  230. //else if block down one is walkable
  231. else if (Block.isBlockAtPosition(position + Vector3.down, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  232. moveTo = hit;
  233. }//end for
  234. //Set Current Block and move
  235. CurrentBlock = moveTo;
  236. StartCoroutine(JumpCoroutine(CurrentBlock, transform, speed, 0.5f));
  237. //transform.position = CurrentBlock.VisualPosition;
  238. }
  239. #endregion Private Functions
  240. }