using System.Collections; using UnityEngine; public class GrappleGun : Tool { [Header("Grapple Gun Parameters")] public float range; public float hookStickTime; public GameObject hook; bool isMoving = false; bool stuckInTarget = false; private Vector3 hookBaseLocation; private Transform hookParent; private void Start() { hookBaseLocation = hook.transform.localPosition; hookParent = hook.transform.parent; } IEnumerator GoToTarget(Vector3 target) { GameManager.Instance.PlayerController.SetCharacterControl(false); isMoving = true; Vector3 startPosition = hook.transform.position; float elapsedTime = 0f; while (elapsedTime < hookStickTime) { float t = elapsedTime / hookStickTime; hook.transform.position = Vector3.Lerp(startPosition, target, t); elapsedTime += Time.deltaTime; yield return null; } // Ensure final position is exact hook.transform.position = target; hook.transform.parent = null; isMoving = false; stuckInTarget = true; StartCoroutine(MovePlayerToTarget(target)); } IEnumerator MovePlayerToTarget(Vector3 target) { Transform player = GameManager.Instance.PlayerController.transform; Vector3 startPosition = player.position; float elapsedTime = 0f; while (elapsedTime < hookStickTime) { float t = elapsedTime / hookStickTime; player.position = Vector3.Lerp(startPosition, target, t); elapsedTime += Time.deltaTime; yield return null; } // Ensure final position is exact player.position = target; stuckInTarget = false; hook.transform.parent = hookParent; hook.transform.localPosition = hookBaseLocation; isMoving = false; stuckInTarget = false; GameManager.Instance.PlayerController.SetCharacterControl(true); } IEnumerator ShootAndMiss() { GameManager.Instance.PlayerController.SetCharacterControl(false); isMoving = true; // move to edge of range and don't stick anywhere Vector3 startPosition = hook.transform.position; Vector3 target = transform.position + (transform.forward * range); float elapsedTime = 0f; while (elapsedTime < hookStickTime) { float t = elapsedTime / hookStickTime; hook.transform.position = Vector3.Lerp(startPosition, target, t); elapsedTime += Time.deltaTime; yield return null; } hook.transform.localPosition = hookBaseLocation; isMoving = false; stuckInTarget = false; GameManager.Instance.PlayerController.SetCharacterControl(true); } public override void Use() { if (stuckInTarget || isMoving) { StopAllCoroutines(); hook.transform.parent = hookParent; hook.transform.localPosition = hookBaseLocation; isMoving = false; stuckInTarget = false; GameManager.Instance.PlayerController.SetCharacterControl(true); } else { RaycastHit hit; if (Physics.Raycast(transform.position, transform.forward, out hit, range)) { StartCoroutine(GoToTarget(hit.point)); } else { StartCoroutine(ShootAndMiss()); } } } public override void UseAlt() { throw new System.NotImplementedException(); } }