using System.Collections;
|
|
using UnityEngine;
|
|
|
|
[CreateAssetMenu(menuName = "Major Project/Pick Ups/HookShot Block")]
|
|
[System.Serializable]
|
|
public class HookShot : LogicBlock
|
|
{
|
|
[SerializeField]
|
|
[Header("Direction to shoot in")]
|
|
private Direction Direction;
|
|
|
|
[SerializeField]
|
|
private string ResourceName;
|
|
|
|
[SerializeField]
|
|
private float ShotSpeed = 1;
|
|
|
|
public override Block GetEndBlock(Block startBlock, Transform transform, LayerMask layerMask)
|
|
{
|
|
//setting up variables
|
|
Vector3 position; // position wanted
|
|
Block hit; //output of block detection
|
|
Block retVal = startBlock; //block we'll actually move to
|
|
|
|
//Check blocks in front until we hit an obstruction or went the distance
|
|
for (int i = 1; i <= 30; i++)
|
|
{
|
|
//Next position to MoveTo
|
|
position = startBlock.position + (Direction.ToVector(transform) * i);
|
|
|
|
//if position is off the screen there is nothing to hit
|
|
if (!Block.isPositionVisible(position))
|
|
return startBlock;
|
|
|
|
//if hit player return block they are standing on
|
|
if (Block.isBlockAtPosition(position, 1, layerMask, out hit)) {
|
|
if (hit.CurrentPlayer != null)
|
|
return hit;
|
|
}
|
|
|
|
//if block block paths return block infront of it
|
|
if (Block.isBlockAtPosition(position + Vector3.up,1,layerMask))
|
|
{
|
|
return Block.GetOrCreateBlockAtPosition(position - Direction.ToVector(transform), 1, layerMask);
|
|
}
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
protected override IEnumerator BlockLogic(Character player, float animationTime, bool useBlockDirection = false)
|
|
{
|
|
Block hitBlock = GetEndBlock(player.CurrentBlock, player.transform, ~player.Ignore);
|
|
|
|
if (hitBlock == player.CurrentBlock)
|
|
yield break;
|
|
|
|
GameObject shot = GameObject.CreatePrimitive(PrimitiveType.Sphere);
|
|
shot.transform.localScale = Vector3.one * 0.33f;
|
|
yield return player.StartCoroutine(lerpShot(shot.transform, player.transform.position, hitBlock.VisualPosition,ShotSpeed));
|
|
Destroy(shot);
|
|
|
|
if (hitBlock.CurrentPlayer != null)
|
|
{
|
|
Block pullBlock = Block.GetOrCreateBlockAtPosition(player.CurrentBlock.position + Direction.ToVector(player.transform), 1, ~player.Ignore);
|
|
yield return player.StartCoroutine(hitBlock.CurrentPlayer.MoveToBlock(pullBlock, Character.Animation.Hit, ShotSpeed));
|
|
}
|
|
else
|
|
{
|
|
yield return player.StartCoroutine(player.MoveToBlock(hitBlock, Character.Animation.Jump, ShotSpeed));
|
|
}
|
|
}
|
|
|
|
private IEnumerator lerpShot(Transform target, Vector3 startPosition,Vector3 endPosition, float time)
|
|
{
|
|
float elapsedTime = 0;
|
|
|
|
while (elapsedTime < time)
|
|
{
|
|
target.transform.position = Vector3.Lerp(startPosition, endPosition, elapsedTime / time);
|
|
|
|
yield return new WaitForEndOfFrame();
|
|
elapsedTime += Time.deltaTime;
|
|
}
|
|
target.position = endPosition;
|
|
}
|
|
|
|
public override void CopyToken(BlockToken token)
|
|
{
|
|
base.CopyToken(token);
|
|
Direction = ((HookShotToken)token).Direction;
|
|
ResourceName = ((HookShotToken)token).ResourceName;
|
|
ShotSpeed = ((HookShotToken)token).ShotSpeed;
|
|
}
|
|
|
|
public override BlockToken ToToken(BlockToken token = null)
|
|
{
|
|
if (token == null)
|
|
token = new HookShotToken(this);
|
|
|
|
HookShotToken retVal = (HookShotToken)base.ToToken(token);
|
|
retVal.Direction = Direction;
|
|
retVal.ResourceName = ResourceName;
|
|
retVal.ShotSpeed = ShotSpeed;
|
|
|
|
return retVal;
|
|
}
|
|
}
|
|
|
|
[System.Serializable]
|
|
public class HookShotToken : BlockToken
|
|
{
|
|
public Direction Direction;
|
|
public string ResourceName;
|
|
public float ShotSpeed;
|
|
|
|
public HookShotToken(LogicBlock block) : base(block) { }
|
|
}
|