101 lines
2.8 KiB
C#
101 lines
2.8 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace RootMotion.Demos
|
|
{
|
|
public class MechSpider : MonoBehaviour
|
|
{
|
|
public LayerMask raycastLayers;
|
|
|
|
public float scale = 1f;
|
|
|
|
public Transform body;
|
|
|
|
public MechSpiderLeg[] legs;
|
|
|
|
public float legRotationWeight = 1f;
|
|
|
|
public float rootPositionSpeed = 5f;
|
|
|
|
public float rootRotationSpeed = 30f;
|
|
|
|
public float breatheSpeed = 2f;
|
|
|
|
public float breatheMagnitude = 0.2f;
|
|
|
|
public float height = 3.5f;
|
|
|
|
public float minHeight = 2f;
|
|
|
|
public float raycastHeight = 10f;
|
|
|
|
public float raycastDistance = 5f;
|
|
|
|
private Vector3 lastPosition;
|
|
|
|
private Vector3 defaultBodyLocalPosition;
|
|
|
|
private float sine;
|
|
|
|
private RaycastHit rootHit;
|
|
|
|
private void Update()
|
|
{
|
|
Vector3 legsPlaneNormal = GetLegsPlaneNormal();
|
|
Quaternion quaternion = Quaternion.FromToRotation(base.transform.up, legsPlaneNormal);
|
|
base.transform.rotation = Quaternion.Slerp(base.transform.rotation, quaternion * base.transform.rotation, Time.deltaTime * rootRotationSpeed);
|
|
Vector3 vector = Vector3.Project(GetLegCentroid() + base.transform.up * height * scale - base.transform.position, base.transform.up);
|
|
base.transform.position += vector * Time.deltaTime * (rootPositionSpeed * scale);
|
|
if (Physics.Raycast(base.transform.position + base.transform.up * raycastHeight * scale, -base.transform.up, out rootHit, raycastHeight * scale + raycastDistance * scale, raycastLayers))
|
|
{
|
|
rootHit.distance -= raycastHeight * scale + minHeight * scale;
|
|
if (rootHit.distance < 0f)
|
|
{
|
|
Vector3 b = base.transform.position - base.transform.up * rootHit.distance;
|
|
base.transform.position = Vector3.Lerp(base.transform.position, b, Time.deltaTime * rootPositionSpeed * scale);
|
|
}
|
|
}
|
|
sine += Time.deltaTime * breatheSpeed;
|
|
if (sine >= MathF.PI * 2f)
|
|
{
|
|
sine -= MathF.PI * 2f;
|
|
}
|
|
float num = Mathf.Sin(sine) * breatheMagnitude * scale;
|
|
Vector3 vector2 = base.transform.up * num;
|
|
body.transform.position = base.transform.position + vector2;
|
|
}
|
|
|
|
private Vector3 GetLegCentroid()
|
|
{
|
|
Vector3 zero = Vector3.zero;
|
|
float num = 1f / (float)legs.Length;
|
|
for (int i = 0; i < legs.Length; i++)
|
|
{
|
|
zero += legs[i].position * num;
|
|
}
|
|
return zero;
|
|
}
|
|
|
|
private Vector3 GetLegsPlaneNormal()
|
|
{
|
|
Vector3 vector = base.transform.up;
|
|
if (legRotationWeight <= 0f)
|
|
{
|
|
return vector;
|
|
}
|
|
float t = 1f / Mathf.Lerp(legs.Length, 1f, legRotationWeight);
|
|
for (int i = 0; i < legs.Length; i++)
|
|
{
|
|
Vector3 vector2 = legs[i].position - (base.transform.position - base.transform.up * height * scale);
|
|
Vector3 normal = base.transform.up;
|
|
Vector3 tangent = vector2;
|
|
Vector3.OrthoNormalize(ref normal, ref tangent);
|
|
Quaternion b = Quaternion.FromToRotation(tangent, vector2);
|
|
b = Quaternion.Lerp(Quaternion.identity, b, t);
|
|
vector = b * vector;
|
|
}
|
|
return vector;
|
|
}
|
|
}
|
|
}
|