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.

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