|
|
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- using UnityEngine.SceneManagement;
- using Networking.Server;
-
- public class Character : MonoBehaviour
- {
- public string nextScene;
- Animator characterAnimator;
- public bool isTuteLevel = false;
-
- public bool inWater = false; //Am I in the water?
- public bool inPit = false; //Did I fall into a pit?
- public bool stuck = false; //Am I still stuck?
- public bool justMoved = false; //Was the logic block I just executed a move command?
-
- #region Inspector Fields
-
- [SerializeField]
- [Tooltip("Will move to this block at start, else will try and find a block below")]
- private Block _currentBlock;
-
- [SerializeField]
- [Tooltip("Layers to ignore when checking for blocks")]
- private LayerMask Ignore;
-
- [Tooltip("Current Inventory of the player")]
- public Inventory Inventory;
- public bool CloneInventoryOnStart = false;
-
- [Tooltip("How many lives to start out with")]
- public int lives = 5;
-
- [SerializeField]
- [Tooltip("Character to display")]
- private string CharacterModel = "Bear";
-
- [SerializeField]
- public ClientData ClientLink;
-
- [SerializeField]
- private TMPro.TextMeshPro BlockTitlePrefab;
-
- #endregion Inspector Fields
-
- #region Read Only
- public Block CurrentBlock { get { return _currentBlock; } }
- #endregion Read Only
-
- #region Unity Functions
-
- private void Start()
- {
- if (Inventory != null && CloneInventoryOnStart)
- Inventory = Inventory.Clone(Inventory);
-
- //If no starting block find one below it
- if (_currentBlock == null)
- Block.isBlockAtPosition(transform.position + Vector3.down / 2, 1, ~Ignore, out _currentBlock);
-
- //move to starting block
- transform.position = _currentBlock.VisualPosition;
-
- //get character string from player replace from "Bear"
- GameObject prefab = Resources.Load(CharacterModel) as GameObject;
- GameObject animal = Instantiate(prefab, this.gameObject.transform);
-
- characterAnimator = GetComponentInChildren<Animator>();
- }
-
-
-
- #endregion Unity Functions
-
- #region Class Implementation
-
- public void Initialise(Block startingBlock, Inventory inventory, string Character)
- {
- _currentBlock = startingBlock;
- Inventory = inventory;
- CharacterModel = Character;
- }
-
- public void DisplayBlock(LogicBlock block)
- {
- if(isTuteLevel == false){
- if (BlockTitlePrefab == null)
- return;
-
- TMPro.TextMeshPro temp = Instantiate(BlockTitlePrefab.gameObject).GetComponent<TMPro.TextMeshPro>();
- temp.text = block.DisplayName;
- temp.color = ClientLink.Color;
-
- temp.transform.position = transform.position + (Vector3.one * 0.25f);
- temp.transform.rotation = Quaternion.LookRotation(temp.transform.position - Camera.main.transform.position);
- }
- }
-
- public Vector3 yValue(float time, float heightMultiplier)
- {
- float y = Mathf.Sin((Mathf.PI * time)) * heightMultiplier;
- return new Vector3(0, y, 0);
- }
-
- IEnumerator JumpCoroutine(Block Target, Transform Current, float time, float heightMax)
- {
- float elapsedTime = 0;
- Vector3 startPosition = Current.position;
- time *= 0.8f;
- characterAnimator.Play("Jump Inplace");
- yield return new WaitForSeconds(0.15f);
- while (elapsedTime < time)
- {
- transform.position = Vector3.Lerp(startPosition, Target.VisualPosition, (elapsedTime / time));
- transform.position += yValue((elapsedTime / time), heightMax);
- yield return new WaitForEndOfFrame();
- elapsedTime += Time.deltaTime;
- }
- transform.position = Target.VisualPosition;
- }
-
- IEnumerator MoveCoroutine(Block Target, Transform Current, float time, float heightMax)
- {
- float elapsedTime = 0;
- Vector3 startPosition = Current.position;
- time *= 0.8f;
- characterAnimator.Play("Walk");
- yield return new WaitForSeconds(0.05f);
- while (elapsedTime < time)
- {
-
- transform.position = Vector3.Lerp(startPosition, Target.VisualPosition, (elapsedTime / time));
- yield return new WaitForEndOfFrame();
- elapsedTime += Time.deltaTime;
- }
- transform.position = Target.VisualPosition;
- }
-
- IEnumerator MoveConveyorForwardCoroutine(Block Target, Transform Current, float time, float heightMax)
- {
- float elapsedTime = 0;
- Vector3 startPosition = Current.position;
- Vector3 charEndPosition = new Vector3(Current.position.x + 1.0f, Current.position.y, Current.position.z);
- time *= 0.8f;
- yield return new WaitForSeconds(0.05f);
- while (elapsedTime < time)
- {
- Current.position = Vector3.Lerp(startPosition, charEndPosition, (elapsedTime / time));
- yield return new WaitForEndOfFrame();
- elapsedTime += Time.deltaTime;
- }
- Current.position = charEndPosition;
- }
- IEnumerator MoveConveyorBackwardCoroutine(Block Target, Transform Current, float time, float heightMax)
- {
- float elapsedTime = 0;
- Vector3 startPosition = Current.position;
- Vector3 charEndPosition = new Vector3(Current.position.x - 1.0f, Current.position.y, Current.position.z);
- time *= 0.8f;
- yield return new WaitForSeconds(0.05f);
- while (elapsedTime < time)
- {
- Current.position = Vector3.Lerp(startPosition, charEndPosition, (elapsedTime / time));
- yield return new WaitForEndOfFrame();
- elapsedTime += Time.deltaTime;
- }
- Current.position = charEndPosition;
- }
- IEnumerator MoveConveyorLeftCoroutine(Block Target, Transform Current, float time, float heightMax)
- {
- float elapsedTime = 0;
- Vector3 startPosition = Current.position;
- Vector3 charEndPosition = new Vector3(Current.position.x, Current.position.y, Current.position.z + 1.0f);
- time *= 0.8f;
- yield return new WaitForSeconds(0.05f);
- while (elapsedTime < time)
- {
- Current.position = Vector3.Lerp(startPosition, charEndPosition, (elapsedTime / time));
- yield return new WaitForEndOfFrame();
- elapsedTime += Time.deltaTime;
- }
- Current.position = charEndPosition;
- }
- IEnumerator MoveConveyorRightCoroutine(Block Target, Transform Current, float time, float heightMax)
- {
- float elapsedTime = 0;
- Vector3 startPosition = Current.position;
- Vector3 charEndPosition = new Vector3(Current.position.x, Current.position.y, Current.position.z - 1.0f);
- time *= 0.8f;
- yield return new WaitForSeconds(0.05f);
- while (elapsedTime < time)
- {
- Current.position = Vector3.Lerp(startPosition, charEndPosition, (elapsedTime / time));
- yield return new WaitForEndOfFrame();
- elapsedTime += Time.deltaTime;
- }
- Current.position = charEndPosition;
- }
-
- IEnumerator PushLeftCoroutine(Transform Current, float time)
- {
- float elapsedTime = 0;
- Vector3 startPosition = Current.transform.position;
- Vector3 endPosition = new Vector3(Current.position.x, Current.position.y, Current.position.z + 1.0f);
- time *= 0.8f;
- yield return new WaitForSeconds(0.05f);
- while (elapsedTime < time)
- {
- Current.position = Vector3.Lerp(startPosition, endPosition, (elapsedTime / time));
- yield return new WaitForEndOfFrame();
- elapsedTime += Time.deltaTime;
- }
- Current.position = endPosition;
- }
-
- IEnumerator PushRightCoroutine(Transform Current, float time)
- {
- float elapsedTime = 0;
- Vector3 startPosition = Current.transform.position;
- Vector3 endPosition = new Vector3(Current.position.x, Current.position.y, Current.position.z - 1.0f);
- time *= 0.8f;
- yield return new WaitForSeconds(0.05f);
- while (elapsedTime < time)
- {
- Current.position = Vector3.Lerp(startPosition, endPosition, (elapsedTime / time));
- yield return new WaitForEndOfFrame();
- elapsedTime += Time.deltaTime;
- }
- Current.position = endPosition;
- }
-
- IEnumerator MoveDownCoroutine(Block Target, Transform Current, float time, float heightMax)
- {
- float elapsedTime = 0;
- Vector3 startPosition = Current.position;
- time *= 0.8f;
- characterAnimator.Play("Walk");
- while (elapsedTime < time)
- {
- transform.position = Vector3.Lerp(startPosition, Target.VisualPosition, (elapsedTime / time));
- transform.position += yValue((elapsedTime / time), heightMax);
- yield return new WaitForEndOfFrame();
- elapsedTime += Time.deltaTime;
- }
- transform.position = Target.VisualPosition;
- }
-
- IEnumerator rotateCoroutine(Direction direction, Transform Current, float time, float heightMax)
- {
- float elapsedTime = 0;
- time *= 0.8f;
- Vector3 endDirection = direction.ToVector(Current);
- Vector3 startDirection = Current.forward;
- Vector3 startPosition = transform.position;
- while (elapsedTime < time)
- {
- characterAnimator.Play("Jump");
- transform.forward = Vector3.Slerp(startDirection, endDirection, (elapsedTime / time));
- yield return new WaitForEndOfFrame();
- elapsedTime += Time.deltaTime;
- }
- transform.forward = endDirection;
- }
-
-
- /// <summary>
- /// Moves one block in specefied direction, Can walk off obstacles
- /// </summary>
- /// <param name="direction">direction to walk</param>
- /// <remarks>Technically is same as JumpLong(1) but kept seperate to avoid confusion</remarks>
- public void Move(Direction direction, float speed)
- {
- //setting up variables
- Vector3 position = _currentBlock.position + direction.ToVector(transform); // position wanted
- Block hit; //output of block detection
- Block moveTo = _currentBlock; //block we'll actually move to
-
- //if move is obstucted no where to move
- if (Block.isBlockAtPosition(position + Vector3.up, 1, ~Ignore))
- return;
-
-
- //If block at Position is walkable set it to moveTo
- if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
- {
- moveTo = hit;
- _currentBlock = moveTo;
- StartCoroutine(MoveCoroutine(_currentBlock, transform, speed, 0.3f));
- }
- //else if block down one is walkable
- else if (Block.isBlockAtPosition(position + Vector3.down, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
- {
- moveTo = hit;
- _currentBlock = moveTo;
- StartCoroutine(MoveDownCoroutine(_currentBlock, transform, speed, 0.3f));
- }
- }
-
- public void conveyorMoveForward(Direction direction, float speed)
- {
- Vector3 position = _currentBlock.position + direction.ToVector(transform); // position wanted
- Block hit; //output of block detection
- Block moveTo = _currentBlock; //block we'll actually move to
- if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
- {
- moveTo = hit;
- _currentBlock = moveTo;
- StartCoroutine(MoveConveyorForwardCoroutine(_currentBlock, transform, speed, 0.3f));
- }
-
- }
- public void conveyorMoveBackward(Direction direction, float speed)
- {
- Vector3 position = _currentBlock.position + direction.ToVector(transform); // position wanted
- Block hit; //output of block detection
- Block moveTo = _currentBlock; //block we'll actually move to
- if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
- {
- moveTo = hit;
- _currentBlock = moveTo;
- StartCoroutine(MoveConveyorBackwardCoroutine(_currentBlock, transform, speed, 0.3f));
- }
- }
- public void conveyorMoveLeft(Direction direction, float speed)
- {
- Vector3 position = _currentBlock.position + direction.ToVector(transform); // position wanted
- Block hit; //output of block detection
- Block moveTo = _currentBlock; //block we'll actually move to
- if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
- {
- moveTo = hit;
- _currentBlock = moveTo;
- StartCoroutine(MoveConveyorLeftCoroutine(_currentBlock, transform, speed, 0.3f));
- }
- }
- public void conveyorMoveRight(Direction direction, float speed)
- {
- Vector3 position = _currentBlock.position + direction.ToVector(transform); // position wanted
- Block hit; //output of block detection
- Block moveTo = _currentBlock; //block we'll actually move to
- if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
- {
- moveTo = hit;
- _currentBlock = moveTo;
- StartCoroutine(MoveConveyorRightCoroutine(_currentBlock, transform, speed, 0.3f));
- }
- }
-
- public void CannonRMove(float speed)
- {
- Direction direction = Direction.Right;
- Vector3 position = _currentBlock.position + direction.ToVector(transform); // position wanted
- Block hit; //output of block detection
- Block moveTo = _currentBlock; //block we'll actually move to
- if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
- {
- moveTo = hit;
- _currentBlock = moveTo;
- StartCoroutine(PushRightCoroutine(transform, speed));
- }
- }
- public void CannonLMove(float speed)
- {
- Direction direction = Direction.Left;
- Vector3 position = _currentBlock.position + direction.ToVector(transform); // position wanted
- Block hit; //output of block detection
- Block moveTo = _currentBlock; //block we'll actually move to
- if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
- {
- moveTo = hit;
- _currentBlock = moveTo;
- StartCoroutine(PushLeftCoroutine(transform, speed));
- }
- }
-
-
- public void respawnCharacter()
- {
- /* Will introduce more complex criteria for choosing where to respawn the player in future
- * For now: if the square one back (x =- 1) from the pit is walkable and unoccupied, then put them there
- * Otherwise, try the next square back, etc, until we find an available one
- */
-
- Block currentBlock = null;
- //We start from the position of our pit, at ground level
- Vector3 currentPos = new Vector3(this.transform.position.x, this.transform.position.y, this.transform.position.z);
-
- Debug.Log("Commencing respawn");
-
- //Hardcoding the number of iterations for now for simplicity, should change this later
- for (int i = 0; i < 100; i++)
- {
- //First we check one back
- currentPos.x -= 1;
- Debug.Log("currentPos = " + currentPos.x + ", " + currentPos.y + ", " + currentPos.z);
- if (Block.isBlockAtPosition(currentPos, 1, ~Ignore, out currentBlock)) //Does a block exist here?
- {
- Debug.Log("Block exists");
- if (currentBlock.isWalkable(~Ignore)) //If so, can we walk on it?
- {
- Debug.Log("Block is walkable");
- //Don't yet have a check for whether it's occupied
- break; //If it is, we stop here
- }
- }
-
- //If the block one back isn't an option, we check to the left and right
- currentPos.z += 1;
- Debug.Log("currentPos = " + currentPos.x + ", " + currentPos.y + ", " + currentPos.z);
- if (Block.isBlockAtPosition(currentPos, 1, ~Ignore, out currentBlock)) //Does a block exist here?
- {
- Debug.Log("Block exists");
- if (currentBlock.isWalkable(~Ignore)) //If so, can we walk on it?
- {
- Debug.Log("Block is walkable");
- //Don't yet have a check for whether it's occupied
- break; //If it is, we stop here
- }
- }
- currentPos.z -= 2;
- Debug.Log("currentPos = " + currentPos.x + ", " + currentPos.y + ", " + currentPos.z);
- if (Block.isBlockAtPosition(currentPos, 1, ~Ignore, out currentBlock)) //Does a block exist here?
- {
- Debug.Log("Block exists");
- if (currentBlock.isWalkable(~Ignore)) //If so, can we walk on it?
- {
- Debug.Log("Block is walkable");
- //Don't yet have a check for whether it's occupied
- break; //If it is, we stop here
- }
- }
-
- //If we've gotten this far and haven't found an available spot, we move back a row and try again
- currentPos.z += 1;
- }
-
- //Having found our target block, we move the character there
- if (currentBlock != null)
- {
- this.transform.position = currentBlock.VisualPosition;
- this.inPit = false;
- this._currentBlock = currentBlock;
- Debug.Log("Moved " + this.name + " to "
- + this.transform.position.x + ", "
- + this.transform.position.y + ", "
- + this.transform.position.z + ", "
- + " inPit = " + inPit);
- }
- else
- {
- Debug.Log("Failed to find anywhere to put " + this.name);
- }
-
- }
-
- /// <summary>
- /// Upon collision with a floating block, collect its
- /// Upon collision with the end portal, end of level
- /// </summary>
- /// <param name="other">name of collided object</param>
- void OnTriggerEnter(Collider other)
- {
- Collectable collectable = other.GetComponentInChildren<Collectable>();
-
- if (collectable != null)
- {
- collectable.OnCollect(this);
- }
- if (other.gameObject.name == "collect_sphere")
- {
- other.gameObject.SetActive(false);
- //player.collected +=1;
-
- }
- if (other.gameObject.name == "End Portal")
- {
- other.GetComponent<Collider>().enabled = false;
- SceneManager.LoadScene(nextScene);
- }
- }
-
- /// <summary>
- /// Rotates to point in specific direction based on current direction
- /// </summary>
- /// <param name="direction">Local direction to point</param>
- public void Rotate(Direction direction, float speed)
- {
- StartCoroutine(rotateCoroutine(direction, transform, speed, 0.15f));
- //transform.forward = direction.ToVector(transform);
- }
-
- /// <summary>
- /// Jumps in specefied direction, picks between Long Jump and Jumping up
- /// </summary>
- /// <param name="direction">Direction to Jump</param>
- public void Jump(Direction direction, float speed)
- {
- //if there is a block infront JumpUp else LongJump
- if (Block.isBlockAtPosition(_currentBlock.position + direction.ToVector(transform) + Vector3.up, 1, ~Ignore))
- JumpUp(direction, speed);
- else
- JumpLong(direction, speed);
- }
-
- #endregion Class Implementation
-
- #region Private Functions
-
- /// <summary>
- /// Jumps up obstacle of specific height. Jumps as high as possible
- /// </summary>
- /// <param name="direction">Direction of obstacle</param>
- /// <param name="height">max height</param>
- private void JumpUp(Direction direction, float speed, int height = 1)
- {
- //setting up variables
- Vector3 position; // position wanted
- Block hit; //output of block detection
- Block moveTo = _currentBlock; //block we'll actually move to
-
- //Check blocks in going up then move to the heighest walkable one
- for (int i = 0; i <= height; i++)
- {
- //next position up the tower
- position = _currentBlock.position + direction.ToVector(transform) + (Vector3.up * i);
-
- //if block is walkable set it to last known position
- if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
- moveTo = hit;
- }
-
- //set current block && move
- _currentBlock = moveTo;
- StartCoroutine(JumpCoroutine(_currentBlock, transform, speed, 0.5f));
- //transform.position = CurrentBlock.VisualPosition;
- }
-
- /// <summary>
- /// Long jumps forward a specified distance. Can Jump gaps. Stops at obstruction
- /// </summary>
- /// <param name="direction">Direction to Jump</param>
- /// <param name="Distance">Max distance</param>
- private void JumpLong(Direction direction, float speed, int Distance = 2)
- {
- //setting up variables
- Vector3 position; // position wanted
- Block hit; //output of block detection
- Block moveTo = _currentBlock; //block we'll actually move to
-
- //Check blocks in front until we hit an obstruction or went the distance
- for (int i = 1; i <= Distance; i++)
- {
- //Next position to MoveTo
- position = _currentBlock.position + (direction.ToVector(transform) * i);
-
- //if jump is obstructed, stop and go to last known block
- if (Block.isBlockAtPosition(position + Vector3.up, 1, ~Ignore))
- break;
-
-
- //If block at Position is walkable set it to last known position
- if (Block.isBlockAtPosition(position, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
- moveTo = hit;
- //else if block down one is walkable
- else if (Block.isBlockAtPosition(position + Vector3.down, 1, ~Ignore, out hit) && hit.isWalkable(~Ignore))
- moveTo = hit;
-
- }//end for
-
- //Set Current Block and move
- _currentBlock = moveTo;
- StartCoroutine(JumpCoroutine(_currentBlock, transform, speed, 0.5f));
- //transform.position = CurrentBlock.VisualPosition;
- }
-
- #endregion Private Functions
-
- }
|