mirror of
https://github.com/nothke/quality-control.git
synced 2025-08-31 15:43:44 +00:00
Added KCC
This commit is contained in:
261
Assets/Plugins/KinematicCharacterController/Core/PhysicsMover.cs
Normal file
261
Assets/Plugins/KinematicCharacterController/Core/PhysicsMover.cs
Normal file
@@ -0,0 +1,261 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KinematicCharacterController
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the entire state of a PhysicsMover that is pertinent for simulation.
|
||||
/// Use this to save state or revert to past state
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public struct PhysicsMoverState
|
||||
{
|
||||
public Vector3 Position;
|
||||
public Quaternion Rotation;
|
||||
public Vector3 Velocity;
|
||||
public Vector3 AngularVelocity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Component that manages the movement of moving kinematic rigidbodies for
|
||||
/// proper interaction with characters
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
public class PhysicsMover : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// The mover's Rigidbody
|
||||
/// </summary>
|
||||
[ReadOnly]
|
||||
public Rigidbody Rigidbody;
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the platform moves with rigidbody.MovePosition (when true), or with rigidbody.position (when false)
|
||||
/// </summary>
|
||||
public bool MoveWithPhysics = true;
|
||||
|
||||
/// <summary>
|
||||
/// Index of this motor in KinematicCharacterSystem arrays
|
||||
/// </summary>
|
||||
[NonSerialized]
|
||||
public IMoverController MoverController;
|
||||
/// <summary>
|
||||
/// Remembers latest position in interpolation
|
||||
/// </summary>
|
||||
[NonSerialized]
|
||||
public Vector3 LatestInterpolationPosition;
|
||||
/// <summary>
|
||||
/// Remembers latest rotation in interpolation
|
||||
/// </summary>
|
||||
[NonSerialized]
|
||||
public Quaternion LatestInterpolationRotation;
|
||||
/// <summary>
|
||||
/// The latest movement made by interpolation
|
||||
/// </summary>
|
||||
[NonSerialized]
|
||||
public Vector3 PositionDeltaFromInterpolation;
|
||||
/// <summary>
|
||||
/// The latest rotation made by interpolation
|
||||
/// </summary>
|
||||
[NonSerialized]
|
||||
public Quaternion RotationDeltaFromInterpolation;
|
||||
|
||||
/// <summary>
|
||||
/// Index of this motor in KinematicCharacterSystem arrays
|
||||
/// </summary>
|
||||
public int IndexInCharacterSystem { get; set; }
|
||||
/// <summary>
|
||||
/// Remembers initial position before all simulation are done
|
||||
/// </summary>
|
||||
public Vector3 Velocity { get; protected set; }
|
||||
/// <summary>
|
||||
/// Remembers initial position before all simulation are done
|
||||
/// </summary>
|
||||
public Vector3 AngularVelocity { get; protected set; }
|
||||
/// <summary>
|
||||
/// Remembers initial position before all simulation are done
|
||||
/// </summary>
|
||||
public Vector3 InitialTickPosition { get; set; }
|
||||
/// <summary>
|
||||
/// Remembers initial rotation before all simulation are done
|
||||
/// </summary>
|
||||
public Quaternion InitialTickRotation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The mover's Transform
|
||||
/// </summary>
|
||||
public Transform Transform { get; private set; }
|
||||
/// <summary>
|
||||
/// The character's position before the movement calculations began
|
||||
/// </summary>
|
||||
public Vector3 InitialSimulationPosition { get; private set; }
|
||||
/// <summary>
|
||||
/// The character's rotation before the movement calculations began
|
||||
/// </summary>
|
||||
public Quaternion InitialSimulationRotation { get; private set; }
|
||||
|
||||
private Vector3 _internalTransientPosition;
|
||||
|
||||
/// <summary>
|
||||
/// The mover's rotation (always up-to-date during the character update phase)
|
||||
/// </summary>
|
||||
public Vector3 TransientPosition
|
||||
{
|
||||
get
|
||||
{
|
||||
return _internalTransientPosition;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_internalTransientPosition = value;
|
||||
}
|
||||
}
|
||||
|
||||
private Quaternion _internalTransientRotation;
|
||||
/// <summary>
|
||||
/// The mover's rotation (always up-to-date during the character update phase)
|
||||
/// </summary>
|
||||
public Quaternion TransientRotation
|
||||
{
|
||||
get
|
||||
{
|
||||
return _internalTransientRotation;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_internalTransientRotation = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
ValidateData();
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
ValidateData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle validating all required values
|
||||
/// </summary>
|
||||
public void ValidateData()
|
||||
{
|
||||
Rigidbody = gameObject.GetComponent<Rigidbody>();
|
||||
|
||||
Rigidbody.centerOfMass = Vector3.zero;
|
||||
Rigidbody.maxAngularVelocity = Mathf.Infinity;
|
||||
Rigidbody.maxDepenetrationVelocity = Mathf.Infinity;
|
||||
Rigidbody.isKinematic = true;
|
||||
Rigidbody.interpolation = RigidbodyInterpolation.None;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
KinematicCharacterSystem.EnsureCreation();
|
||||
KinematicCharacterSystem.RegisterPhysicsMover(this);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
KinematicCharacterSystem.UnregisterPhysicsMover(this);
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Transform = this.transform;
|
||||
ValidateData();
|
||||
|
||||
TransientPosition = Rigidbody.position;
|
||||
TransientRotation = Rigidbody.rotation;
|
||||
InitialSimulationPosition = Rigidbody.position;
|
||||
InitialSimulationRotation = Rigidbody.rotation;
|
||||
LatestInterpolationPosition = Transform.position;
|
||||
LatestInterpolationRotation = Transform.rotation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the mover's position directly
|
||||
/// </summary>
|
||||
public void SetPosition(Vector3 position)
|
||||
{
|
||||
Transform.position = position;
|
||||
Rigidbody.position = position;
|
||||
InitialSimulationPosition = position;
|
||||
TransientPosition = position;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the mover's rotation directly
|
||||
/// </summary>
|
||||
public void SetRotation(Quaternion rotation)
|
||||
{
|
||||
Transform.rotation = rotation;
|
||||
Rigidbody.rotation = rotation;
|
||||
InitialSimulationRotation = rotation;
|
||||
TransientRotation = rotation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the mover's position and rotation directly
|
||||
/// </summary>
|
||||
public void SetPositionAndRotation(Vector3 position, Quaternion rotation)
|
||||
{
|
||||
Transform.SetPositionAndRotation(position, rotation);
|
||||
Rigidbody.position = position;
|
||||
Rigidbody.rotation = rotation;
|
||||
InitialSimulationPosition = position;
|
||||
InitialSimulationRotation = rotation;
|
||||
TransientPosition = position;
|
||||
TransientRotation = rotation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all the state information of the mover that is pertinent for simulation
|
||||
/// </summary>
|
||||
public PhysicsMoverState GetState()
|
||||
{
|
||||
PhysicsMoverState state = new PhysicsMoverState();
|
||||
|
||||
state.Position = TransientPosition;
|
||||
state.Rotation = TransientRotation;
|
||||
state.Velocity = Velocity;
|
||||
state.AngularVelocity = AngularVelocity;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a mover state instantly
|
||||
/// </summary>
|
||||
public void ApplyState(PhysicsMoverState state)
|
||||
{
|
||||
SetPositionAndRotation(state.Position, state.Rotation);
|
||||
Velocity = state.Velocity;
|
||||
AngularVelocity = state.AngularVelocity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Caches velocity values based on deltatime and target position/rotations
|
||||
/// </summary>
|
||||
public void VelocityUpdate(float deltaTime)
|
||||
{
|
||||
InitialSimulationPosition = TransientPosition;
|
||||
InitialSimulationRotation = TransientRotation;
|
||||
|
||||
MoverController.UpdateMovement(out _internalTransientPosition, out _internalTransientRotation, deltaTime);
|
||||
|
||||
if (deltaTime > 0f)
|
||||
{
|
||||
Velocity = (TransientPosition - InitialSimulationPosition) / deltaTime;
|
||||
|
||||
Quaternion rotationFromCurrentToGoal = TransientRotation * (Quaternion.Inverse(InitialSimulationRotation));
|
||||
AngularVelocity = (Mathf.Deg2Rad * rotationFromCurrentToGoal.eulerAngles) / deltaTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user