119 lines
3.8 KiB
C#
119 lines
3.8 KiB
C#
|
using UnityEngine;
|
||
|
using Player.Information;
|
||
|
namespace Player.Interactions
|
||
|
{
|
||
|
public class GrappleHook : MonoBehaviour
|
||
|
{
|
||
|
[SerializeField] private float maxGrappleThrow;
|
||
|
|
||
|
[SerializeField] private float grappleStrength;
|
||
|
|
||
|
[SerializeField] public float grappledAirControl;
|
||
|
|
||
|
[SerializeField] private GameObject grapplePointPrefab;
|
||
|
|
||
|
public bool grappled;
|
||
|
|
||
|
[SerializeField] private LineRenderer lineRender;
|
||
|
public GameObject reticleMaster;
|
||
|
private GameObject curPointObj;
|
||
|
private Vector3 grapplePos;
|
||
|
|
||
|
private PlayerStats playerStats;
|
||
|
private GameObject reticleClose;
|
||
|
|
||
|
private GameObject reticleOpen;
|
||
|
|
||
|
// Start is called before the first frame update
|
||
|
private void Start()
|
||
|
{
|
||
|
grappled = false;
|
||
|
grapplePos = Vector3.zero;
|
||
|
lineRender.enabled = false;
|
||
|
|
||
|
reticleOpen = reticleMaster.transform.Find("Reticle Open").gameObject;
|
||
|
reticleClose = reticleMaster.transform.Find("Reticle Close").gameObject;
|
||
|
reticleClose.SetActive(false);
|
||
|
|
||
|
playerStats = gameObject.GetComponent<PlayerStats>();
|
||
|
}
|
||
|
|
||
|
// Update is called once per frame
|
||
|
private void Update()
|
||
|
{
|
||
|
if (playerStats.grappleEnabled)
|
||
|
{
|
||
|
if (WouldGrapple())
|
||
|
{
|
||
|
reticleOpen.SetActive(false);
|
||
|
reticleClose.SetActive(true);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
reticleOpen.SetActive(true);
|
||
|
reticleClose.SetActive(false);
|
||
|
}
|
||
|
|
||
|
if ((Input.GetKeyDown(KeyCode.L) || Input.GetMouseButtonDown(0)) ) ShootGrapple();
|
||
|
|
||
|
if ((Input.GetKeyDown(KeyCode.K) || Input.GetMouseButtonUp(0)) ) ReleaseGrapple();
|
||
|
|
||
|
if (grappled)
|
||
|
{
|
||
|
lineRender.SetPosition(0, gameObject.transform.position);
|
||
|
lineRender.SetPosition(1, grapplePos);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public bool WouldGrapple()
|
||
|
{
|
||
|
RaycastHit hit;
|
||
|
if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit,
|
||
|
maxGrappleThrow))
|
||
|
{
|
||
|
TraversalProperties tp = hit.collider.gameObject.GetComponent<TraversalProperties>();
|
||
|
if (tp == null || tp.canGrappleOnto) return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public void ShootGrapple()
|
||
|
{
|
||
|
// perform a raycast from the player's reticle
|
||
|
RaycastHit hit;
|
||
|
if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit,
|
||
|
maxGrappleThrow))
|
||
|
{
|
||
|
//Debug.DrawRay(Camera.main.transform.position, hit.point, Color.green, 5f);
|
||
|
TraversalProperties tp = hit.collider.gameObject.GetComponent<TraversalProperties>();
|
||
|
if (tp == null || tp.canGrappleOnto)
|
||
|
{
|
||
|
grappled = true;
|
||
|
grapplePos = hit.point;
|
||
|
if (curPointObj != null) Destroy(curPointObj);
|
||
|
|
||
|
curPointObj = Instantiate(grapplePointPrefab, hit.point, Quaternion.identity);
|
||
|
lineRender.enabled = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void ReleaseGrapple()
|
||
|
{
|
||
|
grappled = false;
|
||
|
grapplePos = Vector3.zero;
|
||
|
if (curPointObj != null) Destroy(curPointObj);
|
||
|
|
||
|
lineRender.enabled = false;
|
||
|
}
|
||
|
|
||
|
public Vector3 PullForce(Vector3 playerPos)
|
||
|
{
|
||
|
if (!grappled)
|
||
|
return Vector3.zero;
|
||
|
return (grapplePos - playerPos).normalized * grappleStrength;
|
||
|
}
|
||
|
}
|
||
|
}
|