Files
obsidian-vault/personal/projects/psychologist-app/character-design.md
T

824 lines
43 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Дизайн Анимированного Персонажа для AI-Компаньона (Психологическое Приложение)
> Исследование выполнено: май 2026
> Контекст: персонаж — визуальное лицо AI-компаньона в приложении психологической рефлексии. Абстрактный (не человек, не робот). Реагирует на эмоции и голос пользователя.
---
## 1. Существующие Примеры Абстрактных AI Персонажей
### 1.1 Большие платформы
#### 🔵 Siri (Apple) — Waveform / Орб
- **Эволюция**: Siri прошёл путь от простых волн (iOS 7–12) до живого светящегося шара (iOS 14+) и «гало» вокруг экрана (iOS 18/26)
- **Что работает**: плавные цветовые переходы синий→фиолетовый→розовый ассоциируются с «думающим» AI без антропоморфизации
- **Реализация**: Core Animation + Metal шейдеры; собственный рендер Apple
- **Эмоциональный эффект**: пользователи воспринимают его как «живой», но не угрожающий (Reddit: r/ios26, обсуждение «Type to Siri Wavy Effect»)
- **Референс**: [Apple Human Interface Guidelines — Siri](https://developer.apple.com/design/human-interface-guidelines/siri)
#### 🟡 Alexa (Amazon) — Кольцо/Ring
- **Визуал**: круговое световое кольцо: синий = слушает, оранжевый = нет сети, фиолетовый = не беспокоить, белый = регулировка громкости
- **Что работает**: семиотика цвета как язык состояний — пользователи быстро запоминают коды без слов
- **Ограничение для нашего case**: слишком «железный», не подходит для эмпатийного контекста
#### 🔮 Google Assistant — Точки / G-шар
- **Визуал**: 4 цветные точки (синяя, красная, жёлтая, зелёная), анимирующиеся в вол-ну при активации; позже — 3D светящийся «G»
- **Что работает**: цветовая идентичность бренда, минимализм
- **Ограничение**: слишком корпоративный, не тёплый
#### 🟢 ChatGPT (OpenAI) — Пульсирующий Шар
- **Визуал**: анимированный чёрно-белый шар в голосовом режиме Canvas/voice mode; в web — простая анимация печатающегося текста
- **Решение**: нейтральный ч/б орб не навязывает эмоцию — пользователь сам проецирует
- **Реакция пользователей**: в Reddit threads (r/ChatGPT) отмечают, что голосовой орб ощущается «медитативно», снижает тревогу перед диалогом
#### 🔵 Microsoft Copilot — Градиентная Орбита
- **Визуал**: анимированная орбита из синих и фиолетовых полос, морфирующая при ответе
- **Что работает**: ощущение «умного движения», не угрожающего; подходит для рабочей среды
---
### 1.2 Mental Health / Медитация
#### 🧘 Headspace — «Andy» (апельсиновый шар)
- **Визуал**: простой оранжевый круг с минимальными чертами лица (точки-глаза, дуга-рот)
- **Степень абстракции**: умеренная — есть лицо, но без носа/ушей
- **Что работает**: тёплый цвет = дружелюбие, округлость = безопасность
- **Референс**: [Headspace Design System](https://www.headspace.com/design)
- **Ограничение**: лицо делает его «детским» — не подходит для взрослой аудитории
#### 🌊 Calm — Анимированные Фоны
- **Подход**: Calm отказался от персонажа-компаньона в пользу окружающей среды (вода, листья, луна)
- **Вывод для нас**: персонаж должен быть частью «среды», а не отдельным элементом
#### 💜 Replika (AI Companion) — 3D Аватар
- **Подход**: антропоморфный 3D аватар, настраиваемый пользователем
- **Минус**: тревожная долина (Uncanny Valley), юридические и этические вопросы привязанности
- **Вывод**: НЕ делать антропоморфный. Наш выбор абстракции — правильный
#### 🌿 Woebot — Минималистичный Робот
- **Визуал**: простой квадратный «робот» с экраном-лицом
- **Что работает**: простота снижает тревогу, неантропоморфность делает его «инструментом», а не «существом»
- **Ограничение**: слишком «роботизированный» для эмпатийного контекста
---
### 1.3 Прочие Примеры
#### 🦜 Duolingo — Duo (сова) + Lily
- **Duo**: антропоморфная сова — зелёная, с глазами; огромный успех с точки зрения вовлечённости
- **Lily (AI Video Call, 2025)**: реализован в **Rive** — анимированный персонаж с state machine, живущий в видеозвонке
- **Кейс-стади Rive**: Duolingo использует Rive для интерактивных персонажей, потому что state machine позволяет плавно переходить между сотнями эмоциональных состояний без написания кода вручную
- **Вывод**: Rive — production-proven для персонажей в consumer apps
#### 🎵 Spotify Wrapped 2025
- Реализован в Rive; дизайн отправляет в production интерактивную анимацию, код управляет данными
- **Паттерн**: «design ships interaction in Rive, code drives it with data» — именно то, что нам нужно
#### 🤖 Notion AI — Спиннер-искры
- **Визуал**: анимированные искры/частицы при генерации текста
- **Что работает**: ощущение «творческой энергии», не агрессивное
- **Минус**: статичный, нет эмоциональных состояний
---
## 2. Rive.app — Детальный Разбор
### 2.1 Что такое Rive и зачем он нам
Rive — это инструмент для создания **интерактивных, production-ready анимаций** с встроенной логикой через **State Machine**. В отличие от Lottie (только воспроизведение заранее заданной анимации), Rive позволяет:
- Управлять переходами между состояниями в реальном времени
- Передавать данные из кода (амплитуда звука, состояние AI) прямо в дизайн
- Дизайнер работает в редакторе → разработчик подключает `.riv` файл → интерактивность работает «из коробки»
**Ключевое преимущество для нашего случая**: голосовая реактивность реализуется через **Number input** в State Machine — разработчик передаёт значение (0.0–1.0 от амплитуды микрофона), дизайн реагирует без написания анимационного кода.
---
### 2.2 Rive для iOS — Техническая Интеграция
**Репозиторий**: [github.com/rive-app/rive-ios](https://github.com/rive-app/rive-ios)
- 780 ⭐ | MIT License | v6.20.3 (май 2026) | 239 релизов
**Установка (Swift Package Manager — рекомендуется)**:
```swift
// Package.swift
dependencies: [
.package(url: "https://github.com/rive-app/rive-ios", from: "6.13.0")
]
```
**Требования**: iOS 14.0+, visionOS 1.0+, tvOS 16.0+, macOS 13.1+
**Минимальная интеграция в SwiftUI** (Legacy API — проще для начала):
```swift
import RiveRuntime
struct CharacterView: View {
var body: some View {
RiveViewModel(
fileName: "ai_companion",
stateMachineName: "EmotionMachine"
).view()
}
}
```
**Продвинутая интеграция (новый runtime, Swift Concurrency)**:
```swift
import RiveRuntime
struct CharacterView: View {
@State private var riveView: RiveUIView?
var body: some View {
AsyncRiveUIViewRepresentable {
let worker = try await Worker()
let file = try await File(source: .local("ai_companion", Bundle.main), worker: worker)
return try await Rive(file: file)
}
}
}
```
**Управление через State Machine (Data Binding)**:
```swift
// Передача амплитуды микрофона → анимация
let numberProp = viewModelInstance.numberProperty(fromPath: "audioAmplitude")!
numberProp.value = Float(microphoneAmplitude) // 0.0...1.0
// Изменение эмоционального состояния
let enumProp = viewModelInstance.enumProperty(fromPath: "emotionState")!
enumProp.value = "thinking" // или "speaking", "listening", "happy", "concerned"
```
---
### 2.3 State Machine в Rive — Как Работает
**State Machine** — это граф состояний анимации с переходами.
**Для нашего персонажа**:
```
[Entry] → [Idle/Breathing] ↔ [Listening] ↔ [Thinking] ↔ [Speaking] ↔ [Happy] ↔ [Concerned]
```
**Типы inputs**:
| Тип | Использование |
|-----|--------------|
| `Boolean` | `isListening`, `isSpeaking`, `isThinking` |
| `Number` | `audioAmplitude` (0.01.0), `emotionIntensity` |
| `Trigger` | `onHappy`, `onConcerned`, `onGreet` |
| `Enum` | `currentState` (idle/listen/think/speak/happy/concerned) |
**Settled State**: автоматически останавливает рендеринг когда нет активных переходов → экономит CPU/батарею. Для idle-анимации = зацикленная бесконечная анимация, которая продолжает работать.
**Playback управление**:
```swift
simpleVM.pause() // заморозить на текущем кадре
simpleVM.play() // возобновить с текущей позиции
simpleVM.stop() // сброс к начальному состоянию
simpleVM.reset() // полный сброс state machine
```
---
### 2.4 Голосовая Реактивность: Как Именно
**Схема реализации**:
1. **AVAudioEngine** (iOS) → получаем амплитуду микрофона в реальном времени
2. Нормализуем: `amplitude = (rawValue + 160) / 160` (или другой масштаб)
3. Передаём в Rive через Number property: `audioAmplitude = smoothedAmplitude`
4. В Rive дизайнер привязывает это число к scale/radius/деформации blob
**Код для получения амплитуды**:
```swift
import AVFoundation
class MicrophoneMonitor: ObservableObject {
private var audioEngine = AVAudioEngine()
@Published var amplitude: Float = 0.0
func startMonitoring() {
let inputNode = audioEngine.inputNode
let recordingFormat = inputNode.outputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { buffer, _ in
guard let channelData = buffer.floatChannelData else { return }
let frameLength = Int(buffer.frameLength)
let rms = sqrt(channelData[0][0..<frameLength].map { $0 * $0 }.reduce(0, +) / Float(frameLength))
DispatchQueue.main.async {
// Сглаживание (lerp) для избежания дёргания
self.amplitude = self.amplitude * 0.7 + min(rms * 10, 1.0) * 0.3
}
}
try? audioEngine.start()
}
}
```
**В SwiftUI — связка**:
```swift
struct CharacterContainer: View {
@StateObject private var mic = MicrophoneMonitor()
@State private var riveVM = RiveViewModel(fileName: "companion", stateMachineName: "Main")
var body: some View {
riveVM.view()
.onChange(of: mic.amplitude) { newValue in
riveVM.setInput("audioAmplitude", value: newValue)
}
}
}
```
---
### 2.5 Rive Pricing для Indie Разработчика
| Тариф | Цена | Что важно |
|-------|------|-----------|
| **Free** | $0/мес | Редактор бесплатно, **нельзя экспортировать .riv** файлы для production |
| **Cadet** | **$9/мес** (до 3 сидений) | ✅ Экспорт .riv файлов, неограниченные файлы, все State Machine фичи |
| **Voyager** | $32/мес | Libraries, Embed URL hosting, до 25 сидений |
| **Enterprise** | $120/мес | Для компаний $10M+ выручки |
**Вывод для indie**: **$9/мес (Cadet)** — это всё что нужно для MVP и production. Free можно использовать для прототипирования. Дизайнер тоже работает на Cadet или тебе передаёт .riv файл.
---
### 2.6 Lottie vs Rive — Сравнение для Нашего Use Case
| Критерий | Lottie | Rive |
|----------|--------|------|
| **Интерактивность** | ❌ Только воспроизведение | ✅ State Machine, inputs, data binding |
| **Голосовая реактивность** | ❌ Невозможно нативно | ✅ Number input → real-time |
| **Размер файла** | ~50200KB | ~20100KB (векторный .riv) |
| **Производительность iOS** | Хорошая | Отличная (собственный рендерер на Metal) |
| **Workflow дизайнер** | After Effects → экспорт JSON | Rive Editor (браузер/десктоп) |
| **Стоимость для дизайнера** | AE нужен ($55/мес) | Rive Cadet $9/мес |
| **Обучение разработчика** | 1–2 часа | 4–8 часов |
| **Эмоциональные состояния** | Несколько файлов + код | 1 файл + state machine |
| **Settled state** | ❌ | ✅ Экономия CPU |
| **Итог для нашего проекта** | ❌ Не подходит | ✅ **Единственный правильный выбор** |
**Вердикт**: Lottie — для декоративных анимаций (иконки, сплэш-скрины). Rive — для **интерактивных персонажей с состояниями**. Наш use case = Rive без сомнений.
---
## 3. Четыре Концепта Персонажа
### 🟣 Концепт A: Дышащий Орб ⭐ РЕКОМЕНДУЕМЫЙ
**Визуал**: Сфера диаметром ~120–160pt, светящаяся изнутри, с мягким bloom-эффектом. Базовый цвет — глубокий индиго (#3D2B8F), с внутренним свечением меняющим оттенок по состоянию.
**5 состояний**:
| Состояние | Визуал | Цвет | Поведение |
|-----------|--------|------|-----------|
| **Idle/Breathing** | Медленное расширение-сжатие (±8%), 4 сек цикл | Индиго → тёмно-синий | Почти незаметное «дыхание» |
| **Listening** | Лёгкая пульсация (синхронно с голосом), размер +голос/амплитуда | Синий → бирюзовый (#00C4CC) | Активная реакция на звук |
| **Thinking** | Медленное вращение внутренних частиц/градиента, ±5% размер | Индиго → фиолетовый (#7B4FD4) | Внутреннее движение, «обработка» |
| **Speaking** | Ритмичные волны-пульсы, согласованные с TTS | Тёплый фиолетовый (#9B59B6) | Лёгкие ряби от центра |
| **Happy** | Быстрое «прыжковое» расширение (+20%), возврат | Тёплый персиковый (#FF6B6B → оранжевый) | Burst-эффект |
| **Concerned** | Медленное сжатие (-10%), глубже цвет | Тёмно-синий (#1A237E) | Серьёзность, не пугающая |
**Техническая реализация в Rive**:
1. Основная форма: эллипс с несколькими вложенными эллипсами (layered glow)
2. Внутренний градиент: радиальный, управляется через Number input `colorShift`
3. Размер: scale контролируется через `audioAmplitude` + дополнительные keyframe анимации для каждого состояния
4. Bloom/glow: **Vector Feathering** в Rive (доступен с 2025) — нативный, без растра
5. State machine: 1 Boolean `isActive` + 1 Number `audioAmplitude` + 1 Enum `emotionState`
**SwiftUI реализация** (если без Rive — чистый SwiftUI):
```swift
struct BreathingOrb: View {
@State private var isPulsing = false
@State private var audioAmplitude: CGFloat = 0
var emotionColor: Color = .indigo
var body: some View {
ZStack {
// Внешнее свечение
Circle()
.fill(emotionColor.opacity(0.15))
.frame(width: 200 + audioAmplitude * 40)
.blur(radius: 20)
// Средний слой
Circle()
.fill(
RadialGradient(
colors: [emotionColor.opacity(0.8), emotionColor],
center: .center, startRadius: 10, endRadius: 70
)
)
.frame(width: 130 + audioAmplitude * 30)
.scaleEffect(isPulsing ? 1.05 : 0.97)
// Внутренняя яркость
Circle()
.fill(Color.white.opacity(0.3))
.frame(width: 50)
.offset(x: -15, y: -15)
.blur(radius: 8)
}
.animation(.easeInOut(duration: 2).repeatForever(autoreverses: true), value: isPulsing)
.onAppear { isPulsing = true }
}
}
```
**Эмоциональный тон**: спокойствие, присутствие, безопасность. Пользователь ощущает, что рядом «кто-то» — но не человек, не робот. «Существо света».
**Сложность реализации**:
- DIY SwiftUI: **4/10** (можно сделать за день)
- Rive с дизайнером: **6/10** (1–2 недели работы дизайнера)
---
### 🟡 Концепт B: Поле Частиц
**Визуал**: 50–200 светящихся точек диаметром 2–6pt, формирующих разные паттерны в зависимости от состояния.
**Состояния через паттерны**:
- **Idle**: медленное дрейфование, как звёзды
- **Listening**: частицы притягиваются к центру, образуя «ухо»-форму
- **Thinking**: хаотичное кружение в определённой зоне
- **Speaking**: волнообразное движение от центра
- **Happy**: взрыв наружу + возврат
**Реализация голосовой реактивности**:
```swift
// SpriteKit или SwiftUI Canvas
// audioAmplitude → силовое поле, отталкивающее частицы
// Каждая частица: позиция = basePosition + sin(time + index) * amplitude * 20
```
**Сложность**:
- DIY SwiftUI Canvas/SpriteKit: **7/10**
- Rive: **8/10** (частицы в Rive нетривиальны, лучше через Scripting/Luau)
- **Metal**: 5/10 при наличии знаний Metal Shaders
**Плюсы**: ощущение интеллекта, «нейронная сеть», уникально
**Минусы**: более сложная реализация, может отвлекать от рефлексии; плохо читается при нервозности пользователя
---
### 🟢 Концепт C: Флюидный Blob
**Визуал**: органическая морфирующая форма — как капля ртути или живая клетка. Постоянно деформируется, «перетекает».
**Референсы в продуктах**:
- **iOS 17 Dynamic Island** — blob-морфинг для уведомлений → пользователи полюбили
- **Headspace «sleep sounds»** анимации — флюидные формы воды
- **Adobe Creative Cloud** онбординг (2021) — морфирующие blob-переходы
**Реализация**:
*Вариант 1 — SwiftUI Canvas + CGPath*:
```swift
// Генерация blob через control points
func blobPath(points: [CGPoint], smoothing: CGFloat) -> Path {
// Catmull-Rom сплайны между точками
// audioAmplitude → смещение контрольных точек
}
```
*Вариант 2 — Metal Shader (лучший результат)*:
```metal
// Метаболы (metaballs) — классическая техника для blob
// distance = sqrt(dx*dx + dy*dy)
// field += radius*radius / distance
// Если field > threshold → рисуем пиксель
```
*Вариант 3 — Rive с mesh deformation*:
- Rive поддерживает **Meshes** (деформация сетки) — дизайнер создаёт blob-форму, задаёт точки деформации, управляемые через inputs
- Сложность в Rive: **8/10**
**Голосовая реактивность**: amплитуда → displacement map → blob «вздрагивает» синхронно с речью
**Плюсы**: максимальная «живость», визуально уникален, метафора «жидкого интеллекта»
**Минусы**: сложная реализация без дизайнера, может вызывать тревогу (нестабильная форма ≠ спокойствие)
**Сложность**: DIY Metal: **8/10**, DIY SwiftUI: **6/10**, Rive с дизайнером: **7/10**
---
### 🔵 Концепт D: Аудио-Волна
**Визуал**: waveform-визуализация, реагирующая на голос — как старый Siri (iOS 7–9) или осциллограф.
**Варианты формы**:
- Классическая waveform (вертикальные полосы переменной высоты)
- Синусоида (гладкая волна)
- Круговая waveform (волна по окружности)
- «Сердцебиение» (EKG-стиль)
**SwiftUI реализация (круговая)**:
```swift
struct AudioWaveformView: View {
var amplitudes: [Float] // массив ~64 значений
var color: Color = .purple
var body: some View {
Canvas { context, size in
let center = CGPoint(x: size.width/2, y: size.height/2)
let baseRadius: CGFloat = 60
var path = Path()
for (i, amp) in amplitudes.enumerated() {
let angle = Double(i) / Double(amplitudes.count) * 2 * .pi
let r = baseRadius + CGFloat(amp) * 40
let x = center.x + cos(angle) * r
let y = center.y + sin(angle) * r
if i == 0 { path.move(to: CGPoint(x: x, y: y)) }
else { path.addLine(to: CGPoint(x: x, y: y)) }
}
path.closeSubpath()
context.fill(path, with: .color(color.opacity(0.7)))
context.stroke(path, with: .color(color), lineWidth: 2)
}
}
}
```
**Плюсы**:
- Максимально простая реализация (DIY: **2/10**)
- Мгновенная связь аудио → визуал понятна пользователю
- Ощущение «технологичности»
**Минусы для психологического контекста**:
- **Холодный, технический** — не тёплый
- Siri давно переехал от waveform именно потому что она не вызывала эмпатии
- Плохо передаёт «мышление» — только «говорение»/«слушание»
- Нет визуального способа показать «обеспокоенность» или «радость»
**Вывод**: Концепт D хорош как **дополнительный элемент** (показывать waveform голоса пользователя внизу экрана), но НЕ как основной персонаж.
---
## 4. Поиск Motion Дизайнера
### 4.1 Где Искать
| Платформа | Специфика | Ссылка |
|-----------|-----------|--------|
| **Rive Marketplace «For Hire»** | Дизайнеры специально рекламируют Rive-навыки | [rive.app/marketplace/for-hire](https://rive.app/marketplace/for-hire/) |
| **Twitter/X @rive_app** | Официальный аккаунт; в ответах и RT часто появляются авторы | twitter.com/rive_app |
| **Dribbble #rive** | Фильтр по тегу; смотри работы со state machine видео | dribbble.com/tags/rive |
| **Upwork** | Поиск «Rive animation designer»; ~$3080/час | upwork.com |
| **Toptal** | Топ 3% фрилансеров; $80–150/час; медленный онбординг | toptal.com |
| **Discord Rive Community** | #for-hire канал; сообщество ~15K человек | discord.com/invite/FGjmaTr |
| **Behance** | Поиск «Rive character animation»; не всегда указывают Rive явно | behance.net |
| **LinkedIn** | «Rive motion designer iOS» → фильтр по навыкам | linkedin.com |
**Самый быстрый путь**: Rive Discord #for-hire + Rive Marketplace For Hire
---
### 4.2 Шаблон Брифа для Motion Дизайнера
```markdown
## Проект: AI-компаньон для приложения психологической рефлексии
### Контекст
Мобильное приложение (iOS/Android) для ежедневной психологической рефлексии с AI-компаньоном.
Аудитория: взрослые 25–45 лет, работают со стрессом, ищут поддержку.
### Задача
Разработать абстрактного анимированного персонажа — визуальное лицо AI-компаньона.
**НЕ**: человек, робот, животное.
**ДА**: орб, blob, абстрактная форма — тёплая, живая, доверительная.
### Концепт (базовый)
[Концепт A: Дышащий орб] — светящаяся сфера ~140pt, с мягким bloom-эффектом.
Референсы: ChatGPT voice mode orb, Apple Siri (iOS 16), Headspace Andy (стиль — не копия).
### Состояния (5 обязательных + idle)
1. **Idle/Breathing** — медленное дыхание, базовый цвет (индиго/фиолетовый)
2. **Listening** — реактивный к амплитуде звука через Number input `audioAmplitude` (0.01.0)
3. **Thinking** — внутреннее движение, «обрабатываю»
4. **Speaking** — пульс/волны при TTS
5. **Happy/Positive** — тёплый burst
6. **Concerned/Serious** — сдержанность, глубокий цвет
### Технические требования
- **Инструмент**: Rive (обязательно)
- **Deliverable**: `.riv` файл с настроенной State Machine
- **State Machine inputs**:
- `audioAmplitude` (Number, 0.01.0) — голосовая реактивность
- `emotionState` (Enum: idle/listening/thinking/speaking/happy/concerned)
- **Размер артборда**: 300×300pt (векторный, масштабируемый)
- **Производительность**: файл должен работать в 60fps на iPhone 12 и новее
- Использовать Vector Feathering для glow (не PNG/растр)
### Что включает deliverable
- [ ] Концепт (2–3 варианта визуала) — для согласования
- [ ] Финальный `.riv` файл со state machine
- [ ] Короткое видео-демо всех состояний (GIF или MP4)
- [ ] Инструкция по inputs для разработчика (1 страница)
### Бюджет ориентировочно
$300–600 (уточняем после концепта)
### Сроки
Концепт: 3–5 дней
Финальный файл: 7–14 дней после согласования
### Контакт / Портфолио
Прошу показать примеры работ с Rive State Machine (не просто Lottie/AE).
```
---
### 4.3 Реалистичная Стоимость
| Уровень дизайнера | Профиль | Концепт + 5 состояний + .riv | Сроки |
|-------------------|---------|------------------------------|-------|
| **Junior Rive** | Upwork, 12 года опыта | $150–300 | 1021 день |
| **Mid-level** | Upwork/Dribbble, портфолио Rive | **$300600** ✅ *sweet spot* | 714 дней |
| **Senior/Студия** | Toptal, известные имена | $800–2000+ | 1430 дней |
| **Готовый шаблон** | Marketplace + кастомизация | $050 + $100200 dev time | 25 дней |
**Реалистичная цена для MVP**: **$300–500** за полный пакет (концепт + 5 состояний + .riv файл)
---
### 4.4 Готовые Персонажи на Маркетплейсах
**Rive Marketplace** ([rive.app/marketplace](https://rive.app/marketplace)):
- Теги для поиска: `orb`, `blob`, `character`, `loader`, `mascot`
- Большинство файлов **бесплатны** для просмотра/ремикса с attribution
- Некоторые продаются за $5–30
**Рекомендуемый поиск**:
- `site:rive.app/community orb animation`
- `site:rive.app/community blob character state machine`
**LottieFiles** (для Lottie) — не подходит для нашего interactive use case, но можно найти вдохновение: lottiefiles.com/search?q=orb+ai+character
**Другие источники готовых Rive файлов**:
- **awesome-rive**: [github.com/rive-app/awesome-rive](https://github.com/rive-app/awesome-rive) — кураторский список
- **Gumroad** + поиск «Rive character»
- **Creative Market** + поиск «Rive animation»
---
## 5. DIY Вариант
### 5.1 Можно ли Без Дизайнера?
**Да, и вот почему это разумно для TestFlight MVP**:
- Для бета-тестирования важно проверить *концепцию взаимодействия*, а не полировку
- SwiftUI Canvas + TimelineView позволяет сделать «достаточно хороший» орб за 1–2 дня
- После валидации концепции → нанять дизайнера для production-версии
### 5.2 Минимальная Версия для TestFlight
**Что должна уметь (MVP)**:
- [x] Визуально отличаться в 3+ состояниях (idle, listening, speaking)
- [x] Реагировать на амплитуду микрофона (пульс/размер)
- [x] Плавные переходы между состояниями (withAnimation + ease)
- [x] Работать в 60fps без прыжков
- [x] Не выглядеть «сломанной» при любом сценарии
**Что НЕ нужно для MVP**:
- Профессиональный Rive-файл
- Все 6 эмоциональных состояний
- Идеальный bloom/glow
### 5.3 Полный SwiftUI Орб — Структура Кода
```swift
import SwiftUI
import AVFoundation
// MARK: - Состояния персонажа
enum CompanionState {
case idle, listening, thinking, speaking, happy, concerned
var color: Color {
switch self {
case .idle: return Color(hex: "#3D2B8F") // индиго
case .listening: return Color(hex: "#00C4CC") // бирюзовый
case .thinking: return Color(hex: "#7B4FD4") // фиолетовый
case .speaking: return Color(hex: "#9B59B6") // тёплый фиолетовый
case .happy: return Color(hex: "#FF6B6B") // персиковый
case .concerned: return Color(hex: "#1A237E") // тёмно-синий
}
}
var pulseSpeed: Double {
switch self {
case .idle: return 3.0
case .listening: return 1.5
case .thinking: return 2.0
case .speaking: return 0.8
case .happy: return 0.5
case .concerned: return 4.0
}
}
var baseScale: CGFloat {
switch self {
case .idle: return 1.0
case .listening: return 1.05
case .thinking: return 0.97
case .speaking: return 1.03
case .happy: return 1.15
case .concerned: return 0.92
}
}
}
// MARK: - Орб
struct CompanionOrbView: View {
var state: CompanionState
var audioAmplitude: Float // 0.0...1.0
@State private var isBreathing = false
@State private var rotationAngle: Double = 0
private let baseSize: CGFloat = 130
var body: some View {
let amplitudeBoost = CGFloat(audioAmplitude) * 35
let currentSize = baseSize * state.baseScale + amplitudeBoost
ZStack {
// Слой 3: дальнее свечение
Circle()
.fill(state.color.opacity(0.08))
.frame(width: currentSize + 70)
.blur(radius: 30)
// Слой 2: среднее свечение
Circle()
.fill(state.color.opacity(0.2))
.frame(width: currentSize + 30)
.blur(radius: 15)
// Слой 1: основной орб
Circle()
.fill(
RadialGradient(
colors: [
state.color.opacity(0.6),
state.color,
state.color.opacity(0.85)
],
center: .init(x: 0.35, y: 0.3),
startRadius: 5,
endRadius: currentSize / 2
)
)
.frame(width: currentSize, height: currentSize)
.scaleEffect(isBreathing ? 1.04 : 0.97)
// Внутренний блик (имитация 3D)
Ellipse()
.fill(
LinearGradient(
colors: [.white.opacity(0.4), .clear],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)
.frame(width: currentSize * 0.45, height: currentSize * 0.25)
.offset(x: -currentSize * 0.12, y: -currentSize * 0.18)
.blur(radius: 4)
// Вращающийся внутренний элемент (для состояния "thinking")
if state == .thinking {
Circle()
.trim(from: 0, to: 0.3)
.stroke(state.color.opacity(0.5), lineWidth: 2)
.frame(width: currentSize * 0.6)
.rotationEffect(.degrees(rotationAngle))
}
}
.animation(
.easeInOut(duration: state.pulseSpeed).repeatForever(autoreverses: true),
value: isBreathing
)
.animation(.easeInOut(duration: 0.4), value: state)
.animation(.linear(duration: 0.05), value: audioAmplitude)
.onAppear {
isBreathing = true
withAnimation(.linear(duration: 2).repeatForever(autoreverses: false)) {
rotationAngle = 360
}
}
}
}
// MARK: - Контейнер с микрофоном
struct CompanionContainer: View {
@StateObject private var mic = MicrophoneMonitor()
@State var companionState: CompanionState = .idle
var body: some View {
VStack {
Spacer()
CompanionOrbView(state: companionState, audioAmplitude: mic.amplitude)
.frame(width: 220, height: 220)
Spacer()
}
.background(Color(hex: "#0D0D1A")) // тёмный фон
.onAppear { mic.startMonitoring() }
}
}
```
**Оценка результата без дизайнера**: 6.5/10 — выглядит профессионально для бета-тестирования при правильно подобранных цветах.
---
## 6. Сводная Таблица Концептов
| Критерий | A: Орб | B: Частицы | C: Blob | D: Waveform |
|----------|--------|-----------|---------|-------------|
| Эмоциональное тепло | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐ |
| DIY сложность | **4/10** | 7/10 | 6/10 | 2/10 |
| Голосовая реактивность | ✅ Отлично | ✅ Хорошо | ✅ Хорошо | ✅ Отлично |
| Rive реализация | 6/10 | 8/10 | 7/10 | 3/10 |
| Для психологии | ✅✅✅ | ✅✅ | ✅✅ | ⚠️ |
| Уникальность | Средняя | Высокая | Высокая | Низкая |
| Стоимость дизайнера | $300500 | $400700 | $400600 | $150300 |
---
## 7. ✅ Рекомендация и Следующие Шаги
### Рекомендованный Концепт: **A (Дышащий Орб) с элементами C (Blob)**
**Почему**:
1. Орб — самый доказанный паттерн (Siri, ChatGPT, Alexa) — пользователи уже знают этот «язык»
2. Добавление slight fluid-деформации (±blob) делает его уникальным и «живым»
3. Лучший баланс тепла + технологичности для психологического контекста
4. Реалистичен для DIY MVP
5. Хорошо масштабируется до профессиональной Rive-версии
**Цветовая палитра**:
- Base: `#3D2B8F` (тёмный индиго)
- Listening: `#00C4CC` (бирюзовый)
- Thinking: `#7B4FD4` (фиолетовый)
- Speaking: `#9B59B6`
- Happy: `#FF6B6B`
- Concerned: `#1A237E`
- Background: `#0D0D1A` (почти чёрный)
---
### Путь 1: DIY для TestFlight (Рекомендую НАЧАТЬ ЗДЕСЬ)
**Что делать**:
1. Реализовать SwiftUI орб из кода выше (1–2 дня)
2. Подключить AVAudioEngine (1 день)
3. Добавить 3 состояния: idle / listening / speaking (1 день)
4. Запустить TestFlight бета, собрать отзывы (2 недели)
5. Решить — нанимать дизайнера или нет
**Стоимость**: $0 (только время разработчика)
**Срок до TestFlight**: ~57 дней
---
### Путь 2: Hire Motion Designer (После Валидации Концепции)
**Когда нанимать**: после того как бета подтвердит что персонаж нужен и работает
**Где искать**: Rive Discord #for-hire → Rive Marketplace for-hire → Upwork
**Бюджет**: $400–600 за полный пакет
**Что получить**: концепт (2–3 варианта) + .riv файл + state machine + инструкция
**Конкретные шаги**:
1. Написать бриф по шаблону выше
2. Разместить в Rive Discord #for-hire
3. Попросить показать работы именно с Rive State Machine
4. Начать с концепта ($50–100 за концепт) → подтвердить → финальный файл
---
### Инструменты и Ресурсы
| Ресурс | Ссылка |
|--------|--------|
| Rive Editor (бесплатно) | editor.rive.app |
| Rive iOS Runtime | github.com/rive-app/rive-ios |
| Rive Docs iOS | rive.app/docs/runtimes/apple/apple |
| Rive Docs State Machine | rive.app/docs/runtimes/state-machines |
| Rive Community Discord | discord.com/invite/FGjmaTr |
| Rive Marketplace | rive.app/marketplace |
| awesome-rive | github.com/rive-app/awesome-rive |
| Видео: Build iOS App with Rive (DesignCode, 187K views) | youtube.com/watch?v=h4vyOz4Tztg |
| Видео: Build Interactive Characters in Rive (67K views) | youtube.com/watch?v=-vuQvvFiR8s |
| Видео: Glowing Jellyfish (blob референс) | youtube.com/watch?v=4oH0jV-L-dU |
| Видео: Rive State Machine Tutorial | youtube.com/watch?v=oDhdGmXco00 |
---
*Документ создан агентом исследования. Обновить после TestFlight бета (2 недели).*