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.

723 lines
27 KiB

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using UnityEngine.SceneManagement;
  6. using Networking.Server;
  7. public class Character : MonoBehaviour
  8. {
  9. public enum Animation { Walk, Run, Jump, Sit, Attack, Hit }
  10. public string nextScene;
  11. Animator characterAnimator;
  12. public bool isTuteLevel = false;
  13. public bool inWater = false; //Am I in the water?
  14. public bool inPit = false; //Did I fall into a pit?
  15. public bool stuck = false; //Am I still stuck?
  16. public bool justMoved = false; //Was the logic block I just executed a move command?
  17. #region Inspector Fields
  18. [SerializeField]
  19. [Tooltip("Will move to this block at start, else will try and find a block below")]
  20. private Block _currentBlock;
  21. [SerializeField]
  22. [Tooltip("Layers to ignore when checking for blocks")]
  23. public LayerMask Ignore;
  24. [Tooltip("Current Inventory of the player")]
  25. public Inventory Inventory;
  26. public bool CloneInventoryOnStart = false;
  27. [Tooltip("How many lives to start out with")]
  28. public int lives = 3;
  29. [SerializeField]
  30. [Tooltip("Character to display")]
  31. private string CharacterModel = "Bear";
  32. [SerializeField]
  33. public ClientData ClientLink;
  34. [SerializeField]
  35. private TMPro.TextMeshPro BlockTitlePrefab;
  36. #endregion Inspector Fields
  37. #region Read Only
  38. public Block CurrentBlock { get { return _currentBlock; } }
  39. #endregion Read Only
  40. #region Unity Functions
  41. private void Start()
  42. {
  43. if (Inventory != null && CloneInventoryOnStart)
  44. Inventory = Inventory.Clone(Inventory);
  45. //If no starting block find one below it
  46. if (_currentBlock == null)
  47. Block.isBlockAtPosition(transform.position + Vector3.down / 2, 1, ~Ignore, out _currentBlock);
  48. //move to starting block
  49. transform.position = _currentBlock.VisualPosition;
  50. //get character string from player replace from "Bear"
  51. GameObject prefab = Resources.Load(CharacterModel) as GameObject;
  52. GameObject animal = Instantiate(prefab, this.gameObject.transform);
  53. characterAnimator = GetComponentInChildren<Animator>();
  54. }
  55. #endregion Unity Functions
  56. #region Class Implementation
  57. public void Initialise(Block startingBlock, Inventory inventory, string Character)
  58. {
  59. _currentBlock = startingBlock;
  60. Inventory = inventory;
  61. CharacterModel = Character;
  62. }
  63. public void DisplayBlock(LogicBlock block)
  64. {
  65. if (isTuteLevel == false)
  66. {
  67. if (BlockTitlePrefab == null)
  68. return;
  69. TMPro.TextMeshPro temp = Instantiate(BlockTitlePrefab.gameObject).GetComponent<TMPro.TextMeshPro>();
  70. temp.text = block.DisplayName;
  71. temp.color = ClientLink.Color;
  72. temp.transform.position = transform.position + (Vector3.one * 0.25f);
  73. temp.transform.rotation = Quaternion.LookRotation(temp.transform.position - Camera.main.transform.position);
  74. }
  75. }
  76. public IEnumerator MoveToBlock(Block target, Animation animation, float time)
  77. {
  78. System.Func<float, float> yFunction = null;
  79. if (animation == Animation.Jump)
  80. yFunction = (t) => Mathf.Sin((Mathf.PI * t));
  81. StartAnimation(animation, time);
  82. yield return StartCoroutine(LerpToBlock(target.VisualPosition, time, yFunction));
  83. _currentBlock= target;
  84. StopAnimation(animation);
  85. }
  86. public IEnumerator RotateToDirection(Direction direction, Animation animation, float time, bool isLocal = true)
  87. {
  88. System.Func<float, float> yFunction = null;
  89. if (animation == Animation.Jump)
  90. yFunction = (t) => Mathf.Sin((Mathf.PI * t));
  91. Vector3 _endDir = isLocal ? direction.ToVector(transform) : direction.ToVector();
  92. StartAnimation(animation, time);
  93. yield return StartCoroutine(LerpToRotation(_endDir, time, yFunction));
  94. StopAnimation(animation);
  95. }
  96. private IEnumerator LerpToBlock(Vector3 target, float time, System.Func<float, float> heightOffset = null)
  97. {
  98. Vector3 _startPos = transform.position;
  99. Vector3 _endPos = target;
  100. Vector3 _newPos;
  101. float elapsedTime = 0;
  102. while (elapsedTime / time < 1)
  103. {
  104. _newPos = Vector3.Lerp(_startPos, _endPos, (elapsedTime / time));
  105. if (heightOffset != null)
  106. _newPos.y += heightOffset(elapsedTime / time);
  107. transform.position = _newPos;
  108. yield return new WaitForEndOfFrame();
  109. elapsedTime += Time.deltaTime;
  110. }
  111. _newPos = _endPos;
  112. if (heightOffset != null)
  113. _newPos.y += heightOffset(1);
  114. transform.position = _newPos;
  115. }
  116. private IEnumerator LerpToRotation(Vector3 target, float time, System.Func<float, float> heightOffset = null)
  117. {
  118. Vector3 _startDir = transform.forward;
  119. Vector3 _endDir = target;
  120. Vector3 _startPos = transform.position;
  121. float elapsedTime = 0;
  122. while (elapsedTime / time < 1)
  123. {
  124. transform.forward = Vector3.Slerp(_startDir, _endDir, (elapsedTime / time));
  125. if (heightOffset != null)
  126. transform.position = _startPos + Vector3.up * heightOffset(elapsedTime / time);
  127. yield return new WaitForEndOfFrame();
  128. elapsedTime += Time.deltaTime;
  129. }
  130. transform.forward = target;
  131. if (heightOffset != null)
  132. transform.position = _startPos + Vector3.up * heightOffset(1);
  133. }
  134. public void StartAnimation(Animation animation,float speed = 1)
  135. {
  136. characterAnimator.SetFloat("AnimationSpeed", (1 / speed));
  137. switch (animation)
  138. {
  139. case Animation.Walk:
  140. characterAnimator.SetBool("isWalking", true);
  141. break;
  142. case Animation.Run:
  143. characterAnimator.SetBool("isRunning", true);
  144. break;
  145. case Animation.Sit:
  146. characterAnimator.SetBool("isSitting", true);
  147. break;
  148. case Animation.Jump:
  149. characterAnimator.SetTrigger("Jump");
  150. break;
  151. case Animation.Attack:
  152. characterAnimator.SetTrigger("Attack");
  153. break;
  154. case Animation.Hit:
  155. characterAnimator.SetTrigger("Hit");
  156. break;
  157. default:
  158. break;
  159. }
  160. }
  161. public void StopAnimation(Animation animation)
  162. {
  163. characterAnimator.SetFloat("AnimationSpeed", 1f);
  164. switch (animation)
  165. {
  166. case Animation.Walk:
  167. characterAnimator.SetBool("isWalking", false);
  168. break;
  169. case Animation.Run:
  170. characterAnimator.SetBool("isRunning", false);
  171. break;
  172. case Animation.Sit:
  173. characterAnimator.SetBool("isSitting", false);
  174. break;
  175. }
  176. }
  177. IEnumerator JumpCoroutine(Block Target, Transform Current, float time, float heightMax)
  178. {
  179. float elapsedTime = 0;
  180. Vector3 startPosition = Current.position;
  181. time *= 0.8f;
  182. characterAnimator.Play("Jump Inplace");
  183. yield return new WaitForSeconds(0.15f);
  184. while (elapsedTime < time)
  185. {
  186. transform.position = Vector3.Lerp(startPosition, Target.VisualPosition, (elapsedTime / time));
  187. //transform.position += yValue((elapsedTime / time), heightMax);
  188. yield return new WaitForEndOfFrame();
  189. elapsedTime += Time.deltaTime;
  190. }
  191. transform.position = Target.VisualPosition;
  192. }
  193. IEnumerator MoveCoroutine(Block Target, Transform Current, float time, float heightMax)
  194. {
  195. float elapsedTime = 0;
  196. Vector3 startPosition = Current.position;
  197. time *= 0.8f;
  198. characterAnimator.Play("Walk");
  199. yield return new WaitForSeconds(0.05f);
  200. while (elapsedTime < time)
  201. {
  202. transform.position = Vector3.Lerp(startPosition, Target.VisualPosition, (elapsedTime / time));
  203. yield return new WaitForEndOfFrame();
  204. elapsedTime += Time.deltaTime;
  205. }
  206. transform.position = Target.VisualPosition;
  207. }
  208. IEnumerator MoveConveyorForwardCoroutine(Block Target, Transform Current, float time, float heightMax)
  209. {
  210. float elapsedTime = 0;
  211. Vector3 startPosition = Current.position;
  212. Vector3 charEndPosition = new Vector3(Current.position.x + 1.0f, Current.position.y, Current.position.z);
  213. time *= 0.8f;
  214. yield return new WaitForSeconds(0.05f);
  215. while (elapsedTime < time)
  216. {
  217. Current.position = Vector3.Lerp(startPosition, charEndPosition, (elapsedTime / time));
  218. yield return new WaitForEndOfFrame();
  219. elapsedTime += Time.deltaTime;
  220. }
  221. Current.position = charEndPosition;
  222. }
  223. IEnumerator MoveConveyorBackwardCoroutine(Block Target, Transform Current, float time, float heightMax)
  224. {
  225. float elapsedTime = 0;
  226. Vector3 startPosition = Current.position;
  227. Vector3 charEndPosition = new Vector3(Current.position.x - 1.0f, Current.position.y, Current.position.z);
  228. time *= 0.8f;
  229. yield return new WaitForSeconds(0.05f);
  230. while (elapsedTime < time)
  231. {
  232. Current.position = Vector3.Lerp(startPosition, charEndPosition, (elapsedTime / time));
  233. yield return new WaitForEndOfFrame();
  234. elapsedTime += Time.deltaTime;
  235. }
  236. Current.position = charEndPosition;
  237. }
  238. IEnumerator MoveConveyorLeftCoroutine(Block Target, Transform Current, float time, float heightMax)
  239. {
  240. float elapsedTime = 0;
  241. Vector3 startPosition = Current.position;
  242. Vector3 charEndPosition = new Vector3(Current.position.x, Current.position.y, Current.position.z + 1.0f);
  243. time *= 0.8f;
  244. yield return new WaitForSeconds(0.05f);
  245. while (elapsedTime < time)
  246. {
  247. Current.position = Vector3.Lerp(startPosition, charEndPosition, (elapsedTime / time));
  248. yield return new WaitForEndOfFrame();
  249. elapsedTime += Time.deltaTime;
  250. }
  251. Current.position = charEndPosition;
  252. }
  253. IEnumerator MoveConveyorRightCoroutine(Block Target, Transform Current, float time, float heightMax)
  254. {
  255. float elapsedTime = 0;
  256. Vector3 startPosition = Current.position;
  257. Vector3 charEndPosition = new Vector3(Current.position.x, Current.position.y, Current.position.z - 1.0f);
  258. time *= 0.8f;
  259. yield return new WaitForSeconds(0.05f);
  260. while (elapsedTime < time)
  261. {
  262. Current.position = Vector3.Lerp(startPosition, charEndPosition, (elapsedTime / time));
  263. yield return new WaitForEndOfFrame();
  264. elapsedTime += Time.deltaTime;
  265. }
  266. Current.position = charEndPosition;
  267. }
  268. IEnumerator PushLeftCoroutine(Transform Current, float time)
  269. {
  270. float elapsedTime = 0;
  271. Vector3 startPosition = Current.transform.position;
  272. Vector3 endPosition = new Vector3(Current.position.x, Current.position.y, Current.position.z + 1.0f);
  273. time *= 0.8f;
  274. yield return new WaitForSeconds(0.05f);
  275. while (elapsedTime < time)
  276. {
  277. Current.position = Vector3.Lerp(startPosition, endPosition, (elapsedTime / time));
  278. yield return new WaitForEndOfFrame();
  279. elapsedTime += Time.deltaTime;
  280. }
  281. Current.position = endPosition;
  282. }
  283. IEnumerator PushRightCoroutine(Transform Current, float time)
  284. {
  285. float elapsedTime = 0;
  286. Vector3 startPosition = Current.transform.position;
  287. Vector3 endPosition = new Vector3(Current.position.x, Current.position.y, Current.position.z - 1.0f);
  288. time *= 0.8f;
  289. yield return new WaitForSeconds(0.05f);
  290. while (elapsedTime < time)
  291. {
  292. Current.position = Vector3.Lerp(startPosition, endPosition, (elapsedTime / time));
  293. yield return new WaitForEndOfFrame();
  294. elapsedTime += Time.deltaTime;
  295. }
  296. Current.position = endPosition;
  297. }
  298. IEnumerator MoveDownCoroutine(Block Target, Transform Current, float time, float heightMax)
  299. {
  300. float elapsedTime = 0;
  301. Vector3 startPosition = Current.position;
  302. time *= 0.8f;
  303. characterAnimator.Play("Walk");
  304. while (elapsedTime < time)
  305. {
  306. transform.position = Vector3.Lerp(startPosition, Target.VisualPosition, (elapsedTime / time));
  307. //transform.position += yValue((elapsedTime / time), heightMax);
  308. yield return new WaitForEndOfFrame();
  309. elapsedTime += Time.deltaTime;
  310. }
  311. transform.position = Target.VisualPosition;
  312. }
  313. IEnumerator rotateCoroutine(Direction direction, Transform Current, float time, float heightMax)
  314. {
  315. float elapsedTime = 0;
  316. time *= 0.8f;
  317. Vector3 endDirection = direction.ToVector(Current);
  318. Vector3 startDirection = Current.forward;
  319. while (elapsedTime < time)
  320. {
  321. characterAnimator.Play("Jump");
  322. transform.forward = Vector3.Slerp(startDirection, endDirection, (elapsedTime / time));
  323. yield return new WaitForEndOfFrame();
  324. elapsedTime += Time.deltaTime;
  325. }
  326. transform.forward = endDirection;
  327. }
  328. IEnumerator rotateHalfCoroutine(Direction direction, Transform Current, float time, float heightMax)
  329. {
  330. float elapsedTime = 0;
  331. time *= 0.8f;
  332. Vector3 endDirection = (direction.ToVector(Current) + Current.forward).normalized;
  333. Vector3 startDirection = Current.forward;
  334. while (elapsedTime < time)
  335. {
  336. characterAnimator.Play("Jump");
  337. transform.forward = Vector3.Slerp(startDirection, endDirection, (elapsedTime / time));
  338. yield return new WaitForEndOfFrame();
  339. elapsedTime += Time.deltaTime;
  340. }
  341. transform.forward = endDirection;
  342. }
  343. /// <summary>
  344. /// Moves one block in specefied direction, Can walk off obstacles
  345. /// </summary>
  346. /// <param name="direction">direction to walk</param>
  347. /// <remarks>Technically is same as JumpLong(1) but kept seperate to avoid confusion</remarks>
  348. public void Move(Direction direction, float speed)
  349. {
  350. //setting up variables
  351. Vector3 position = _currentBlock.position + direction.ToVector(transform); // position wanted
  352. Block hit; //output of block detection
  353. Block moveTo = _currentBlock; //block we'll actually move to
  354. //if move is obstucted no where to move
  355. if (Block.isBlockAtPosition(position + Vector3.up, 1, ~Ignore))
  356. return;
  357. //If block at Position is walkable set it to moveTo
  358. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  359. {
  360. moveTo = hit;
  361. _currentBlock = moveTo;
  362. StartCoroutine(MoveCoroutine(_currentBlock, transform, speed, 0.3f));
  363. }
  364. //else if block down one is walkable
  365. else if (Block.isBlockAtPosition(position + Vector3.down, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  366. {
  367. moveTo = hit;
  368. _currentBlock = moveTo;
  369. StartCoroutine(MoveDownCoroutine(_currentBlock, transform, speed, 0.3f));
  370. }
  371. }
  372. public void conveyorMoveForward(Direction direction, float speed)
  373. {
  374. Vector3 position = _currentBlock.position + direction.ToVector(transform); // position wanted
  375. Block hit; //output of block detection
  376. Block moveTo = _currentBlock; //block we'll actually move to
  377. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  378. {
  379. moveTo = hit;
  380. _currentBlock = moveTo;
  381. StartCoroutine(MoveConveyorForwardCoroutine(_currentBlock, transform, speed, 0.3f));
  382. }
  383. }
  384. public void conveyorMoveBackward(Direction direction, float speed)
  385. {
  386. Vector3 position = _currentBlock.position + direction.ToVector(transform); // position wanted
  387. Block hit; //output of block detection
  388. Block moveTo = _currentBlock; //block we'll actually move to
  389. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  390. {
  391. moveTo = hit;
  392. _currentBlock = moveTo;
  393. StartCoroutine(MoveConveyorBackwardCoroutine(_currentBlock, transform, speed, 0.3f));
  394. }
  395. }
  396. public void conveyorMoveLeft(Direction direction, float speed)
  397. {
  398. Vector3 position = _currentBlock.position + direction.ToVector(transform); // position wanted
  399. Block hit; //output of block detection
  400. Block moveTo = _currentBlock; //block we'll actually move to
  401. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  402. {
  403. moveTo = hit;
  404. _currentBlock = moveTo;
  405. StartCoroutine(MoveConveyorLeftCoroutine(_currentBlock, transform, speed, 0.3f));
  406. }
  407. }
  408. public void conveyorMoveRight(Direction direction, float speed)
  409. {
  410. Vector3 position = _currentBlock.position + direction.ToVector(transform); // position wanted
  411. Block hit; //output of block detection
  412. Block moveTo = _currentBlock; //block we'll actually move to
  413. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  414. {
  415. moveTo = hit;
  416. _currentBlock = moveTo;
  417. StartCoroutine(MoveConveyorRightCoroutine(_currentBlock, transform, speed, 0.3f));
  418. }
  419. }
  420. public void CannonRMove(float speed)
  421. {
  422. Direction direction = Direction.Right;
  423. Vector3 position = _currentBlock.position + direction.ToVector(transform); // position wanted
  424. Block hit; //output of block detection
  425. Block moveTo = _currentBlock; //block we'll actually move to
  426. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  427. {
  428. moveTo = hit;
  429. _currentBlock = moveTo;
  430. StartCoroutine(PushRightCoroutine(transform, speed));
  431. }
  432. }
  433. public void CannonLMove(float speed)
  434. {
  435. Direction direction = Direction.Left;
  436. Vector3 position = _currentBlock.position + direction.ToVector(transform); // position wanted
  437. Block hit; //output of block detection
  438. Block moveTo = _currentBlock; //block we'll actually move to
  439. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  440. {
  441. moveTo = hit;
  442. _currentBlock = moveTo;
  443. StartCoroutine(PushLeftCoroutine(transform, speed));
  444. }
  445. }
  446. public void respawnCharacter()
  447. {
  448. /* Will introduce more complex criteria for choosing where to respawn the player in future
  449. * For now: if the square one back (x =- 1) from the pit is walkable and unoccupied, then put them there
  450. * Otherwise, try the next square back, etc, until we find an available one
  451. */
  452. Block currentBlock = null;
  453. //We start from the position of our pit, at ground level
  454. Vector3 currentPos = new Vector3(this.transform.position.x, this.transform.position.y, this.transform.position.z);
  455. Debug.Log("Commencing respawn");
  456. //Hardcoding the number of iterations for now for simplicity, should change this later
  457. for (int i = 0; i < 100; i++)
  458. {
  459. //First we check one back
  460. currentPos.x -= 1;
  461. Debug.Log("currentPos = " + currentPos.x + ", " + currentPos.y + ", " + currentPos.z);
  462. if (Block.isBlockAtPosition(currentPos, 1, ~Ignore, out currentBlock)) //Does a block exist here?
  463. {
  464. Debug.Log("Block exists");
  465. if (currentBlock.isWalkable(~Ignore)) //If so, can we walk on it?
  466. {
  467. Debug.Log("Block is walkable");
  468. //Don't yet have a check for whether it's occupied
  469. break; //If it is, we stop here
  470. }
  471. }
  472. //If the block one back isn't an option, we check to the left and right
  473. currentPos.z += 1;
  474. Debug.Log("currentPos = " + currentPos.x + ", " + currentPos.y + ", " + currentPos.z);
  475. if (Block.isBlockAtPosition(currentPos, 1, ~Ignore, out currentBlock)) //Does a block exist here?
  476. {
  477. Debug.Log("Block exists");
  478. if (currentBlock.isWalkable(~Ignore)) //If so, can we walk on it?
  479. {
  480. Debug.Log("Block is walkable");
  481. //Don't yet have a check for whether it's occupied
  482. break; //If it is, we stop here
  483. }
  484. }
  485. currentPos.z -= 2;
  486. Debug.Log("currentPos = " + currentPos.x + ", " + currentPos.y + ", " + currentPos.z);
  487. if (Block.isBlockAtPosition(currentPos, 1, ~Ignore, out currentBlock)) //Does a block exist here?
  488. {
  489. Debug.Log("Block exists");
  490. if (currentBlock.isWalkable(~Ignore)) //If so, can we walk on it?
  491. {
  492. Debug.Log("Block is walkable");
  493. //Don't yet have a check for whether it's occupied
  494. break; //If it is, we stop here
  495. }
  496. }
  497. //If we've gotten this far and haven't found an available spot, we move back a row and try again
  498. currentPos.z += 1;
  499. }
  500. //Having found our target block, we move the character there
  501. if (currentBlock != null)
  502. {
  503. this.transform.position = currentBlock.VisualPosition;
  504. this.inPit = false;
  505. this._currentBlock = currentBlock;
  506. Debug.Log("Moved " + this.name + " to "
  507. + this.transform.position.x + ", "
  508. + this.transform.position.y + ", "
  509. + this.transform.position.z + ", "
  510. + " inPit = " + inPit);
  511. }
  512. else
  513. {
  514. Debug.Log("Failed to find anywhere to put " + this.name);
  515. }
  516. }
  517. /// <summary>
  518. /// Upon collision with a floating block, collect its
  519. /// Upon collision with the end portal, end of level
  520. /// </summary>
  521. /// <param name="other">name of collided object</param>
  522. void OnTriggerEnter(Collider other)
  523. {
  524. Collectable collectable = other.GetComponentInChildren<Collectable>();
  525. if (collectable != null)
  526. {
  527. collectable.OnCollect(this);
  528. }
  529. if (other.gameObject.name == "collect_sphere")
  530. {
  531. other.gameObject.SetActive(false);
  532. //player.collected +=1;
  533. }
  534. if (other.gameObject.name == "End Portal")
  535. {
  536. other.GetComponent<Collider>().enabled = false;
  537. SceneManager.LoadScene(nextScene);
  538. }
  539. }
  540. /// <summary>
  541. /// Rotates to point in specific direction based on current direction
  542. /// </summary>
  543. /// <param name="direction">Local direction to point</param>
  544. public void Rotate(Direction direction, float speed)
  545. {
  546. StartCoroutine(rotateCoroutine(direction, transform, speed, 0.15f));
  547. //transform.forward = direction.ToVector(transform);
  548. }
  549. public void RotateHalf(Direction direction, float speed)
  550. {
  551. StartCoroutine(rotateHalfCoroutine(direction, transform, speed, 0.15f));
  552. //transform.forward = direction.ToVector(transform);
  553. }
  554. /// <summary>
  555. /// Jumps in specefied direction, picks between Long Jump and Jumping up
  556. /// </summary>
  557. /// <param name="direction">Direction to Jump</param>
  558. public void Jump(Direction direction, float speed)
  559. {
  560. //if there is a block infront JumpUp else LongJump
  561. if (Block.isBlockAtPosition(_currentBlock.position + direction.ToVector(transform) + Vector3.up, 1, ~Ignore))
  562. JumpUp(direction, speed);
  563. else
  564. JumpLong(direction, speed);
  565. }
  566. #endregion Class Implementation
  567. #region Private Functions
  568. /// <summary>
  569. /// Jumps up obstacle of specific height. Jumps as high as possible
  570. /// </summary>
  571. /// <param name="direction">Direction of obstacle</param>
  572. /// <param name="height">max height</param>
  573. private void JumpUp(Direction direction, float speed, int height = 1)
  574. {
  575. //setting up variables
  576. Vector3 position; // position wanted
  577. Block hit; //output of block detection
  578. Block moveTo = _currentBlock; //block we'll actually move to
  579. //Check blocks in going up then move to the heighest walkable one
  580. for (int i = 0; i <= height; i++)
  581. {
  582. //next position up the tower
  583. position = _currentBlock.position + direction.ToVector(transform) + (Vector3.up * i);
  584. //if block is walkable set it to last known position
  585. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  586. moveTo = hit;
  587. }
  588. //set current block && move
  589. _currentBlock = moveTo;
  590. StartCoroutine(JumpCoroutine(_currentBlock, transform, speed, 0.5f));
  591. //transform.position = CurrentBlock.VisualPosition;
  592. }
  593. /// <summary>
  594. /// Long jumps forward a specified distance. Can Jump gaps. Stops at obstruction
  595. /// </summary>
  596. /// <param name="direction">Direction to Jump</param>
  597. /// <param name="Distance">Max distance</param>
  598. private void JumpLong(Direction direction, float speed, int Distance = 2)
  599. {
  600. //setting up variables
  601. Vector3 position; // position wanted
  602. Block hit; //output of block detection
  603. Block moveTo = _currentBlock; //block we'll actually move to
  604. //Check blocks in front until we hit an obstruction or went the distance
  605. for (int i = 1; i <= Distance; i++)
  606. {
  607. //Next position to MoveTo
  608. position = _currentBlock.position + (direction.ToVector(transform) * i);
  609. //if jump is obstructed, stop and go to last known block
  610. if (Block.isBlockAtPosition(position + Vector3.up, 1, ~Ignore))
  611. break;
  612. //If block at Position is walkable set it to last known position
  613. if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  614. moveTo = hit;
  615. //else if block down one is walkable
  616. else if (Block.isBlockAtPosition(position + Vector3.down, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
  617. moveTo = hit;
  618. }//end for
  619. //Set Current Block and move
  620. _currentBlock = moveTo;
  621. StartCoroutine(JumpCoroutine(_currentBlock, transform, speed, 0.5f));
  622. //transform.position = CurrentBlock.VisualPosition;
  623. }
  624. #endregion Private Functions
  625. }