139 lines
3.9 KiB
C#
139 lines
3.9 KiB
C#
using System;
|
|
using HG;
|
|
using UnityEngine;
|
|
using UnityEngine.Networking;
|
|
|
|
namespace RoR2;
|
|
|
|
[RequireComponent(typeof(WormBodyPositions2))]
|
|
public class WormBodyPositionsDriver : MonoBehaviour
|
|
{
|
|
public Transform referenceTransform;
|
|
|
|
public Transform chasePositionVisualizer;
|
|
|
|
public float maxTurnSpeed = 180f;
|
|
|
|
public float verticalTurnSquashFactor = 2f;
|
|
|
|
public float ySpringConstant = 100f;
|
|
|
|
public float yDamperConstant = 1f;
|
|
|
|
public bool allowShoving;
|
|
|
|
public float yShoveVelocityThreshold;
|
|
|
|
public float yShovePositionThreshold;
|
|
|
|
public float yShoveForce;
|
|
|
|
public float turnRateCoefficientAboveGround;
|
|
|
|
public float wormForceCoefficientAboveGround;
|
|
|
|
public float keyFrameGenerationInterval = 0.25f;
|
|
|
|
public float maxBreachSpeed = 40f;
|
|
|
|
private WormBodyPositions2 wormBodyPositions;
|
|
|
|
private CharacterDirection characterDirection;
|
|
|
|
private Vector3 chaserPreviousVelocity;
|
|
|
|
private bool chaserIsUnderground;
|
|
|
|
private float keyFrameGenerationTimer;
|
|
|
|
public Vector3 chaserVelocity { get; set; }
|
|
|
|
public Vector3 chaserPosition { get; private set; }
|
|
|
|
private void Awake()
|
|
{
|
|
wormBodyPositions = GetComponent<WormBodyPositions2>();
|
|
characterDirection = GetComponent<CharacterDirection>();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
wormBodyPositions.onPredictedBreachDiscovered += OnPredictedBreachDiscovered;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
wormBodyPositions.onPredictedBreachDiscovered -= OnPredictedBreachDiscovered;
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
if (NetworkServer.active)
|
|
{
|
|
chaserPosition = base.transform.position;
|
|
chaserVelocity = characterDirection.forward;
|
|
}
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
if (NetworkServer.active)
|
|
{
|
|
FixedUpdateServer();
|
|
}
|
|
}
|
|
|
|
public void OnTeleport(Vector3 oldPosition, Vector3 newPosition)
|
|
{
|
|
Vector3 vector = newPosition - oldPosition;
|
|
chaserPosition += vector;
|
|
}
|
|
|
|
private void OnPredictedBreachDiscovered(float expectedTime, Vector3 hitPosition, Vector3 hitNormal)
|
|
{
|
|
float magnitude = chaserVelocity.magnitude;
|
|
if (magnitude > maxBreachSpeed)
|
|
{
|
|
chaserVelocity /= magnitude / maxBreachSpeed;
|
|
}
|
|
}
|
|
|
|
private void FixedUpdateServer()
|
|
{
|
|
Vector3 position = referenceTransform.position;
|
|
float speedMultiplier = wormBodyPositions.speedMultiplier;
|
|
Vector3 normalized = (position - chaserPosition).normalized;
|
|
float num = (chaserIsUnderground ? maxTurnSpeed : (maxTurnSpeed * turnRateCoefficientAboveGround)) * (MathF.PI / 180f);
|
|
Vector3 current = new Vector3(chaserVelocity.x, 0f, chaserVelocity.z);
|
|
Vector3 vector = new Vector3(normalized.x, 0f, normalized.z);
|
|
current = Vector3.RotateTowards(current, vector * speedMultiplier, num * Time.fixedDeltaTime, float.PositiveInfinity).normalized * speedMultiplier;
|
|
float num2 = position.y - chaserPosition.y;
|
|
float num3 = (0f - chaserVelocity.y) * yDamperConstant;
|
|
float num4 = num2 * ySpringConstant;
|
|
Vector3 vec;
|
|
if (allowShoving && Mathf.Abs(chaserVelocity.y) < yShoveVelocityThreshold && num2 > yShovePositionThreshold)
|
|
{
|
|
vec = chaserVelocity;
|
|
chaserVelocity = vec.XAZ(chaserVelocity.y + yShoveForce * Time.fixedDeltaTime);
|
|
}
|
|
if (!chaserIsUnderground)
|
|
{
|
|
num4 *= wormForceCoefficientAboveGround;
|
|
num3 *= wormForceCoefficientAboveGround;
|
|
}
|
|
vec = chaserVelocity;
|
|
chaserVelocity = vec.XAZ(chaserVelocity.y + (num4 + num3) * Time.fixedDeltaTime);
|
|
chaserVelocity += Physics.gravity * Time.fixedDeltaTime;
|
|
chaserVelocity = new Vector3(current.x, chaserVelocity.y, current.z);
|
|
chaserPosition += chaserVelocity * Time.fixedDeltaTime;
|
|
chasePositionVisualizer.position = chaserPosition;
|
|
chaserIsUnderground = 0f - num2 < wormBodyPositions.undergroundTestYOffset;
|
|
keyFrameGenerationTimer -= Time.deltaTime;
|
|
if (keyFrameGenerationTimer <= 0f)
|
|
{
|
|
keyFrameGenerationTimer = keyFrameGenerationInterval;
|
|
wormBodyPositions.AttemptToGenerateKeyFrame(wormBodyPositions.GetSynchronizedTimeStamp() + wormBodyPositions.followDelay, chaserPosition, chaserVelocity);
|
|
}
|
|
}
|
|
}
|