using System.Collections; using System.Collections.Generic; 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); //Debug.Log("hookshot: " + hitBlock.position, hitBlock.gameObject); if (hitBlock == player.CurrentBlock) yield break; //Debug.Log("Instantiating shot"); 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) { } }