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.

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