Más contenido relacionado
La actualidad más candente (20)
Similar a 視聴者参加型のライブ動画を実現!GenvidをUE4に実装する方法 | UNREAL FEST EXTREME 2020 WINTER (20)
Más de エピック・ゲームズ・ジャパン Epic Games Japan (20)
視聴者参加型のライブ動画を実現!GenvidをUE4に実装する方法 | UNREAL FEST EXTREME 2020 WINTER
- 3. #ue4fest#ue4fest
• Genvid 概要
Genvid Technologies Japan K.K.
ビジネスディレクター ジョンソン裕子
スピーカーとアジェンダ
• “In The Black”のUE4側実装方法
Impeller Studios, Inc.
エバンジェリスト Julian Huguet
テクニカルディレクター Noah Brewster
• “In The Black”のオーバーレイ側実装方法
Genvid Technologies, Inc.
ウェブデベロッパー Shuichi Aizawa
- 10. #ue4fest#ue4fest
Genvidで可能になるインタラクション
Tier 1
介入
Tier 2
カスタマイズ
Tier 3
情報表示
視聴者が直接ゲームなどのコンテンツに介入し、プレイヤー
とインタラクションすることが可能に。
(passive input - プレイヤー、他の視聴者にも見える )
(active input - 視聴者が積極的にコンテンツに介入 )
カスタムフィード(chat / data / camera etc.) を提供することで
視聴者がレベルや好みによって視聴体験を調整することが
可能に。
視聴者からベテランまで、視聴者のレベルや好みに応じて
データや情報などをリアルタイムに表示。視聴者の教育や
ビューアビリティの向上が可能に。
- 24. #ue4fest#ue4fest
fetch(endpointURL + "/api/public/channels/join" , {method: "post"})
.then(function(response){ return response.json(); })
.then(function(data) {
let gvClient = genvid.createGenvidClient(data.info, data.uri, data.token, null, {twitchExt: true, silent: false});
gvClient.onAuthenticated(function(success){ /* handler logic */ });
gvClient.onVideoPlayerReady (function(element){ /* handler logic */ });
gvClient.onNotificationsReceived (function(notifications){ /* handler logic */ });
gvClient.onStreamsReceived (function(dataStreams){ /* handler logic */ });
gvClient.onDraw(function(frame) {
// most logic goes here
});
gvClient.start();
})
.catch(function(error){ console.log(error); });
genvid_overlay.js の例
- 26. #ue4fest#ue4fest
gvClient.onDraw(function(frame) {
...
let matchData = JSON.parse(frame.streams.MatchData.data);
let header = document.getElementById('header');
header.querySelector('.header-score-left').innerText = matchData.Score[0].Value;
header.querySelector('.header-score-right' ).innerText = matchData.Score[1].Value;
header.querySelector('.header-location').innerText = matchData.Location;
header.querySelector('.header-time').innerText = matchData.Time;
if (!header.querySelector('.header-name-left').innerText ||
!header.querySelector('.header-name-right' ).innerText) {
header.querySelector('.header-name-left').innerText = matchData.Score[0].Name;
header.querySelector('.header-name-right' ).innerText = matchData.Score[1].Name;
}
...
});
gvClient.onDraw() 例 1: match data
- 28. #ue4fest#ue4fest
gvClient.onDraw(function(frame) {
...
let players = JSON.parse(frame.streams.GameData.data).Players;
miniMapContext.clearRect(0, 0, miniMapCanvas.width, miniMapCanvas.height);
players.forEach((player) => {
let playerImage = getPlayerImage(playerDataMap[player.Name][ 'id'],
player.IsDead,
player.IsFocused,
player.CurrentVehicle.Position.z);
miniMapContext. drawImage(playerImage,
player.CurrentVehicle.Position.x - miniMapCanvas.width /2,
player.CurrentVehicle.Position.y - miniMapCanvas.height /2);
});
...
});
gvClient.onDraw() 例 2: mini map
- 32. #ue4fest#ue4fest
document.getElementById('cheer-button-' + playerName).onclick = function() {
let cheerEvent = {cheer: playerName};
gvClient.sendEventObject(cheerEvent);
}
combatantInfoCardAddBounty .onclick = function() {
let bountyAmount = 1000;
let bountyCost = 1100;
let combatantName = document.getElementById('combatant-info-card-name' ).innerHTML;
let event = {
"key": ["setBounty", combatantName, viewerName],
"value": bountyAmount
}
gvClient.sendEvent([event]);
viewerPoints -= bountyCost;
}
gvClient.sendEvent() 例