change: rebuilt grapple
This commit is contained in:
@@ -40,6 +40,7 @@ namespace NodeCanvas.Tasks.Actions {
|
||||
private Vector3 originalDirection;
|
||||
|
||||
public float breakAtDistance;
|
||||
[Tooltip("The dot product between the current direction to the grapple point, and the direction to the grapple point when started. Starts at 1 and gradually gets closer to -1, with 0 being 90 degrees perpendicular.")]
|
||||
public float breakAtDotProduct;
|
||||
|
||||
private float currentSpeed;
|
||||
@@ -53,6 +54,8 @@ namespace NodeCanvas.Tasks.Actions {
|
||||
private float gizmoVertValue;
|
||||
|
||||
private Transform camera;
|
||||
|
||||
Vector3 smoothedSwingDirection;
|
||||
|
||||
private float referenceSpeed;
|
||||
|
||||
@@ -62,11 +65,6 @@ namespace NodeCanvas.Tasks.Actions {
|
||||
//Use for initialization. This is called only once in the lifetime of the task.
|
||||
//Return null if init was successfull. Return an error string otherwise
|
||||
protected override string OnInit(){
|
||||
DebugOverlayDrawer.AddOnOverlay("Grapple", "Composite Swing Direction", Vector3.zero);
|
||||
DebugOverlayDrawer.AddOnOverlay("Grapple", "Target Swing Direction", Vector3.zero);
|
||||
DebugOverlayDrawer.AddOnOverlay("Grapple", "Smoothed Input", Vector3.zero);
|
||||
|
||||
|
||||
return null;
|
||||
|
||||
|
||||
@@ -84,74 +82,110 @@ namespace NodeCanvas.Tasks.Actions {
|
||||
// Get the current move direction
|
||||
velocityOnStart = agent.outputMoveDirection;
|
||||
|
||||
// For setting finalDirection's initial value, first compose the swing variables one-time
|
||||
Vector3 velocityWhenMoving = CalculateSwingDirections(Vector3.Distance(agent.transform.position, grapplePoint.value), directionOnStart);
|
||||
|
||||
// Lerp the initial direction more towards the point of the grapple and less towards current momentum if not moving fast
|
||||
finalDirection = Vector3.Lerp(velocityOnStart, directionOnStart, velocityOnStart.magnitude / 10f);
|
||||
finalDirection = Vector3.Lerp(velocityOnStart, velocityWhenMoving, velocityOnStart.magnitude / 2f); // This isn't working
|
||||
|
||||
// Set the intial swing direction to the same thing, so it starts swinging withing snapping on start
|
||||
smoothedSwingDirection = finalDirection.Flatten(null, .4f, null);
|
||||
|
||||
startTime = Time.time;
|
||||
currentSpeed = pullSpeedCurve.value[0].value * pullSpeedRange.value.y;
|
||||
|
||||
smoothedInput = agent.GetComponent<CharacterController>().velocity.normalized.Flatten(null, 0f, 0f);
|
||||
// smoothedInput = agent.GetComponent<CharacterController>().velocity.normalized.Flatten(null, 0f, 0f);
|
||||
smoothedInput = Vector3.zero;
|
||||
}
|
||||
|
||||
//Called once per frame while the action is active.
|
||||
protected override void OnUpdate(){
|
||||
// Get direction to the point
|
||||
agent.outputMoveDirection = Vector3.MoveTowards(agent.outputMoveDirection, Vector3.zero, .5f);
|
||||
|
||||
// Basic variables, direction to point and current distnace
|
||||
Vector3 directionToPoint = agent.transform.position.DirectionTo(grapplePoint.value);
|
||||
float currentDist = Vector3.Distance(agent.transform.position, grapplePoint.value);
|
||||
|
||||
// Calculate input
|
||||
Vector2 rawInput = agent.GetComponent<PlayerControls>().rawMoveInput;
|
||||
Vector3 input = new(rawInput.x, rawInput.y, 0f);
|
||||
|
||||
smoothedInput = Vector3.SmoothDamp(smoothedInput, input, ref smoothedInputRefVelocity, 2);
|
||||
smoothedInput = Vector3.SmoothDamp(smoothedInput, input, ref smoothedInputRefVelocity, 1f);
|
||||
DebugOverlayDrawer.ChangeValue("Grapple", "Smoothed Input", smoothedInput.ToString());
|
||||
|
||||
// Change input handling based on position
|
||||
if (directionToPoint.y < 0) {
|
||||
|
||||
} else {
|
||||
}
|
||||
|
||||
// Create the distance variables
|
||||
float currentDist = Vector3.Distance(agent.transform.position, grapplePoint.value);
|
||||
// The swing angle needs to change for the downwards swing, based on distance to the ground
|
||||
Physics.Raycast(agent.transform.position, Vector3.down, out RaycastHit hit);
|
||||
float distanceToGround = hit.distance;
|
||||
|
||||
float downwardsSwingAngle = Mathf.Lerp(30, 100, distanceToGround / 20f);
|
||||
|
||||
// Altered swing angle based on distance to the grapple point, used to keep the player not too close or far
|
||||
|
||||
float inwardsAngle = Mathf.Lerp(0f, -60f, currentDist / -15f);
|
||||
float outwardsAngle = Mathf.Lerp(0f, -60f, currentDist / 15f);
|
||||
float outputAngle = inwardsAngle + outwardsAngle;
|
||||
|
||||
DebugOverlayDrawer.ChangeValue("Grapple", "Output Angle", outputAngle.ToString() + $"({inwardsAngle.ToString()} + {outwardsAngle.ToString()})");
|
||||
|
||||
|
||||
// Calculate the swing direction.
|
||||
// Vector3 swingDirection = Quaternion.LookRotation(smoothedInput) * directionToPoint * smoothedInput.magnitude; // Old
|
||||
Vector3 sidewaysSwingAngle = Quaternion.AngleAxis(90f, Vector3.up) * directionToPoint;
|
||||
Vector3 upwardsSwingAngle = Quaternion.AngleAxis(-90f, Vector3.right) * directionToPoint;
|
||||
// Vector3 downwardsSwingAngle = Quaternion.AngleAxis(90f, Vector3.right) * directionToPoint; // why not just use upwards but negative based on input on Y
|
||||
Vector3 pointDirectionXZStable = agent.transform.position.DirectionTo(grapplePoint.value.Flatten(null, agent.transform.position.y));
|
||||
Vector3 rightSwingDirectin = Quaternion.AngleAxis(100f + outputAngle, Vector3.up) * pointDirectionXZStable; // Working
|
||||
Vector3 leftSwingDirectin = Quaternion.AngleAxis(-100f - outputAngle, Vector3.up) * pointDirectionXZStable; // Working
|
||||
Vector3 upwardsSwingDirection = Quaternion.AngleAxis(-140f - outputAngle, Quaternion.LookRotation(directionToPoint) * Vector3.right) * directionToPoint; // Working
|
||||
Vector3 downwardsSwingDirection = Quaternion.AngleAxis(downwardsSwingAngle, Quaternion.LookRotation(directionOnStart) * Vector3.right) * directionToPoint; // WORKING NOW!! Note: this has to rotate by directionOnStart because else it just moves towards the point
|
||||
|
||||
// Create the composite swing direction and the target swing direction
|
||||
// The composite is the output while the target is the one used in calculating
|
||||
Vector3 compositeSwingDirection;
|
||||
// Get the target swing direction. This is the direction "around" the point based on context
|
||||
Vector3 targetSwingDirection;
|
||||
|
||||
// if (directionToPoint.y > 0) {
|
||||
DebugOverlayDrawer.ChangeValue("Grapple", "Target Swing Direction", Mathf.Abs((smoothedInput.y + 1f) / 2).ToString());
|
||||
Vector3 swingAngleAbovePoint = -upwardsSwingAngle;
|
||||
|
||||
if (Mathf.Abs(smoothedInput.y) > .01f){
|
||||
swingAngleAbovePoint = Vector3.Slerp(-upwardsSwingAngle, upwardsSwingAngle, Mathf.Abs((smoothedInput.y + 1f) / 2));
|
||||
// Start with up and down
|
||||
Vector3 yAxisTargetDirection;
|
||||
|
||||
if (Vector3.Dot(-directionOnStart, directionToPoint) > 0) { // More than 90 degrees from the start angle, just start going forward from the swing
|
||||
targetSwingDirection = finalDirection;
|
||||
} else {
|
||||
if (Mathf.Abs(input.y) > 0.1f) { // Input exists on up and down, switch direction based on input
|
||||
yAxisTargetDirection = Vector3.Slerp(upwardsSwingDirection, downwardsSwingDirection, Mathf.Abs((input.y - 1f) / 2f));
|
||||
} else { // No input on up/down controller, so swing relative to the point
|
||||
if (directionToPoint.y < 0) { // Since you're under the point swing downwards
|
||||
yAxisTargetDirection = downwardsSwingDirection;
|
||||
} else { // Since you're over the point, swing upwards
|
||||
yAxisTargetDirection = upwardsSwingDirection;
|
||||
}
|
||||
}
|
||||
Vector3 axisFromInput = Vector3.zero;
|
||||
|
||||
if (smoothedInput.x > 0) {
|
||||
axisFromInput = Vector3.Slerp(swingAngleAbovePoint, sidewaysSwingAngle, smoothedInput.x);
|
||||
|
||||
if (directionToPoint.y > -.5f) {
|
||||
// yAxisTargetDirection += Vector3.up * 4f; // This works but it's making downward motion not work
|
||||
}
|
||||
|
||||
if (smoothedInput.x < 0) {
|
||||
axisFromInput = Vector3.Slerp(swingAngleAbovePoint, -sidewaysSwingAngle, Mathf.Abs(smoothedInput.x));
|
||||
}
|
||||
targetSwingDirection = yAxisTargetDirection * Mathf.Abs((input.y));
|
||||
|
||||
compositeSwingDirection = Vector3.Slerp(swingAngleAbovePoint, axisFromInput, smoothedInput.x);
|
||||
// } else {
|
||||
// compositeSwingDirection = Vector3.Slerp(upwardsSwingAngle, sidewaysSwingAngle, smoothedInput.magnitude);
|
||||
// }
|
||||
if (Mathf.Abs(input.x) > 0.1f) {
|
||||
Vector3 xAxisTargetDirection = Vector3.Lerp(rightSwingDirectin, leftSwingDirectin, Mathf.Abs((input.x - 1f) / 2f));
|
||||
targetSwingDirection = Vector3.Slerp(targetSwingDirection, xAxisTargetDirection, Mathf.Abs((input.x)));
|
||||
// targetSwingDirection = xAxisTargetDirection;
|
||||
DebugOverlayDrawer.ChangeValue("Grapple", "LR Input Dot", Mathf.Abs((input.x - 1f) / 2f).ToString());
|
||||
}
|
||||
|
||||
targetSwingDirection = targetSwingDirection.normalized;
|
||||
}
|
||||
|
||||
// Smooth it, but don't smooth it as well if the dot product between the new direction and current direction are too large
|
||||
float newDirDot = Vector3.Dot(smoothedSwingDirection, targetSwingDirection);
|
||||
newDirDot = (newDirDot + 1f) / 2f;
|
||||
|
||||
smoothedSwingDirection = Vector3.Slerp(smoothedSwingDirection, targetSwingDirection, 2f * Time.deltaTime * newDirDot);
|
||||
|
||||
// DebugOverlayDrawer.ChangeValue("Grapple", "Downwards Swing Angle", downwardsSwingDirection.ToString());
|
||||
// DebugOverlayDrawer.ChangeValue("Grapple", "Upwards Swing Angle", upwardsSwingDirection.ToString());
|
||||
// DebugOverlayDrawer.ChangeValue("Grapple", "Right Swing Angle", rightSwingDirectin.ToString());
|
||||
// DebugOverlayDrawer.ChangeValue("Grapple", "Left Swing Angle", leftSwingDirectin.ToString());
|
||||
|
||||
// Some math for getting the Y
|
||||
yChangeMultipler = Mathf.Lerp(yChangeMultipler, 0f, elapsedTime * .5f); // Starts at 1 so that the player has more ability to change height on start of swing, then smooths to zero
|
||||
|
||||
DebugOverlayDrawer.ChangeValue("Grapple", "Composite Swing Direction", compositeSwingDirection.ToString());
|
||||
Debug.Log(Vector3.Dot(directionToPoint, Vector3.down));
|
||||
DebugOverlayDrawer.ChangeValue("Grapple", "Composite Swing Direction", smoothedSwingDirection.ToString());
|
||||
|
||||
// Speed
|
||||
float evaluatedSpeed = pullSpeedCurve.value.Evaluate(Mathf.Clamp((Time.time - startTime) / 6f, 0f, Mathf.Infinity));
|
||||
@@ -177,31 +211,92 @@ namespace NodeCanvas.Tasks.Actions {
|
||||
// Soften the speed changes
|
||||
currentSpeed = Mathf.Lerp(currentSpeed, speedAgainstCurve, 10f * Time.deltaTime);
|
||||
|
||||
// Test
|
||||
finalDirection = Vector3.Slerp(finalDirection, smoothedSwingDirection, (elapsedTime / 1f) + Mathf.Max(0f, smoothedInput.magnitude)); // Set to smoothedSwingDirection when done testing
|
||||
|
||||
// Gizmos
|
||||
gizmoVertValue = finalDirection.y;
|
||||
gizmosSmoothedInput = smoothedInput;
|
||||
gizmoPointDirection = directionToPoint;
|
||||
gizmoSwingDirection = swingAngleAbovePoint;
|
||||
gizmoPointDirection = targetSwingDirection;
|
||||
gizmoSwingDirection = smoothedSwingDirection; // Set to smoothedSwingDirection when done testing
|
||||
gizmoFinalDirection = finalDirection;
|
||||
|
||||
//Test
|
||||
finalDirection = gizmoSwingDirection;
|
||||
|
||||
|
||||
agent.SetNewDirection(finalDirection.Flatten(null, 0));
|
||||
agent.SetNewDirection(Vector3.Lerp(agent.additionalMoveDirection, finalDirection.Flatten(null, 0), 1f * Time.deltaTime));
|
||||
agent.SetNewGravity(finalDirection.y);
|
||||
agent.SmoothToSpeed(0f, 1f * Time.deltaTime, out referenceSpeed);
|
||||
agent.SmoothToSpeed(30f, 20f * Time.deltaTime, out referenceSpeed);
|
||||
|
||||
// agent.SmoothToDirection(finalDirection.Flatten(null, 0).normalized * evaluatedSpeed, 1f * Time.deltaTime, out referenceDirection);
|
||||
// agent.SmoothToGravitation(finalDirection.y, 1f, out referenceGravity);
|
||||
|
||||
if (Vector3.Dot(directionOnStart, directionToPoint.normalized) < breakAtDotProduct) {
|
||||
// EndAction(true);
|
||||
// Calculate dot products for using to end the action
|
||||
float xzDot = Vector3.Dot(directionOnStart.Flatten(null, 0f), directionToPoint.normalized.Flatten(null, 0f));
|
||||
float yDot = Vector3.Dot(directionOnStart.Flatten(0f, null, 0f), directionToPoint.normalized.Flatten(0f, null, 0f));
|
||||
|
||||
if (xzDot < breakAtDotProduct || yDot < -.9) { // TODO: Change .8 to a variable
|
||||
EndAction(true);
|
||||
} else if (currentDist < breakAtDistance) {
|
||||
EndAction(true);
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 CalculateSwingDirections(float currentDist, Vector3 directionToPoint){
|
||||
// Get input
|
||||
Vector2 rawInput = agent.GetComponent<PlayerControls>().rawMoveInput;
|
||||
Vector3 input = new(rawInput.x, rawInput.y, 0f);
|
||||
|
||||
// The swing angle needs to change for the downwards swing, based on distance to the ground
|
||||
Physics.Raycast(agent.transform.position, Vector3.down, out RaycastHit hit);
|
||||
float distanceToGround = hit.distance;
|
||||
|
||||
float downwardsSwingAngle = Mathf.Lerp(30, 100, distanceToGround / 20f);
|
||||
|
||||
// Altered swing angle based on distance to the grapple point, used to keep the player not too close or far
|
||||
|
||||
float inwardsAngle = Mathf.Lerp(0f, -60f, currentDist / -15f);
|
||||
float outwardsAngle = Mathf.Lerp(0f, -60f, currentDist / 15f);
|
||||
float outputAngle = inwardsAngle + outwardsAngle;
|
||||
|
||||
DebugOverlayDrawer.ChangeValue("Grapple", "Output Angle", outputAngle.ToString() + $"({inwardsAngle.ToString()} + {outwardsAngle.ToString()})");
|
||||
|
||||
Vector3 pointDirectionXZStable = agent.transform.position.DirectionTo(grapplePoint.value.Flatten(null, agent.transform.position.y));
|
||||
Vector3 rightSwingDirectin = Quaternion.AngleAxis(100f + outputAngle, Vector3.up) * pointDirectionXZStable; // Working
|
||||
Vector3 leftSwingDirectin = Quaternion.AngleAxis(-100f - outputAngle, Vector3.up) * pointDirectionXZStable; // Working
|
||||
Vector3 upwardsSwingDirection = Quaternion.AngleAxis(-140f - outputAngle, Quaternion.LookRotation(directionToPoint) * Vector3.right) * directionToPoint; // Working
|
||||
Vector3 downwardsSwingDirection = Quaternion.AngleAxis(downwardsSwingAngle, Quaternion.LookRotation(directionOnStart) * Vector3.right) * directionToPoint; // WORKING NOW!! Note: this has to rotate by directionOnStart because else it just moves towards the point
|
||||
|
||||
// Get the target swing direction. This is the direction "around" the point based on context
|
||||
Vector3 targetSwingDirection;
|
||||
|
||||
// Start with up and down
|
||||
Vector3 yAxisTargetDirection;
|
||||
|
||||
if (Mathf.Abs(input.y) > 0.1f) { // Input exists on up and down, switch direction based on input
|
||||
yAxisTargetDirection = Vector3.Slerp(upwardsSwingDirection, downwardsSwingDirection, Mathf.Abs((input.y - 1f) / 2f));
|
||||
} else { // No input on up/down controller, so swing relative to the point
|
||||
if (directionToPoint.y < 0) { // Since you're under the point swing downwards
|
||||
yAxisTargetDirection = downwardsSwingDirection;
|
||||
} else { // Since you're over the point, swing upwards
|
||||
yAxisTargetDirection = downwardsSwingDirection;
|
||||
}
|
||||
}
|
||||
|
||||
if (directionToPoint.y > -.5f) {
|
||||
// yAxisTargetDirection += Vector3.up * 4f; // This works but it's making downward motion not work
|
||||
}
|
||||
|
||||
targetSwingDirection = yAxisTargetDirection * Mathf.Abs((input.y));
|
||||
|
||||
if (Mathf.Abs(input.x) > 0.1f) {
|
||||
Vector3 xAxisTargetDirection = Vector3.Lerp(rightSwingDirectin, leftSwingDirectin, Mathf.Abs((input.x - 1f) / 2f));
|
||||
targetSwingDirection = Vector3.Slerp(targetSwingDirection, xAxisTargetDirection, Mathf.Abs((input.x)));
|
||||
// targetSwingDirection = xAxisTargetDirection;
|
||||
DebugOverlayDrawer.ChangeValue("Grapple", "LR Input Dot", Mathf.Abs((input.x - 1f) / 2f).ToString());
|
||||
}
|
||||
|
||||
return targetSwingDirection.normalized;
|
||||
}
|
||||
|
||||
public void DrawGrappleGizmo(){
|
||||
// Destination gizmos
|
||||
using (Draw.WithColor(Color.blue)){
|
||||
@@ -234,7 +329,7 @@ namespace NodeCanvas.Tasks.Actions {
|
||||
using (Draw.WithColor(dirColor)) {
|
||||
float pointLength = 1.2f;
|
||||
Vector3 pointStart = agent.transform.position + Vector3.up * .2f;
|
||||
Vector3 pointDir = pointStart + gizmoPointDirection.normalized * pointLength;
|
||||
Vector3 pointDir = grapplePoint.value;
|
||||
Draw.DashedLine(pointStart, pointDir, .2f, .2f);
|
||||
Draw.ArrowheadArc(pointStart, gizmoPointDirection.normalized, pointLength, 15f);
|
||||
Draw.Label2D(pointDir + Vector3.up * .4f, "Grapple Point Direction");
|
||||
|
||||
@@ -140,10 +140,8 @@ namespace Reset.Core.Tools{
|
||||
try {
|
||||
AddOnOverlay(pageName, sourceName);
|
||||
Instance.values[$"{pageName}/{sourceName}"].text = newValue;
|
||||
throw;
|
||||
} catch (Exception exception) {
|
||||
Debug.LogError($"Failed to both update an existing or create a new debug overlay: {exception.Message}" );
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using NUnit.Framework.Internal;
|
||||
using UnityEngine;
|
||||
using ParadoxNotion.Design;
|
||||
@@ -7,8 +6,6 @@ using Sirenix.OdinInspector;
|
||||
using UnityEditor.Rendering;
|
||||
using UnityEngine.Serialization;
|
||||
using Quaternion = UnityEngine.Quaternion;
|
||||
using Vector2 = UnityEngine.Vector2;
|
||||
using Vector3 = UnityEngine.Vector3;
|
||||
|
||||
public enum PlayerFacingDirection{
|
||||
TowardsTarget = 0,
|
||||
@@ -72,7 +69,7 @@ namespace Reset.Units{
|
||||
[ShowInInspector, ReadOnly] private float outputSpeed;
|
||||
[ShowInInspector, ReadOnly] private float additionalSpeed;
|
||||
[ShowInInspector, ReadOnly] public Vector3 outputMoveDirection;
|
||||
[ShowInInspector, ReadOnly] private Vector3 additionalMoveDirection;
|
||||
[ShowInInspector, ReadOnly] public Vector3 additionalMoveDirection;
|
||||
[ShowInInspector, ReadOnly] private Quaternion outputRotation;
|
||||
[ShowInInspector, ReadOnly] private Quaternion specifiedRotation;
|
||||
[ShowInInspector, ReadOnly] private float outputRotationSpeed;
|
||||
@@ -138,7 +135,7 @@ namespace Reset.Units{
|
||||
}
|
||||
|
||||
public void SmoothToSpeed(float desiredSpeed, float smoothing, out float referenceSpeed){
|
||||
additionalSpeed = Mathf.Lerp(outputSpeed, desiredSpeed, smoothing * Time.deltaTime);
|
||||
additionalSpeed = Mathf.Lerp(additionalSpeed, desiredSpeed, smoothing * Time.deltaTime);
|
||||
|
||||
referenceSpeed = additionalSpeed;
|
||||
}
|
||||
@@ -257,7 +254,7 @@ namespace Reset.Units{
|
||||
float gravityMoveDirection = data.jumpPower + (Physics.gravity.y * data.gravityPower);
|
||||
|
||||
// Commit gravity to move direction, ignoring XZ since those are done in UpdateMovementDirection
|
||||
// outputMoveDirection.y = Mathf.SmoothDamp(outputMoveDirection.y, gravityMoveDirection, ref gravitySmooth, .1f * Time.deltaTime);
|
||||
outputMoveDirection.y = Mathf.SmoothDamp(outputMoveDirection.y, gravityMoveDirection, ref gravitySmooth, .1f * Time.deltaTime);
|
||||
}
|
||||
|
||||
// Update the rotation, called every frame
|
||||
|
||||
Reference in New Issue
Block a user