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.

210 lines
7.0 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. IEnumerator MoveCoRoutine(Block Target, Transform Current, float time)
  35. {
  36. float elapsedTime = 0;
  37. Vector3 startPosition = Current.position;
  38. time *= 0.8f;
  39. while (elapsedTime < time)
  40. {
  41. transform.position = Vector3.Lerp(startPosition, Target.VisualPosition, (elapsedTime / time));
  42. yield return new WaitForEndOfFrame();
  43. elapsedTime += Time.deltaTime;
  44. }
  45. transform.position = Target.VisualPosition;
  46. }
  47. /// <summary>
  48. /// Moves one block in specefied direction, Can walk off obstacles
  49. /// </summary>
  50. /// <param name="direction">direction to walk</param>
  51. /// <remarks>Technically is same as JumpLong(1) but kept seperate to avoid confusion</remarks>
  52. public void Move(Direction direction, float speed)
  53. {
  54. //setting up variables
  55. Vector3 position = CurrentBlock.position + direction.ToVector(transform); // position wanted
  56. Block hit; //output of block detection
  57. Block moveTo = CurrentBlock; //block we'll actually move to
  58. //if move is obstucted no where to move
  59. if (Block.isBlockAtPosition(position + Vector3.up, 1, ~Ignore))
  60. return;
  61. //If block at Position is walkable set it to moveTo
  62. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  63. moveTo = hit;
  64. //else if block down one is walkable
  65. else if (Block.isBlockAtPosition(position + Vector3.down, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  66. moveTo = hit;
  67. //set current block && move
  68. CurrentBlock = moveTo;
  69. StartCoroutine(MoveCoRoutine(CurrentBlock, transform, speed));
  70. //transform.position = CurrentBlock.VisualPosition;
  71. }
  72. /// <summary>
  73. /// Upon collision with a floating block, collect its
  74. /// Upon collision with the end portal, end of level
  75. /// </summary>
  76. /// <param name="other">name of collided object</param>
  77. void OnTriggerEnter(Collider other)
  78. {
  79. Collectable collectable = other.GetComponentInChildren<Collectable>();
  80. if (collectable != null)
  81. {
  82. collectable.OnCollect(this);
  83. }
  84. if (other.gameObject.name == "End Portal")
  85. {
  86. other.GetComponent<Collider>().enabled = false;
  87. Debug.Log("You finished this level!");
  88. SceneManager.LoadScene(nextScene);
  89. }
  90. }
  91. /// <summary>
  92. /// Rotates to point in specific direction based on current direction
  93. /// </summary>
  94. /// <param name="direction">Local direction to point</param>
  95. public void Rotate(Direction direction)
  96. {
  97. transform.forward = direction.ToVector(transform);
  98. }
  99. /// <summary>
  100. /// Jumps in specefied direction, picks between Long Jump and Jumping up
  101. /// </summary>
  102. /// <param name="direction">Direction to Jump</param>
  103. public void Jump(Direction direction)
  104. {
  105. //if there is a block infront JumpUp else LongJump
  106. if (Block.isBlockAtPosition(CurrentBlock.position + direction.ToVector(transform) + Vector3.up, 1, ~Ignore))
  107. JumpUp(direction);
  108. else
  109. JumpLong(direction);
  110. }
  111. #endregion Class Implementation
  112. #region Private Functions
  113. /// <summary>
  114. /// Jumps up obstacle of specific height. Jumps as high as possible
  115. /// </summary>
  116. /// <param name="direction">Direction of obstacle</param>
  117. /// <param name="height">max height</param>
  118. private void JumpUp(Direction direction, int height = 1)
  119. {
  120. //setting up variables
  121. Vector3 position; // position wanted
  122. Block hit; //output of block detection
  123. Block moveTo = CurrentBlock; //block we'll actually move to
  124. //Check blocks in going up then move to the heighest walkable one
  125. for (int i = 0; i <= height; i++)
  126. {
  127. //next position up the tower
  128. position = CurrentBlock.position + direction.ToVector(transform) + (Vector3.up * i);
  129. //if block is walkable set it to last known position
  130. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  131. moveTo = hit;
  132. }
  133. //set current block && move
  134. CurrentBlock = moveTo;
  135. transform.position = CurrentBlock.VisualPosition;
  136. }
  137. /// <summary>
  138. /// Long jumps forward a specified distance. Can Jump gaps. Stops at obstruction
  139. /// </summary>
  140. /// <param name="direction">Direction to Jump</param>
  141. /// <param name="Distance">Max distance</param>
  142. private void JumpLong(Direction direction, int Distance = 2)
  143. {
  144. //setting up variables
  145. Vector3 position; // position wanted
  146. Block hit; //output of block detection
  147. Block moveTo = CurrentBlock; //block we'll actually move to
  148. //Check blocks in front until we hit an obstruction or went the distance
  149. for (int i = 1; i <= Distance; i++)
  150. {
  151. //Next position to MoveTo
  152. position = CurrentBlock.position + (direction.ToVector(transform) * i);
  153. //if jump is obstructed, stop and go to last known block
  154. if (Block.isBlockAtPosition(position + Vector3.up, 1, ~Ignore))
  155. break;
  156. //If block at Position is walkable set it to last known position
  157. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  158. moveTo = hit;
  159. //else if block down one is walkable
  160. else if (Block.isBlockAtPosition(position + Vector3.down, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  161. moveTo = hit;
  162. }//end for
  163. //Set Current Block and move
  164. CurrentBlock = moveTo;
  165. transform.position = CurrentBlock.VisualPosition;
  166. }
  167. #endregion Private Functions
  168. }