118 lines
3.6 KiB
C#
118 lines
3.6 KiB
C#
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<LineRenderer>();
|
|
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<SpringJoint>();
|
|
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);
|
|
}
|
|
|
|
}
|