217 lines
6.6 KiB
C#
217 lines
6.6 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class grapplingHookEffect : MonoBehaviour
|
|
{
|
|
[Header ("Main Settings")]
|
|
[Space]
|
|
|
|
[Tooltip ("The speed of the entire effect.")]
|
|
public float Speed = 3f;
|
|
[Tooltip ("The speed of the spiral offset (relative to 'Speed').")]
|
|
public float SpiralSpeed = 4f;
|
|
[Tooltip ("The speed that the end of the line moves to the target point (relative to 'Speed')")]
|
|
public float DistanceSpeed = 2f;
|
|
[Tooltip ("A multiplier for the pull of gravity.")]
|
|
public float Gravity = 0.5f;
|
|
[Tooltip ("The number of points to be drawn by the line renderer. \nUpdates every time the effect is triggered.")]
|
|
public int Segments = 100;
|
|
public LayerMask layerMask;
|
|
|
|
[Space]
|
|
[Header ("Spiral Settings")]
|
|
[Space]
|
|
|
|
[Tooltip ("The strength of the spiral.")]
|
|
public Vector2 Magnitude = Vector2.one;
|
|
[Tooltip ("The number of 'Curve' repetitions per world-unit.")]
|
|
public float Frequency = 0.5f;
|
|
[Tooltip ("The amount the horizontal part of the spiral is offset along 'Curve.' \nIf 'Curve' is a sine wave, 0.25 will result in a perfect spiral.")]
|
|
public float HorizontalOffset = 0.25f;
|
|
|
|
[Space]
|
|
[Header ("Noise Settings")]
|
|
[Space]
|
|
|
|
[Tooltip ("The strength of the noise.")]
|
|
public float Strength = 0.5f;
|
|
[Tooltip ("The scale of the noise samples. \nHigher = smoother.")]
|
|
public float Scale = 0.25f;
|
|
|
|
[Space]
|
|
[Header ("Curves Settings")]
|
|
[Space]
|
|
|
|
[Tooltip ("The base curve that the points will be offset along. \nA sine wave will make it look like a grapple spiral.")]
|
|
public AnimationCurve Curve = new AnimationCurve ();
|
|
[Tooltip ("The strength of the spiral and noise over time.")]
|
|
public AnimationCurve MagnitudeOverTime = new AnimationCurve ();
|
|
[Tooltip ("The strength of the spiral and noise from the start to current end point within a 0 to 1 range.")]
|
|
public AnimationCurve MagnitudeOverDistance = new AnimationCurve ();
|
|
[Tooltip ("The vertical offset applied in world space to the line from the start to current end point within a 0 to 1 range.")]
|
|
public AnimationCurve GravityOverDistance = new AnimationCurve ();
|
|
[Tooltip ("The strength of the gravity over time.")]
|
|
public AnimationCurve GravityOverTime = new AnimationCurve ();
|
|
|
|
[Space]
|
|
[Header ("Debug")]
|
|
[Space]
|
|
|
|
public bool showGizmo;
|
|
public bool grapplingHookEffectActive;
|
|
public bool fixedUpdateActive;
|
|
|
|
[Space]
|
|
[Header ("Components")]
|
|
[Space]
|
|
|
|
public LineRenderer lineRenderer;
|
|
public Transform mainCameraTransform;
|
|
public Transform lineRendererOriginPositionTransform;
|
|
public Transform lineRendererTargetPositionTransform;
|
|
public Transform playerControllerTransform;
|
|
|
|
float scaledTimeOffset = 0f;
|
|
float spiralTimeOffset = 0f;
|
|
float lastGrappleTime = 0f;
|
|
Vector3 grapplePoint;
|
|
RaycastHit hit;
|
|
|
|
Vector3 currentPosition;
|
|
|
|
public void activateGrapplingHookEffect (Vector3 raycastDirection)
|
|
{
|
|
if (Physics.Raycast (mainCameraTransform.position, raycastDirection, out hit, Mathf.Infinity, layerMask)) {
|
|
lineRenderer.enabled = true;
|
|
|
|
DoGrapple (hit.point);
|
|
|
|
grapplingHookEffectActive = true;
|
|
}
|
|
|
|
if (showGizmo) {
|
|
Debug.DrawLine (mainCameraTransform.position, mainCameraTransform.position + raycastDirection * 1000, Color.red, 5);
|
|
}
|
|
}
|
|
|
|
public void activateGrapplingHookEffect ()
|
|
{
|
|
if (Physics.Raycast (mainCameraTransform.position, mainCameraTransform.forward, out hit, Mathf.Infinity, layerMask)) {
|
|
lineRenderer.enabled = true;
|
|
|
|
DoGrapple (hit.point);
|
|
|
|
grapplingHookEffectActive = true;
|
|
}
|
|
}
|
|
|
|
public void deactivateGrapplingHookEffect ()
|
|
{
|
|
grapplingHookEffectActive = false;
|
|
|
|
lineRenderer.enabled = false;
|
|
|
|
for (int i = 0; i < lineRenderer.positionCount; i++) {
|
|
lineRenderer.SetPosition (i, lineRendererOriginPositionTransform.position);
|
|
}
|
|
}
|
|
|
|
public void DoGrapple (Vector3 newWrapplePoint)
|
|
{
|
|
grapplePoint = newWrapplePoint;
|
|
|
|
scaledTimeOffset = spiralTimeOffset = 0f;
|
|
if (lineRenderer.positionCount != Segments)
|
|
lineRenderer.positionCount = Segments;
|
|
|
|
lastGrappleTime = Time.time * 10f;
|
|
}
|
|
|
|
public void setFixedUpdateActiveState (bool state)
|
|
{
|
|
fixedUpdateActive = state;
|
|
}
|
|
|
|
void Update ()
|
|
{
|
|
if (!fixedUpdateActive) {
|
|
updateEffect ();
|
|
}
|
|
}
|
|
|
|
void FixedUpdate ()
|
|
{
|
|
if (fixedUpdateActive) {
|
|
updateEffect ();
|
|
}
|
|
}
|
|
|
|
void updateEffect ()
|
|
{
|
|
if (grapplingHookEffectActive) {
|
|
if (lineRendererTargetPositionTransform == null) {
|
|
deactivateGrapplingHookEffect ();
|
|
|
|
return;
|
|
}
|
|
|
|
grapplePoint = lineRendererTargetPositionTransform.position;
|
|
|
|
lineRendererOriginPositionTransform.LookAt (grapplePoint);
|
|
var difference = grapplePoint - lineRendererOriginPositionTransform.position;
|
|
var direction = difference.normalized;
|
|
var distanceMultiplier = Mathf.Clamp01 (scaledTimeOffset * DistanceSpeed);
|
|
var distance = difference.magnitude * distanceMultiplier;
|
|
|
|
scaledTimeOffset += Speed * Time.deltaTime;
|
|
|
|
if (distanceMultiplier < 1f) {
|
|
spiralTimeOffset += Speed * SpiralSpeed * Time.deltaTime;
|
|
}
|
|
|
|
for (int i = 0; i < lineRenderer.positionCount; i++) {
|
|
var t = (float)i / lineRenderer.positionCount;
|
|
currentPosition = lineRendererOriginPositionTransform.position;
|
|
var forwardOffset = direction * (t * distance);
|
|
currentPosition += forwardOffset;
|
|
|
|
var curveSamplePosition = forwardOffset.magnitude * Frequency - spiralTimeOffset;
|
|
|
|
var verticalOffset = lineRendererOriginPositionTransform.up * Curve.Evaluate (curveSamplePosition);
|
|
var horizontalOffset = lineRendererOriginPositionTransform.right * Curve.Evaluate (curveSamplePosition + HorizontalOffset);
|
|
|
|
verticalOffset *= Magnitude.y;
|
|
horizontalOffset *= Magnitude.x;
|
|
|
|
var noiseSamplePosition = -t * Scale + scaledTimeOffset + lastGrappleTime;
|
|
verticalOffset += lineRendererOriginPositionTransform.up * ((Mathf.PerlinNoise (0f, noiseSamplePosition) - 0.5f) * 2f * Strength);
|
|
horizontalOffset += lineRendererOriginPositionTransform.right * ((Mathf.PerlinNoise (noiseSamplePosition, 0f) - 0.5f) * 2f * Strength);
|
|
|
|
var magnitude = MagnitudeOverTime.Evaluate (scaledTimeOffset) * MagnitudeOverDistance.Evaluate (t);
|
|
verticalOffset *= magnitude;
|
|
horizontalOffset *= magnitude;
|
|
|
|
currentPosition += verticalOffset;
|
|
currentPosition += horizontalOffset;
|
|
|
|
currentPosition += Vector3.up * (GravityOverDistance.Evaluate (t) * GravityOverTime.Evaluate (scaledTimeOffset) * Gravity);
|
|
|
|
lineRenderer.SetPosition (i, currentPosition);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void changeLineRendererOriginPositionParent (Transform newParent)
|
|
{
|
|
lineRendererOriginPositionTransform.SetParent (newParent);
|
|
|
|
lineRendererOriginPositionTransform.localPosition = Vector3.zero;
|
|
}
|
|
|
|
public void setNewlineRendererTargetPositionTransform (Transform newObject)
|
|
{
|
|
lineRendererTargetPositionTransform = newObject;
|
|
}
|
|
}
|