using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Character : MonoBehaviour
{
public string nextScene;
#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;
public string PickUpTag = "NewBlock";
#endregion Inspector Fields
#region Unity Functions
private void Awake ()
{
//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;
}
#endregion Unity Functions
#region Class Implementation
///
/// Moves one block in specefied direction, Can walk off obstacles
///
/// direction to walk
/// Technically is same as JumpLong(1) but kept seperate to avoid confusion
public void Move (Direction direction)
{
//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;
//else if block down one is walkable
else if (Block.isBlockAtPosition (position + Vector3.down, 1, ~Ignore, out hit) && hit.isWalkable (~Ignore))
moveTo = hit;
//set current block && move
CurrentBlock = moveTo;
transform.position = CurrentBlock.VisualPosition;
}
///
/// Upon collision with a floating block, collect its
/// Upon collision with the end portal, end of level
///
/// name of collided object
void OnTriggerEnter (Collider other)
{
if (other.gameObject.tag == PickUpTag) {
other.gameObject.SetActive (false);
Debug.Log ("You picked up the new coding block " + other.gameObject.name + "!");
}
if (other.gameObject.name == "End Portal") {
other.GetComponent().enabled = false;
Debug.Log ("You finished this level!");
SceneManager.LoadScene(nextScene);
}
}
///
/// Rotates to point in specific direction based on current direction
///
/// Local direction to point
public void Rotate (Direction direction)
{
transform.forward = direction.ToVector (transform);
}
///
/// Jumps in specefied direction, picks between Long Jump and Jumping up
///
/// Direction to Jump
public void Jump (Direction direction)
{
//if there is a block infront JumpUp else LongJump
if (Block.isBlockAtPosition (CurrentBlock.position + direction.ToVector (transform) + Vector3.up, 1, ~Ignore))
JumpUp (direction);
else
JumpLong (direction);
}
#endregion Class Implementation
#region Private Functions
///
/// Jumps up obstacle of specific height. Jumps as high as possible
///
/// Direction of obstacle
/// max height
private void JumpUp (Direction direction, 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;
transform.position = CurrentBlock.VisualPosition;
}
///
/// Long jumps forward a specified distance. Can Jump gaps. Stops at obstruction
///
/// Direction to Jump
/// Max distance
private void JumpLong (Direction direction, 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;
transform.position = CurrentBlock.VisualPosition;
}
#endregion Private Functions
}