Created
December 9, 2024 03:05
A simple rive view that draw to full screen RawImage.
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 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