Skip to main content

VR/AR & Mobile

Complete examples and tutorials for creating VR/AR and mobile animations with Animatix Pro. This comprehensive guide provides ready-to-use examples for immersive and mobile experiences.

🥽 VR/AR Animation Examples

VR Interaction Animations

Complete VR interaction examples for immersive experiences.

VR Hand Tracking Animation

Create animations that respond to hand tracking.

using AnimatixPro.GraphFlow;
using UnityEngine;
using UnityEngine.XR;

public class VRHandTrackingExample : MonoBehaviour
{
[SerializeField] private GraphFlowAsset handOpenAnimation;
[SerializeField] private GraphFlowAsset handCloseAnimation;
[SerializeField] private GraphFlowAsset handPointAnimation;
[SerializeField] private Transform leftHand;
[SerializeField] private Transform rightHand;
[SerializeField] private float gestureThreshold = 0.8f;

private GraphExecutor graphExecutor;
private bool isLeftHandOpen = false;
private bool isRightHandOpen = false;
private bool isLeftHandPointing = false;
private bool isRightHandPointing = false;

private void Start()
{
graphExecutor = GetComponent<GraphExecutor>();
if (graphExecutor == null)
{
graphExecutor = gameObject.AddComponent<GraphExecutor>();
}
}

private void Update()
{
HandleHandTracking();
}

private void HandleHandTracking()
{
// Get hand tracking data (this would integrate with your VR SDK)
float leftHandOpenness = GetHandOpenness(XRNode.LeftHand);
float rightHandOpenness = GetHandOpenness(XRNode.RightHand);
bool leftHandPointing = GetHandPointing(XRNode.LeftHand);
bool rightHandPointing = GetHandPointing(XRNode.RightHand);

// Handle left hand gestures
HandleHandGesture(leftHandOpenness, leftHandPointing, true);

// Handle right hand gestures
HandleHandGesture(rightHandOpenness, rightHandPointing, false);
}

private void HandleHandGesture(float openness, bool pointing, bool isLeftHand)
{
if (pointing)
{
if (isLeftHand && !isLeftHandPointing)
{
isLeftHandPointing = true;
PlayHandAnimation(handPointAnimation, leftHand);
}
else if (!isLeftHand && !isRightHandPointing)
{
isRightHandPointing = true;
PlayHandAnimation(handPointAnimation, rightHand);
}
}
else
{
if (isLeftHand && isLeftHandPointing)
{
isLeftHandPointing = false;
}
else if (!isLeftHand && isRightHandPointing)
{
isRightHandPointing = false;
}

// Handle open/close gestures
if (openness > gestureThreshold)
{
if (isLeftHand && !isLeftHandOpen)
{
isLeftHandOpen = true;
PlayHandAnimation(handOpenAnimation, leftHand);
}
else if (!isLeftHand && !isRightHandOpen)
{
isRightHandOpen = true;
PlayHandAnimation(handOpenAnimation, rightHand);
}
}
else
{
if (isLeftHand && isLeftHandOpen)
{
isLeftHandOpen = false;
PlayHandAnimation(handCloseAnimation, leftHand);
}
else if (!isLeftHand && isRightHandOpen)
{
isRightHandOpen = false;
PlayHandAnimation(handCloseAnimation, rightHand);
}
}
}
}

private void PlayHandAnimation(GraphFlowAsset animation, Transform hand)
{
if (animation != null && hand != null)
{
// Create a temporary GraphExecutor for this hand
GraphExecutor handExecutor = hand.GetComponent<GraphExecutor>();
if (handExecutor == null)
{
handExecutor = hand.gameObject.AddComponent<GraphExecutor>();
}

handExecutor.SetGraphFlowAsset(animation);
handExecutor.Play();
}
}

private float GetHandOpenness(XRNode hand)
{
// This would integrate with your VR SDK's hand tracking
// For example, with Oculus Integration:
// return OVRInput.Get(OVRInput.Axis1D.PrimaryHandTrigger, hand == XRNode.LeftHand ? OVRInput.Controller.LTouch : OVRInput.Controller.RTouch);

// Placeholder implementation
return Input.GetAxis("HandOpenness");
}

private bool GetHandPointing(XRNode hand)
{
// This would integrate with your VR SDK's hand tracking
// Placeholder implementation
return Input.GetKey(hand == XRNode.LeftHand ? KeyCode.Q : KeyCode.E);
}
}

VR Object Interaction

Create animations for VR object interactions.

using AnimatixPro.GraphFlow;
using UnityEngine;
using UnityEngine.XR;

public class VRObjectInteractionExample : MonoBehaviour
{
[SerializeField] private GraphFlowAsset grabAnimation;
[SerializeField] private GraphFlowAsset releaseAnimation;
[SerializeField] private GraphFlowAsset hoverAnimation;
[SerializeField] private Transform vrHand;
[SerializeField] private float interactionDistance = 0.1f;

private GraphExecutor graphExecutor;
private bool isGrabbed = false;
private bool isHovered = false;
private Transform originalParent;
private Vector3 originalPosition;
private Quaternion originalRotation;

private void Start()
{
graphExecutor = GetComponent<GraphExecutor>();
if (graphExecutor == null)
{
graphExecutor = gameObject.AddComponent<GraphExecutor>();
}

originalParent = transform.parent;
originalPosition = transform.position;
originalRotation = transform.rotation;
}

private void Update()
{
HandleVRInteraction();
}

private void HandleVRInteraction()
{
if (vrHand == null) return;

float distance = Vector3.Distance(transform.position, vrHand.position);
bool isInRange = distance <= interactionDistance;

// Handle hover state
if (isInRange && !isHovered)
{
StartHover();
}
else if (!isInRange && isHovered)
{
StopHover();
}

// Handle grab/release
if (isInRange && GetGrabInput() && !isGrabbed)
{
GrabObject();
}
else if (isGrabbed && !GetGrabInput())
{
ReleaseObject();
}

// Handle grabbed object movement
if (isGrabbed)
{
UpdateGrabbedObject();
}
}

private void StartHover()
{
isHovered = true;

if (hoverAnimation != null)
{
graphExecutor.SetGraphFlowAsset(hoverAnimation);
graphExecutor.Play();
}
}

private void StopHover()
{
isHovered = false;

if (graphExecutor.IsPlaying())
{
graphExecutor.Stop();
}
}

private void GrabObject()
{
isGrabbed = true;

if (grabAnimation != null)
{
graphExecutor.SetGraphFlowAsset(grabAnimation);
graphExecutor.Play();
}

// Parent to hand for movement
transform.SetParent(vrHand);
}

private void ReleaseObject()
{
isGrabbed = false;

if (releaseAnimation != null)
{
graphExecutor.SetGraphFlowAsset(releaseAnimation);
graphExecutor.Play();
}

// Return to original parent
transform.SetParent(originalParent);
}

private void UpdateGrabbedObject()
{
// Smoothly follow hand position
transform.position = Vector3.Lerp(transform.position, vrHand.position, Time.deltaTime * 10f);
transform.rotation = Quaternion.Lerp(transform.rotation, vrHand.rotation, Time.deltaTime * 10f);
}

private bool GetGrabInput()
{
// This would integrate with your VR SDK's input system
// For example, with Oculus Integration:
// return OVRInput.Get(OVRInput.Button.PrimaryHandTrigger, OVRInput.Controller.RTouch);

// Placeholder implementation
return Input.GetKey(KeyCode.G);
}
}

AR Animation Examples

Complete AR animation examples for augmented reality experiences.

AR Object Placement

Create animations for AR object placement.

using AnimatixPro.GraphFlow;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class ARObjectPlacementExample : MonoBehaviour
{
[SerializeField] private GraphFlowAsset placementAnimation;
[SerializeField] private GraphFlowAsset selectionAnimation;
[SerializeField] private GameObject arObjectPrefab;
[SerializeField] private ARRaycastManager raycastManager;
[SerializeField] private Camera arCamera;

private GraphExecutor graphExecutor;
private GameObject placedObject;
private bool isPlacing = false;

private void Start()
{
graphExecutor = GetComponent<GraphExecutor>();
if (graphExecutor == null)
{
graphExecutor = gameObject.AddComponent<GraphExecutor>();
}
}

private void Update()
{
HandleARPlacement();
}

private void HandleARPlacement()
{
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);

if (touch.phase == TouchPhase.Began)
{
TryPlaceObject(touch.position);
}
}

// Handle mouse input for testing
if (Input.GetMouseButtonDown(0))
{
TryPlaceObject(Input.mousePosition);
}
}

private void TryPlaceObject(Vector2 screenPosition)
{
if (isPlacing) return;

List<ARRaycastHit> hits = new List<ARRaycastHit>();

if (raycastManager.Raycast(screenPosition, hits, TrackableType.PlaneWithinPolygon))
{
ARRaycastHit hit = hits[0];
Vector3 worldPosition = hit.pose.position;

if (placedObject == null)
{
PlaceObject(worldPosition);
}
else
{
MoveObject(worldPosition);
}
}
}

private void PlaceObject(Vector3 position)
{
isPlacing = true;

// Create AR object
placedObject = Instantiate(arObjectPrefab, position, Quaternion.identity);

// Play placement animation
if (placementAnimation != null)
{
GraphExecutor objectExecutor = placedObject.GetComponent<GraphExecutor>();
if (objectExecutor == null)
{
objectExecutor = placedObject.AddComponent<GraphExecutor>();
}

objectExecutor.SetGraphFlowAsset(placementAnimation);
objectExecutor.Play();
}

isPlacing = false;
}

private void MoveObject(Vector3 position)
{
if (placedObject == null) return;

// Smoothly move object to new position
StartCoroutine(MoveObjectCoroutine(placedObject.transform, position));
}

private System.Collections.IEnumerator MoveObjectCoroutine(Transform objectTransform, Vector3 targetPosition)
{
Vector3 startPosition = objectTransform.position;
float elapsed = 0f;
float duration = 0.5f;

while (elapsed < duration)
{
elapsed += Time.deltaTime;
float progress = elapsed / duration;
objectTransform.position = Vector3.Lerp(startPosition, targetPosition, progress);
yield return null;
}

objectTransform.position = targetPosition;
}
}

AR Face Tracking

Create animations that respond to face tracking.

using AnimatixPro.GraphFlow;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class ARFaceTrackingExample : MonoBehaviour
{
[SerializeField] private GraphFlowAsset smileAnimation;
[SerializeField] private GraphFlowAsset frownAnimation;
[SerializeField] private GraphFlowAsset winkAnimation;
[SerializeField] private ARFaceManager faceManager;
[SerializeField] private float expressionThreshold = 0.5f;

private GraphExecutor graphExecutor;
private bool isSmiling = false;
private bool isFrowning = false;
private bool isWinking = false;

private void Start()
{
graphExecutor = GetComponent<GraphExecutor>();
if (graphExecutor == null)
{
graphExecutor = gameObject.AddComponent<GraphExecutor>();
}
}

private void Update()
{
HandleFaceTracking();
}

private void HandleFaceTracking()
{
if (faceManager == null) return;

// Get face tracking data
foreach (var face in faceManager.trackables)
{
if (face.trackingState == TrackingState.Tracking)
{
// Get facial expressions (this would integrate with your AR SDK)
float smileValue = GetSmileValue(face);
float frownValue = GetFrownValue(face);
bool isWinkingLeft = GetWinkValue(face, true);
bool isWinkingRight = GetWinkValue(face, false);

// Handle smile expression
if (smileValue > expressionThreshold && !isSmiling)
{
isSmiling = true;
PlayExpressionAnimation(smileAnimation);
}
else if (smileValue <= expressionThreshold && isSmiling)
{
isSmiling = false;
}

// Handle frown expression
if (frownValue > expressionThreshold && !isFrowning)
{
isFrowning = true;
PlayExpressionAnimation(frownAnimation);
}
else if (frownValue <= expressionThreshold && isFrowning)
{
isFrowning = false;
}

// Handle wink expression
if ((isWinkingLeft || isWinkingRight) && !isWinking)
{
isWinking = true;
PlayExpressionAnimation(winkAnimation);
}
else if (!isWinkingLeft && !isWinkingRight && isWinking)
{
isWinking = false;
}
}
}
}

private void PlayExpressionAnimation(GraphFlowAsset animation)
{
if (animation != null)
{
graphExecutor.SetGraphFlowAsset(animation);
graphExecutor.Play();
}
}

private float GetSmileValue(ARFace face)
{
// This would integrate with your AR SDK's face tracking
// Placeholder implementation
return Input.GetAxis("Smile");
}

private float GetFrownValue(ARFace face)
{
// This would integrate with your AR SDK's face tracking
// Placeholder implementation
return Input.GetAxis("Frown");
}

private bool GetWinkValue(ARFace face, bool leftEye)
{
// This would integrate with your AR SDK's face tracking
// Placeholder implementation
return Input.GetKey(leftEye ? KeyCode.LeftArrow : KeyCode.RightArrow);
}
}

📱 Mobile Animation Examples

Touch Gesture Animations

Complete touch gesture examples for mobile devices.

Pinch Zoom Animation

Create pinch zoom animations for mobile interfaces.

using AnimatixPro.GraphFlow;
using UnityEngine;

public class PinchZoomExample : MonoBehaviour
{
[SerializeField] private GraphFlowAsset zoomInAnimation;
[SerializeField] private GraphFlowAsset zoomOutAnimation;
[SerializeField] private float minScale = 0.5f;
[SerializeField] private float maxScale = 3f;
[SerializeField] private float zoomSpeed = 2f;

private GraphExecutor graphExecutor;
private float initialDistance = 0f;
private float initialScale = 1f;
private bool isZooming = false;

private void Start()
{
graphExecutor = GetComponent<GraphExecutor>();
if (graphExecutor == null)
{
graphExecutor = gameObject.AddComponent<GraphExecutor>();
}
}

private void Update()
{
HandlePinchZoom();
}

private void HandlePinchZoom()
{
if (Input.touchCount == 2)
{
Touch touch1 = Input.GetTouch(0);
Touch touch2 = Input.GetTouch(1);

if (touch1.phase == TouchPhase.Began || touch2.phase == TouchPhase.Began)
{
initialDistance = Vector2.Distance(touch1.position, touch2.position);
initialScale = transform.localScale.x;
isZooming = true;
}
else if (touch1.phase == TouchPhase.Moved || touch2.phase == TouchPhase.Moved)
{
if (isZooming)
{
float currentDistance = Vector2.Distance(touch1.position, touch2.position);
float scaleFactor = currentDistance / initialDistance;
float newScale = initialScale * scaleFactor;

// Clamp scale
newScale = Mathf.Clamp(newScale, minScale, maxScale);

// Apply scale
transform.localScale = Vector3.one * newScale;

// Play appropriate animation
if (scaleFactor > 1.1f && zoomInAnimation != null)
{
graphExecutor.SetGraphFlowAsset(zoomInAnimation);
graphExecutor.Play();
}
else if (scaleFactor < 0.9f && zoomOutAnimation != null)
{
graphExecutor.SetGraphFlowAsset(zoomOutAnimation);
graphExecutor.Play();
}
}
}
}
else
{
isZooming = false;
}
}
}

Swipe Navigation Animation

Create swipe navigation animations for mobile interfaces.

using AnimatixPro.GraphFlow;
using UnityEngine;

public class SwipeNavigationExample : MonoBehaviour
{
[SerializeField] private GraphFlowAsset swipeLeftAnimation;
[SerializeField] private GraphFlowAsset swipeRightAnimation;
[SerializeField] private GraphFlowAsset swipeUpAnimation;
[SerializeField] private GraphFlowAsset swipeDownAnimation;
[SerializeField] private float swipeThreshold = 50f;
[SerializeField] private float swipeSpeed = 5f;

private GraphExecutor graphExecutor;
private Vector2 startTouchPosition;
private Vector2 endTouchPosition;
private bool isSwiping = false;

private void Start()
{
graphExecutor = GetComponent<GraphExecutor>();
if (graphExecutor == null)
{
graphExecutor = gameObject.AddComponent<GraphExecutor>();
}
}

private void Update()
{
HandleSwipeInput();
}

private void HandleSwipeInput()
{
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);

if (touch.phase == TouchPhase.Began)
{
startTouchPosition = touch.position;
isSwiping = true;
}
else if (touch.phase == TouchPhase.Ended && isSwiping)
{
endTouchPosition = touch.position;
ProcessSwipe();
isSwiping = false;
}
}

// Handle mouse input for testing
if (Input.GetMouseButtonDown(0))
{
startTouchPosition = Input.mousePosition;
isSwiping = true;
}
else if (Input.GetMouseButtonUp(0) && isSwiping)
{
endTouchPosition = Input.mousePosition;
ProcessSwipe();
isSwiping = false;
}
}

private void ProcessSwipe()
{
Vector2 swipeDirection = endTouchPosition - startTouchPosition;
float swipeDistance = swipeDirection.magnitude;

if (swipeDistance > swipeThreshold)
{
swipeDirection.Normalize();

if (Mathf.Abs(swipeDirection.x) > Mathf.Abs(swipeDirection.y))
{
// Horizontal swipe
if (swipeDirection.x > 0)
{
SwipeRight();
}
else
{
SwipeLeft();
}
}
else
{
// Vertical swipe
if (swipeDirection.y > 0)
{
SwipeUp();
}
else
{
SwipeDown();
}
}
}
}

private void SwipeLeft()
{
if (swipeLeftAnimation != null)
{
graphExecutor.SetGraphFlowAsset(swipeLeftAnimation);
graphExecutor.Play();
}
}

private void SwipeRight()
{
if (swipeRightAnimation != null)
{
graphExecutor.SetGraphFlowAsset(swipeRightAnimation);
graphExecutor.Play();
}
}

private void SwipeUp()
{
if (swipeUpAnimation != null)
{
graphExecutor.SetGraphFlowAsset(swipeUpAnimation);
graphExecutor.Play();
}
}

private void SwipeDown()
{
if (swipeDownAnimation != null)
{
graphExecutor.SetGraphFlowAsset(swipeDownAnimation);
graphExecutor.Play();
}
}
}

Mobile UI Animations

Complete mobile UI animation examples.

Mobile Menu Animation

Create mobile-optimized menu animations.

using AnimatixPro.GraphFlow;
using UnityEngine;
using UnityEngine.UI;

public class MobileMenuExample : MonoBehaviour
{
[SerializeField] private GraphFlowAsset menuSlideInAnimation;
[SerializeField] private GraphFlowAsset menuSlideOutAnimation;
[SerializeField] private RectTransform menuPanel;
[SerializeField] private Button menuButton;
[SerializeField] private Button closeButton;
[SerializeField] private bool isMenuOpen = false;

private GraphExecutor graphExecutor;
private bool isAnimating = false;

private void Start()
{
graphExecutor = GetComponent<GraphExecutor>();
if (graphExecutor == null)
{
graphExecutor = gameObject.AddComponent<GraphExecutor>();
}

// Initially hide menu
menuPanel.gameObject.SetActive(false);

// Set up button events
menuButton.onClick.AddListener(ToggleMenu);
closeButton.onClick.AddListener(CloseMenu);
}

private void ToggleMenu()
{
if (isAnimating) return;

if (isMenuOpen)
{
CloseMenu();
}
else
{
OpenMenu();
}
}

private void OpenMenu()
{
if (isAnimating) return;

StartCoroutine(OpenMenuCoroutine());
}

private void CloseMenu()
{
if (isAnimating) return;

StartCoroutine(CloseMenuCoroutine());
}

private System.Collections.IEnumerator OpenMenuCoroutine()
{
isAnimating = true;
isMenuOpen = true;

// Show menu panel
menuPanel.gameObject.SetActive(true);

// Play slide in animation
if (menuSlideInAnimation != null)
{
graphExecutor.SetGraphFlowAsset(menuSlideInAnimation);
graphExecutor.Play();

yield return new WaitUntil(() => !graphExecutor.IsPlaying());
}

isAnimating = false;
}

private System.Collections.IEnumerator CloseMenuCoroutine()
{
isAnimating = true;
isMenuOpen = false;

// Play slide out animation
if (menuSlideOutAnimation != null)
{
graphExecutor.SetGraphFlowAsset(menuSlideOutAnimation);
graphExecutor.Play();

yield return new WaitUntil(() => !graphExecutor.IsPlaying());
}

// Hide menu panel
menuPanel.gameObject.SetActive(false);

isAnimating = false;
}
}

Mobile Notification Animation

Create mobile-optimized notification animations.

using AnimatixPro.GraphFlow;
using UnityEngine;
using UnityEngine.UI;

public class MobileNotificationExample : MonoBehaviour
{
[SerializeField] private GraphFlowAsset notificationSlideInAnimation;
[SerializeField] private GraphFlowAsset notificationSlideOutAnimation;
[SerializeField] private RectTransform notificationPanel;
[SerializeField] private Text notificationText;
[SerializeField] private Button dismissButton;
[SerializeField] private float displayDuration = 3f;

private GraphExecutor graphExecutor;
private bool isShowing = false;
private bool isAnimating = false;

private void Start()
{
graphExecutor = GetComponent<GraphExecutor>();
if (graphExecutor == null)
{
graphExecutor = gameObject.AddComponent<GraphExecutor>();
}

// Initially hide notification
notificationPanel.gameObject.SetActive(false);

// Set up button events
dismissButton.onClick.AddListener(DismissNotification);
}

public void ShowNotification(string message)
{
if (isShowing || isAnimating) return;

StartCoroutine(ShowNotificationCoroutine(message));
}

private System.Collections.IEnumerator ShowNotificationCoroutine(string message)
{
isShowing = true;
isAnimating = true;

// Set message and show panel
notificationText.text = message;
notificationPanel.gameObject.SetActive(true);

// Play slide in animation
if (notificationSlideInAnimation != null)
{
graphExecutor.SetGraphFlowAsset(notificationSlideInAnimation);
graphExecutor.Play();

yield return new WaitUntil(() => !graphExecutor.IsPlaying());
}

isAnimating = false;

// Wait for display duration
yield return new WaitForSeconds(displayDuration);

// Auto-dismiss if not manually dismissed
if (isShowing)
{
yield return StartCoroutine(DismissNotificationCoroutine());
}
}

private void DismissNotification()
{
if (!isShowing || isAnimating) return;

StartCoroutine(DismissNotificationCoroutine());
}

private System.Collections.IEnumerator DismissNotificationCoroutine()
{
isAnimating = true;
isShowing = false;

// Play slide out animation
if (notificationSlideOutAnimation != null)
{
graphExecutor.SetGraphFlowAsset(notificationSlideOutAnimation);
graphExecutor.Play();

yield return new WaitUntil(() => !graphExecutor.IsPlaying());
}

// Hide notification panel
notificationPanel.gameObject.SetActive(false);

isAnimating = false;
}
}

🚀 Performance Optimization

VR/AR Performance Best Practices

  • Optimize for 90fps for VR experiences
  • Use efficient rendering for AR overlays
  • Limit simultaneous animations to prevent frame drops
  • Test on actual devices for accurate performance

Mobile Performance Best Practices

  • Optimize for 60fps on mobile devices
  • Use efficient touch handling for smooth interactions
  • Limit animation complexity for better performance
  • Test on various devices for compatibility

🎉 What's Next?

Now that you understand VR/AR and mobile animations:

📚 Learn More

🎯 Try These Examples


🎊 VR/AR & Mobile mastery achieved! You're ready to create immersive experiences!

Let's explore the API! Check out the API Reference guide!