using System.Collections; using System.Collections.Generic; using UnityEngine; public class GrappleHook : MonoBehaviour { [SerializeField] private float maxGrappleDist = 200; [SerializeField] private float grappleExtendSpeed = 20; [SerializeField] private LayerMask grappleableLayer; [SerializeField] private Transform gunPos; private Vector3 hitPosLocal; private SpringJoint joint; private LineRenderer lr; RaycastHit hit; private bool grappled = false; private Vector3 currGrappleEndPos; [SerializeField] private Transform hitMarker; //TODO obj this should be a sprite or something idk // Start is called before the first frame update void Start() { lr = gameObject.GetComponentInChildren(); lr.enabled = false; hitMarker.gameObject.SetActive(false); } // Update is called once per frame void Update() { if(Input.GetMouseButtonUp(0)){//TODO Change to correct input system EndGrapple(); } if(grappled){ DrawRope(Time.deltaTime); if(Input.GetMouseButtonDown(1)){ joint.minDistance = 0f; joint.maxDistance = 0f; } return; } Aim(); } private void Aim(){ Vector3 mousePos; mousePos = Input.mousePosition; mousePos.z = Mathf.Abs(Camera.main.transform.position.z); mousePos = Camera.main.ScreenToWorldPoint(mousePos); Vector3 aimDir = (mousePos - gameObject.transform.position).normalized; if(!hitMarker.gameObject.activeSelf)hitMarker.gameObject.SetActive(true); hitMarker.position = gameObject.transform.position + aimDir * maxGrappleDist; if(Physics.Raycast(gameObject.transform.position, aimDir, out hit, maxGrappleDist, grappleableLayer)){ hitMarker.position = hit.point; if(Input.GetMouseButtonDown(0)){ StartGrapple(hit); } } } private void DrawRope(float deltaTime){ // TODO animate a wiggle on the rope if(!grappled)return; lr.SetPosition(0, gunPos.position); Vector3 endPoint; if(hit.rigidbody != null){ endPoint = hit.transform.TransformPoint(hitPosLocal); }else{ endPoint = hit.point; } currGrappleEndPos = Vector3.Lerp(currGrappleEndPos, endPoint, deltaTime * grappleExtendSpeed); lr.SetPosition(1, currGrappleEndPos); if(!lr.enabled)lr.enabled = true; } private void StartGrapple(RaycastHit hit){ grappled = true; //Display hitMarker.gameObject.SetActive(false); joint = gameObject.AddComponent(); joint.anchor = transform.InverseTransformPoint(gunPos.position); joint.autoConfigureConnectedAnchor = false; joint.maxDistance = hit.distance * 0.8f; joint.minDistance = hit.distance * 0.25f; if(hit.rigidbody != null){ Rigidbody hitRb = hit.rigidbody; joint.connectedBody = hitRb; joint.connectedAnchor = hit.transform.InverseTransformPoint(hit.point); hitPosLocal = hit.transform.InverseTransformPoint(hit.point); }else{ joint.connectedAnchor = hit.point; } joint.spring = 4.5f * 5f; joint.damper = 7f; joint.massScale = 4.5f; currGrappleEndPos = transform.position; } private void EndGrapple(){ grappled = false; lr.enabled = false; Destroy(joint); } }