Skip to content

Commit

Permalink
feat(Interaction): support legacy animation in animation grab mechanic
Browse files Browse the repository at this point in the history
The Control Animation Grab Mechanic now supports legacy animations as
well as mechanim Animators.
  • Loading branch information
thestonefox committed Oct 27, 2017
1 parent 0bc1acc commit 0db2ffb
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 8 deletions.
6 changes: 5 additions & 1 deletion Assets/VRTK/Documentation/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -5437,11 +5437,15 @@ Scrubs through the given animation based on the distance from the grabbing objec
* Place the `VRTK_ControlAnimationGrabAttach` script on either:
* The GameObject of the Interactable Object to detect interactions on.
* Any other scene GameObject and then link that GameObject to the Interactable Objects `Grab Attach Mechanic Script` parameter to denote use of the grab mechanic.
* Create and apply an animation via:
* `Animation Timeline` parameter takes a legacy `Animation` component to use as the timeline to scrub through. The animation must be marked as `legacy` via the inspector in debug mode.
* `Animator Timeline` parameter takes an Animator component to use as the timeline to scrub through.

### Inspector Parameters

* **Detach Distance:** The maximum distance the grabbing object is away from the Interactable Object before it is automatically released.
* **Timeline:** The Animator with the timeline to scrub through on grab.
* **Animation Timeline:** An Animation with the timeline to scrub through on grab. If this is set then the `Animator Timeline` will be ignored if it is also set.
* **Animator Timeline:** An Animator with the timeline to scrub through on grab.
* **Max Frames:** The maximum amount of frames in the timeline.
* **Distance Multiplier:** An amount to multiply the distance by to determine the scrubbed frame to be on.
* **Rewind On Release:** If this is checked then the animation will rewind to the start on ungrab.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ public struct ControlAnimationGrabAttachEventArgs
/// * Place the `VRTK_ControlAnimationGrabAttach` script on either:
/// * The GameObject of the Interactable Object to detect interactions on.
/// * Any other scene GameObject and then link that GameObject to the Interactable Objects `Grab Attach Mechanic Script` parameter to denote use of the grab mechanic.
/// * Create and apply an animation via:
/// * `Animation Timeline` parameter takes a legacy `Animation` component to use as the timeline to scrub through. The animation must be marked as `legacy` via the inspector in debug mode.
/// * `Animator Timeline` parameter takes an Animator component to use as the timeline to scrub through.
/// </remarks>
[AddComponentMenu("VRTK/Scripts/Interactions/Interactables/Grab Attach Mechanics/VRTK_ControlAnimationGrabAttach")]
public class VRTK_ControlAnimationGrabAttach : VRTK_BaseGrabAttach
Expand All @@ -39,8 +42,10 @@ public class VRTK_ControlAnimationGrabAttach : VRTK_BaseGrabAttach

[Header("Animation Settings", order = 2)]

[Tooltip("The Animator with the timeline to scrub through on grab.")]
public Animator timeline;
[Tooltip("An Animation with the timeline to scrub through on grab. If this is set then the `Animator Timeline` will be ignored if it is also set.")]
public Animation animationTimeline;
[Tooltip("An Animator with the timeline to scrub through on grab.")]
public Animator animatorTimeline;
[Tooltip("The maximum amount of frames in the timeline.")]
public float maxFrames = 1f;
[Tooltip("An amount to multiply the distance by to determine the scrubbed frame to be on.")]
Expand Down Expand Up @@ -68,6 +73,7 @@ public class VRTK_ControlAnimationGrabAttach : VRTK_BaseGrabAttach
protected float currentFrame = 0f;
protected Coroutine resetTimelineRoutine;
protected bool atEnd = false;
protected string animationName = "";

public virtual void OnAnimationFrameChanged(ControlAnimationGrabAttachEventArgs e)
{
Expand Down Expand Up @@ -166,10 +172,10 @@ public override void ProcessUpdate()
public virtual void SetFrame(float frame)
{
float setFrame = frame * distanceMultiplier;
timeline.speed = animationSpeed;
SetTimelineSpeed(animationSpeed);
if (setFrame < maxFrames)
{
timeline.Play(0, 0, setFrame);
SetTimelinePosition(setFrame);
if (setFrame == 0)
{
OnAnimationFrameAtStart(SetEventPayload(setFrame));
Expand Down Expand Up @@ -204,9 +210,52 @@ protected override void Initialise()
tracked = false;
climbable = false;
kinematic = true;
InitTimeline();
}

protected virtual void InitTimeline()
{
animatorTimeline = (animatorTimeline != null ? animatorTimeline : GetComponent<Animator>());
animationTimeline = (animationTimeline != null ? animationTimeline : GetComponent<Animation>());
if (animationTimeline != null)
{
if (!animationTimeline.clip.legacy)
{
VRTK_Logger.Error("The `VRTK_ControlAnimationGrabAttach` script is using an `Animation Timeline` that has not been set to `Legacy Animation`. Only legacy animations are supported.");
}

timeline = (timeline != null ? timeline : GetComponent<Animator>());
timeline.speed = animationSpeed;
foreach (AnimationState currentClip in animationTimeline)
{
animationName = currentClip.name;
break;
}
}
SetTimelineSpeed(animationSpeed);
}

protected virtual void SetTimelineSpeed(float speed)
{
if (animationTimeline != null)
{
animationTimeline[animationName].speed = speed;
}
else if (animatorTimeline != null)
{
animatorTimeline.speed = speed;
}
}

protected virtual void SetTimelinePosition(float framePosition)
{
if (animationTimeline != null)
{
animationTimeline[animationName].time = framePosition;
animationTimeline.Play(animationName);
}
else if (animatorTimeline != null)
{
animatorTimeline.Play(0, 0, framePosition);
}
}

protected virtual void CancelResetTimeline()
Expand All @@ -232,7 +281,7 @@ protected virtual IEnumerator ResetTimeline(float frame)
protected virtual ControlAnimationGrabAttachEventArgs SetEventPayload(float frame)
{
ControlAnimationGrabAttachEventArgs e;
e.interactingObject = grabbedObjectScript.GetGrabbingObject();
e.interactingObject = (grabbedObjectScript != null ? grabbedObjectScript.GetGrabbingObject() : null);
e.currentFrame = frame;
return e;
}
Expand Down

0 comments on commit 0db2ffb

Please sign in to comment.