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.

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