|
|
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- using UnityEngine.SceneManagement;
- using Networking.Server;
-
- public class Character : MonoBehaviour
- {
- public enum Animation { Walk, Run, Jump, Sit, Attack, Hit }
-
- 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 onCrystal = false;
- public bool underRock = false;
- public bool stuck = false; //Am I still stuck?
- public bool justMoved = false; //Was the logic block I just executed a move command?
- Vector3 death = new Vector3(-50, 0, 0);
- #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")]
- public 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 = 3;
-
- [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; } }
- public float lastRotation { get; private set;}
- #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>();
- }
- private void Update()
- {
- if(lives < 1)
- {
- this.transform.position = death;
- //this.enabled = false;
- //gameObject.SetActive(false);
- }
- }
-
-
- #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 IEnumerator MoveToBlock(Block target, Animation animation, float time)
- {
- float startTime = Time.time;
- Vector3 moveDirection = Vector3.ProjectOnPlane(target.position - _currentBlock.position, Vector3.up).normalized;
-
- _currentBlock.OnLeftByPlayer(this);
-
- System.Func<float, float> yFunction = null;
- if (animation == Animation.Jump)
- yFunction = (t) => Mathf.Sin((Mathf.PI * t));
-
- StartAnimation(animation, time);
-
- yield return StartCoroutine(LerpToBlock(target.VisualPosition, time * 0.8f, yFunction));
-
- _currentBlock= target;
- yield return StartCoroutine (_currentBlock.OnWalkedOnByPlayer(this,moveDirection));
-
- yield return new WaitForSeconds(time - (Time.time - startTime));
-
- StopAnimation(animation);
- }
-
-
-
- public IEnumerator RotateInDirection(Direction direction,float angles, Animation animation, float time)
- {
- System.Func<float, float> yFunction = null;
- if (animation == Animation.Jump)
- yFunction = (t) => Mathf.Sin((Mathf.PI * t));
-
- StartAnimation(animation, time);
-
- //Debug.Log("Rotating by: " + angles);
- yield return StartCoroutine(Rotate(direction,angles, time * 0.8f, yFunction));
-
- StopAnimation(animation);
- }
-
-
-
-
- public IEnumerator AnimateToPosition(Vector3 position, Animation animation, float time)
- {
- System.Func<float, float> yFunction = null;
- if (animation == Animation.Jump)
- yFunction = (t) => Mathf.Sin((Mathf.PI * t));
-
- StartAnimation(animation, time);
-
- yield return StartCoroutine(LerpToBlock(position, time * 0.8f, yFunction));
-
- StopAnimation(animation);
- }
-
- public void StartAnimation(Animation animation,float speed = 1)
- {
- characterAnimator.SetFloat("AnimationSpeed", (1 / speed));
-
- switch (animation)
- {
- case Animation.Walk:
- characterAnimator.SetBool("isWalking", true);
- break;
- case Animation.Run:
- characterAnimator.SetBool("isRunning", true);
- break;
- case Animation.Sit:
- characterAnimator.SetBool("isSitting", true);
- break;
- case Animation.Jump:
- characterAnimator.SetTrigger("Jump");
- break;
- case Animation.Attack:
- characterAnimator.SetTrigger("Attack");
- break;
- case Animation.Hit:
- characterAnimator.SetTrigger("Hit");
- break;
- default:
- break;
- }
- }
-
- public void StopAnimation(Animation animation)
- {
- characterAnimator.SetFloat("AnimationSpeed", 1f);
- switch (animation)
- {
- case Animation.Walk:
- characterAnimator.SetBool("isWalking", false);
- break;
- case Animation.Run:
- characterAnimator.SetBool("isRunning", false);
- break;
- case Animation.Sit:
- characterAnimator.SetBool("isSitting", false);
- break;
- }
- }
-
- public void respawnCharacter()
- {
- respawnCharacter(CurrentBlock.position);
- }
-
- public void respawnCharacter(Vector3 respawnPosition)
- {
- /* 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 = respawnPosition;
-
- 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);
- }
- }
-
-
-
- #endregion Class Implementation
-
- #region Private Functions
-
- private IEnumerator LerpToBlock(Vector3 target, float time, System.Func<float, float> heightOffset = null)
- {
-
- Vector3 _startPos = transform.position;
- Vector3 _endPos = target;
-
- Vector3 _newPos;
-
- float elapsedTime = 0;
-
-
-
- while (elapsedTime / time < 1)
- {
-
- _newPos = Vector3.Lerp(_startPos, _endPos, (elapsedTime / time));
-
- if (heightOffset != null)
- _newPos.y += heightOffset(elapsedTime / time);
-
- transform.position = _newPos;
-
- yield return new WaitForEndOfFrame();
-
- elapsedTime += Time.deltaTime;
- }
-
- _newPos = _endPos;
- if (heightOffset != null)
- _newPos.y += heightOffset(1);
-
- transform.position = _newPos;
- }
-
- private IEnumerator Rotate(Direction direction, float angles, float time, System.Func<float, float> heightOffset = null)
- {
-
- int RotationDir = 0;
- switch (direction)
- {
- case Direction.Forward:
- RotationDir = 0;
- break;
- case Direction.Left:
- RotationDir = -1;
- break;
- case Direction.Right:
- RotationDir = 1;
- break;
- case Direction.Back:
- RotationDir = 2;
- break;
- }
-
- lastRotation = angles * RotationDir;
-
-
- float elapsedTime = 0;
- float anglePerSecond = (angles * RotationDir) / time;
- Vector3 _startPos = transform.position;
- Vector3 startDirection = transform.forward;
-
- while (elapsedTime < time)
- {
- transform.Rotate(Vector3.up, anglePerSecond * Time.deltaTime);
-
- if (heightOffset != null)
- transform.position = _startPos + Vector3.up * heightOffset(elapsedTime / time);
-
- yield return new WaitForEndOfFrame();
- elapsedTime += Time.deltaTime;
- }
-
- transform.forward = Quaternion.AngleAxis(angles * RotationDir, Vector3.up) * startDirection;
- if (heightOffset != null)
- transform.position = _startPos + Vector3.up * heightOffset(1);
- }
-
-
-
- #endregion Private Functions
-
-
- }
|