Skip to content

Instantly share code, notes, and snippets.

@thammin
Created December 9, 2024 03:05
A simple rive view that draw to full screen RawImage.
using Rive;
using UnityEngine;
using UnityEngine.UI;
public class RiveView : MonoBehaviour
{
public Asset asset;
public RawImage rawImage;
public AudioSource audioSource;
private Artboard _artboard;
private StateMachine _stateMachine;
private RenderTexture _renderTexture;
private RenderQueue _renderQueue;
private Rive.Renderer _riveRenderer;
private AudioEngine _audioEngine;
private bool _wasMouseDown;
private Vector3 _lastMousePoint;
void Start()
{
LoadFile();
BindAudio();
PrepareRenderTarget();
InitializeRenderer();
SetArtboard();
}
void LoadFile()
{
var file = File.Load(asset);
_artboard = file.Artboard(0);
_stateMachine = _artboard?.StateMachine();
}
void PrepareRenderTarget()
{
var size = rawImage.rectTransform.rect.size;
_renderTexture = new RenderTexture(TextureHelper.Descriptor((int)size.x, (int)size.y));
rawImage.texture = _renderTexture;
if (SystemInfo.graphicsUVStartsAtTop)
{
rawImage.rectTransform.localScale = new Vector3(1f, -1f, 1f);
}
}
void InitializeRenderer()
{
_renderQueue = new RenderQueue(_renderTexture, false);
_riveRenderer = _renderQueue.Renderer();
}
void SetArtboard()
{
_riveRenderer.Align(Fit.cover, Alignment.Center, _artboard);
_riveRenderer.Draw(_artboard);
}
void BindAudio()
{
var channelCount = 1;
switch (AudioSettings.speakerMode)
{
case AudioSpeakerMode.Mono:
channelCount = 1;
break;
case AudioSpeakerMode.Stereo:
channelCount = 2;
break;
case AudioSpeakerMode.Quad:
channelCount = 4;
break;
case AudioSpeakerMode.Surround:
channelCount = 5;
break;
case AudioSpeakerMode.Mode5point1:
channelCount = 6;
break;
case AudioSpeakerMode.Mode7point1:
channelCount = 8;
break;
case AudioSpeakerMode.Prologic:
channelCount = 2;
break;
}
_audioEngine = AudioEngine.Make(channelCount, AudioSettings.outputSampleRate);
_artboard.SetAudioEngine(_audioEngine);
}
void Update()
{
ProcessPointer();
_stateMachine?.Advance(Time.deltaTime);
_riveRenderer.Submit();
}
void ProcessPointer()
{
var camera = Camera.main;
var mousePoint = camera.ScreenToViewportPoint(Input.mousePosition);
var riveScreenPoint = new Vector2(
mousePoint.x * camera.pixelWidth,
(1 - mousePoint.y) * camera.pixelHeight
);
if (_lastMousePoint != mousePoint)
{
_stateMachine?.PointerMove(GetRiveLocalPoint(riveScreenPoint, camera.pixelWidth, camera.pixelHeight));
_lastMousePoint = mousePoint;
}
if (Input.GetMouseButtonDown(0))
{
_stateMachine?.PointerDown(GetRiveLocalPoint(riveScreenPoint, camera.pixelWidth, camera.pixelHeight));
_wasMouseDown = true;
}
else if (_wasMouseDown)
{
_wasMouseDown = false;
_stateMachine?.PointerUp(GetRiveLocalPoint(riveScreenPoint, camera.pixelWidth, camera.pixelHeight));
}
}
Vector2 GetRiveLocalPoint(Vector2 riveScreenPoint, int width, int height)
{
return _artboard.LocalCoordinate(
riveScreenPoint,
new Rect(0, 0, width, height),
Fit.cover,
Alignment.Center
);
}
void OnAudioFilterRead(float[] data, int channels)
{
if (_audioEngine == null) return;
_audioEngine.Sum(data, channels);
}
void OnDestroy()
{
_renderTexture?.Release();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment