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.

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