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.

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