Last active
March 3, 2022 07:46
-
-
Save FleshMobProductions/5f9225ed8c66c53b68f76ea7af0ceab2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
namespace FMPUtils | |
{ | |
/// <summary> | |
/// In order to apply the delta movement to an object, just check if the object is grounded on this obstacle, | |
/// and if it is, store a reference to this behaviour and call one of the following methods in the Update() for | |
/// applying the delta movement of this object: ApplyDeltaTranslationTo, ApplyDeltaRotationTo or | |
/// ApplyDeltaTranslationRotationTo. If the object is disabled, delta changes are 0 and positions / rotations | |
/// won't get updated. | |
/// One recommneded workflow might be to assign another script that handles movement of the transform to this | |
/// gameObject. In the script execution order settings (or by using the DefaultExecutionOrder attribute above | |
/// the class definition), assign a lower value (like -20), for it to have priority. | |
/// Then assign a script execution order value to MovingObstacle that is higher than the movement script, | |
/// but lower than 0, so it has priority towards regular scripts. | |
/// Then the right order is maintained: 1. movement of the object is updated, 2. delta movement values in | |
/// this script are updated, 3. delta movement changes are applied to other objects if the call the "ApplyTo" methods | |
/// </summary> | |
public class MovingObstacle : MonoBehaviour | |
{ | |
private Quaternion rotationPrevFrame; | |
private Quaternion rotationCurrentFrame; | |
private Vector3 positionPrevFrame; | |
private Vector3 positionCurrentFrame; | |
private void Start() | |
{ | |
StoreCurrentValuesInTranslationVars(); | |
} | |
// Make the positions to be the same, so that we don't receive delta position or rotation values from the | |
// disabled objects while they are disabled | |
private void OnEnable() | |
{ | |
StoreCurrentValuesInTranslationVars(); | |
} | |
private void OnDisable() | |
{ | |
StoreCurrentValuesInTranslationVars(); | |
} | |
private void StoreCurrentValuesInTranslationVars() | |
{ | |
rotationCurrentFrame = transform.rotation; | |
rotationPrevFrame = rotationCurrentFrame; | |
positionCurrentFrame = transform.position; | |
positionPrevFrame = positionCurrentFrame; | |
} | |
public Quaternion GetDeltaRotation() | |
{ | |
if (rotationCurrentFrame != rotationPrevFrame) | |
{ | |
return Quaternion.Inverse(rotationPrevFrame) * rotationCurrentFrame; | |
} | |
return Quaternion.identity; | |
} | |
public Vector3 GetDeltaTranslation() | |
{ | |
return positionCurrentFrame - positionPrevFrame; | |
} | |
private void Update() | |
{ | |
rotationPrevFrame = rotationCurrentFrame; | |
positionPrevFrame = positionCurrentFrame; | |
rotationCurrentFrame = transform.rotation; | |
positionCurrentFrame = transform.position; | |
} | |
public void ApplyDeltaTranslationTo(Transform target) | |
{ | |
target.Translate(GetDeltaTranslation(), Space.World); | |
} | |
public void ApplyDeltaRotationTo(Transform target) | |
{ | |
target.rotation *= GetDeltaRotation(); | |
} | |
public void ApplyDeltaTranslationRotationTo(Transform target) | |
{ | |
Vector3 prevPos = target.position; | |
Quaternion prevRot = target.rotation; | |
target.SetPositionAndRotation(prevPos + GetDeltaTranslation(), prevRot * GetDeltaRotation()); | |
} | |
/// <summary> | |
/// Will return the target.position in obstacle local space. The method should | |
/// be called when entering the platform. Use the returned local position for | |
/// future placement on the obstacle | |
/// </summary> | |
/// <param name="target"></param> | |
/// <returns></returns> | |
public Vector3 GetObstacleLocalPositionOnEntering(Transform target) | |
{ | |
return transform.InverseTransformPoint(target.position); | |
} | |
/// <summary> | |
/// Takes the local position the target had on entering the platform and the global position change of the target since the platform was entered, | |
/// and returns the new global position for the target | |
/// </summary> | |
/// <param name="target">the object to apply the position changes to</param> | |
/// <param name="obstacleLocalPosOnEntering">the local position that was returned by calling GetObstacleLocalPositionOnEntering when entering the obstacle</param> | |
/// <param name="globalMovementSinceEntering">The global delta movement of the target since the target entered the obstacle</param> | |
/// <returns></returns> | |
public Vector3 GetGlobalPositionOnObstacleFor(Transform target, Vector3 obstacleLocalPosOnEntering, Vector3 globalMovementSinceEntering) | |
{ | |
return transform.TransformPoint(obstacleLocalPosOnEntering) + globalMovementSinceEntering; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment