initial upload

This commit is contained in:
tom.hempel
2025-09-21 22:42:26 +02:00
commit d03bcd4ba5
6231 changed files with 351582 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: ac6d72f62ff624a668172c39e3639634
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: 7cdefd61256654a66ba209970153a134
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: c41c0269170fa408c8fa1d404cb33d4c
folderAsset: yes
timeCreated: 1434626795
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: 8c3a06490bd824f38ba8dae3780a889c
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,6 @@
fileFormatVersion: 2
guid: bb1f846cefd024029b6b716581825a6c
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: f15268c8bd7c44960aa7b454b78f2574
folderAsset: yes
timeCreated: 1434626795
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,115 @@
using UnityEngine;
using System.Collections;
namespace RootMotion.Demos {
/// <summary>
/// Mech spider Demo.
/// </summary>
public class MechSpider : MonoBehaviour {
public LayerMask raycastLayers; // The ground layers
public float scale = 1f; // For resizing the values when the mech is resized
public Transform body; // The body transform, the root of the legs
public MechSpiderLeg[] legs; // All the legs of this spider
public float legRotationWeight = 1f; // The weight of rotating the body to each leg
public float rootPositionSpeed = 5f; // The speed of positioning the root
public float rootRotationSpeed = 30f; // The slerp speed of rotating the root to leg heights
public float breatheSpeed = 2f; // Speed of the breathing cycle
public float breatheMagnitude = 0.2f; // Magnitude of breathing
public float height = 3.5f; // Height from ground
public float minHeight = 2f; // The minimum height from ground
public float raycastHeight = 10f; // The height of ray origin
public float raycastDistance = 5f; // The distance of rays (total ray length = raycastHeight + raycastDistance)
public Vector3 velocity { get; private set; }
private Vector3 lastPosition;
private Vector3 defaultBodyLocalPosition;
private float sine;
private RaycastHit rootHit;
private void Start()
{
lastPosition = transform.position;
}
void Update() {
velocity = (transform.position - lastPosition) / Time.deltaTime;
lastPosition = transform.position;
// Find the normal of the plane defined by leg positions
Vector3 legsPlaneNormal = GetLegsPlaneNormal();
// Rotating the root
Quaternion fromTo = Quaternion.FromToRotation(transform.up, legsPlaneNormal);
transform.rotation = Quaternion.Slerp(transform.rotation, fromTo * transform.rotation, Time.deltaTime * rootRotationSpeed);
// Positioning the root
Vector3 legCentroid = GetLegCentroid();
Vector3 heightOffset = Vector3.Project((legCentroid + transform.up * height * scale) - transform.position, transform.up);
transform.position += heightOffset * Time.deltaTime * (rootPositionSpeed * scale);
if (Physics.Raycast(transform.position + transform.up * raycastHeight * scale, -transform.up, out rootHit, (raycastHeight * scale) + (raycastDistance * scale), raycastLayers)) {
rootHit.distance -= (raycastHeight * scale) + (minHeight * scale);
if (rootHit.distance < 0f) {
Vector3 targetPosition = transform.position - transform.up * rootHit.distance;
transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * rootPositionSpeed * scale);
}
}
// Update Breathing
sine += Time.deltaTime * breatheSpeed;
if (sine >= Mathf.PI * 2f) sine -= Mathf.PI * 2f;
float br = Mathf.Sin(sine) * breatheMagnitude * scale;
// Apply breathing
Vector3 breatheOffset = transform.up * br;
body.transform.position = transform.position + breatheOffset;
}
// Calculate the normal of the plane defined by leg positions, so we know how to rotate the body
private Vector3 GetLegCentroid() {
Vector3 position = Vector3.zero;
float footWeight = 1f / (float)legs.Length;
// Go through all the legs, rotate the normal by its offset
for (int i = 0; i < legs.Length; i++) {
position += legs[i].position * footWeight;
}
return position;
}
// Calculate the normal of the plane defined by leg positions, so we know how to rotate the body
private Vector3 GetLegsPlaneNormal() {
Vector3 normal = transform.up;
if (legRotationWeight <= 0f) return normal;
float legWeight = 1f / Mathf.Lerp(legs.Length, 1f, legRotationWeight);
// Go through all the legs, rotate the normal by its offset
for (int i = 0; i < legs.Length; i++) {
// Direction from the root to the leg
Vector3 legDirection = legs[i].position - (transform.position - transform.up * height * scale);
// Find the tangent to transform.up
Vector3 legNormal = transform.up;
Vector3 legTangent = legDirection;
Vector3.OrthoNormalize(ref legNormal, ref legTangent);
// Find the rotation offset from the tangent to the direction
Quaternion fromTo = Quaternion.FromToRotation(legTangent, legDirection);
fromTo = Quaternion.Lerp(Quaternion.identity, fromTo, legWeight);
// Rotate the normal
normal = fromTo * normal;
}
return normal;
}
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 5e38d8e43dbfd42c2bbdb924c89c44d0
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,37 @@
using UnityEngine;
using System.Collections;
namespace RootMotion.Demos {
/// <summary>
/// Controller for the Mech spider.
/// </summary>
public class MechSpiderController: MonoBehaviour {
public MechSpider mechSpider; // The mech spider
public Transform cameraTransform; // The camera
public float speed = 6f; // Horizontal speed of the spider
public float turnSpeed = 30f; // The speed of turning the spider to align with the camera
public Vector3 inputVector {
get {
return new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
}
}
void Update() {
// Read the input
Vector3 cameraForward = cameraTransform.forward;
Vector3 camNormal = transform.up;
Vector3.OrthoNormalize(ref camNormal, ref cameraForward);
// Moving the spider
Quaternion cameraLookRotation = Quaternion.LookRotation(cameraForward, transform.up);
transform.Translate(cameraLookRotation * inputVector.normalized * Time.deltaTime * speed * mechSpider.scale, Space.World);
// Rotating the spider to camera forward
transform.rotation = Quaternion.RotateTowards(transform.rotation, cameraLookRotation, Time.deltaTime * turnSpeed);
}
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: dfca8416545ee44e6b71f34d93313b69
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,177 @@
using UnityEngine;
using System.Collections;
using RootMotion.FinalIK;
namespace RootMotion.Demos {
/// <summary>
/// Leg of the Mech spider. Controls stepping and positioning the IK target
/// </summary>
public class MechSpiderLeg : MonoBehaviour {
public MechSpider mechSpider; // Reference to the target
public MechSpiderLeg unSync; // One of the other legs that we dont want to be completely in sync with, that is stepping at the same time
public Vector3 offset; // Offset from the default position
public float minDelay = 0.2f, maxOffset = 1.0f, stepSpeed = 5.0f, footHeight = 0.15f, velocityPrediction = 0.2f, raycastFocus = 0.1f; // Parameters for stepping
public AnimationCurve yOffset;
public Transform foot;
public Vector3 footUpAxis;
public float footRotationSpeed = 10f;
public ParticleSystem sand; // FX for sand
private IK ik;
private float stepProgress = 1f, lastStepTime;
private Vector3 defaultPosition;
private RaycastHit hit = new RaycastHit();
private Quaternion lastFootLocalRotation;
private Vector3 smoothHitNormal = Vector3.up;
private Vector3 lastStepPosition;
// Is the leg stepping?
public bool isStepping {
get {
return stepProgress < 1f;
}
}
// Gets and sets the IK position for this leg
public Vector3 position {
get {
return ik.GetIKSolver().GetIKPosition();
}
set {
ik.GetIKSolver().SetIKPosition(value);
}
}
void Awake()
{
// Find the ik component
ik = GetComponent<IK>();
if (foot != null)
{
if (footUpAxis == Vector3.zero) footUpAxis = Quaternion.Inverse(foot.rotation) * Vector3.up;
lastFootLocalRotation = foot.localRotation;
ik.GetIKSolver().OnPostUpdate += AfterIK;
}
}
private void AfterIK()
{
if (foot == null) return;
foot.localRotation = lastFootLocalRotation;
smoothHitNormal = Vector3.Slerp(smoothHitNormal, hit.normal, Time.deltaTime * footRotationSpeed);
Quaternion f = Quaternion.FromToRotation(foot.rotation * footUpAxis, smoothHitNormal);
foot.rotation = f * foot.rotation;
}
void Start() {
// Workaround for Unity Win Store/Phone serialization bug
stepProgress = 1f;
hit = new RaycastHit();
var points = ik.GetIKSolver().GetPoints();
position = points[points.Length - 1].transform.position;
lastStepPosition = position;
hit.point = position;
// Store the default rest position of the leg
defaultPosition = mechSpider.transform.InverseTransformPoint(position + offset * mechSpider.scale);
StartCoroutine(Step(position, position));
}
// Find the relaxed grounded positon of the leg relative to the body in world space.
private Vector3 GetStepTarget(out bool stepFound, float focus, float distance) {
stepFound = false;
// place hit.point to the default position relative to the body
Vector3 stepTarget = mechSpider.transform.TransformPoint(defaultPosition);
//stepTarget += (hit.point - position) * velocityPrediction;
stepTarget += mechSpider.velocity * velocityPrediction;
Vector3 up = mechSpider.transform.up;
// Focus the ray directions towards the spider body
Vector3 toBody = mechSpider.body.position - position;
Vector3 axis = Vector3.Cross(up, toBody);
up = Quaternion.AngleAxis(focus, axis) * up;
// Raycast to ground the relaxed position
if (Physics.Raycast(stepTarget + up * mechSpider.raycastHeight * mechSpider.scale, -up, out hit, mechSpider.raycastHeight * mechSpider.scale + distance, mechSpider.raycastLayers)) stepFound = true;
//return hit.point + mechSpider.transform.up * footHeight * mechSpider.scale;
return hit.point + hit.normal * footHeight * mechSpider.scale;
}
private void UpdatePosition(float distance)
{
Vector3 up = mechSpider.transform.up;
if (Physics.Raycast(lastStepPosition + up * mechSpider.raycastHeight * mechSpider.scale, -up, out hit, mechSpider.raycastHeight * mechSpider.scale + distance, mechSpider.raycastLayers))
{
position = hit.point + hit.normal * footHeight * mechSpider.scale;
}
}
void Update () {
UpdatePosition(mechSpider.raycastDistance * mechSpider.scale);
// if already stepping, do nothing
if (isStepping) return;
// Minimum delay before stepping again
if (Time.time < lastStepTime + minDelay) return;
// If the unSync leg is stepping, do nothing
if (unSync != null) {
if (unSync.isStepping) return;
}
// Find the ideal relaxed position for the leg relative to the body
bool stepFound = false;
Vector3 idealPosition = GetStepTarget(out stepFound, raycastFocus, mechSpider.raycastDistance * mechSpider.scale);
if (!stepFound) idealPosition = GetStepTarget(out stepFound, -raycastFocus, mechSpider.raycastDistance * 3f * mechSpider.scale); // Try again with inverted focus
if (!stepFound) return;
// If distance to that ideal position is less than the threshold, do nothing
if (Vector3.Distance(position, idealPosition) < maxOffset * mechSpider.scale * UnityEngine.Random.Range(0.9f, 1.2f)) return;
// Need to step closer to the ideal position
StopAllCoroutines();
StartCoroutine(Step(position, idealPosition));
}
// Stepping co-routine
private IEnumerator Step(Vector3 stepStartPosition, Vector3 targetPosition) {
stepProgress = 0f;
// Moving the IK position
while (stepProgress < 1) {
stepProgress += Time.deltaTime * stepSpeed;
position = Vector3.Lerp(stepStartPosition, targetPosition, stepProgress);
position += mechSpider.transform.up * yOffset.Evaluate(stepProgress) * mechSpider.scale;
lastStepPosition = position;
yield return null;
}
position = targetPosition;
lastStepPosition = position;
// Emit sand
if (sand != null) {
sand.transform.position = position - mechSpider.transform.up * footHeight * mechSpider.scale;
sand.Emit(20);
}
lastStepTime = Time.time;
}
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: ed6e75890d3ab4d4baef5ecd91784aba
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,38 @@
using UnityEngine;
using System.Collections;
namespace RootMotion.Demos {
/// <summary>
/// Emitting smoke for the mech spider
/// </summary>
public class MechSpiderParticles: MonoBehaviour {
public MechSpiderController mechSpiderController;
private ParticleSystem particles;
void Start() {
particles = (ParticleSystem)GetComponent(typeof(ParticleSystem));
}
void Update() {
// Smoke
float inputMag = mechSpiderController.inputVector.magnitude;
float emissionRate = Mathf.Clamp(inputMag * 50, 30, 50);
#if (UNITY_5_3 || UNITY_5_4)
var emission = particles.emission;
emission.rate = new ParticleSystem.MinMaxCurve(emissionRate);
particles.startColor = new Color (particles.startColor.r, particles.startColor.g, particles.startColor.b, Mathf.Clamp(inputMag, 0.4f, 1f));
#else
var emission = particles.emission;
emission.rateOverTime = new ParticleSystem.MinMaxCurve(emissionRate);
var main = particles.main;
main.startColor = new Color (particles.main.startColor.color.r, particles.main.startColor.color.g, particles.main.startColor.color.b, Mathf.Clamp(inputMag, 0.4f, 1f));
#endif
}
}
}

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: e1a69cb78a14c451884988d32da4a529
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: