目次

サンプルカメラ

対応バージョンは、UniVCI v0.33以降です。

カメラAPI(ExportPhotographyCamera)のサンプルです。
UniVCIをインポートすると[VCI-Official-Samples > CameraApiSample]内に当サンプルも追加されます。

フォトキャプチャと同等の機能が利用できるVCIです。

サンプルデータ

https://virtualcast.jp/products/9c3b67770dc3523a193ed7829b9a3b77b00cef4f48153dc614fd8d25135a8f35

cameraapisample.zip

コンポーネント設定

VCI Object

Sub Item 設定一覧 (クリックで展開)
VCI Sub Item : ButtonTele

VCI Sub Item : ButtonWide

VCI Sub Item : Camera

VCIスクリプト

main.lua
-- 写真撮影用カメラのサンプル
-- 
-- ※注意※
-- * 本サンプルでは、カメラで撮影した写真と写真のディスプレイを表示するマテリアルが割り当てられているメッシュは、
--   16:9 で UV 割り当てされていることが期待されています
-- 
-- 以下の操作はネットワーク同期されます
-- * ズームアウトボタンをUseすると、カメラがズームアウトします
-- * ズームインボタンをUseすると、カメラがズームインします
 
-- 以下の操作はUseした本人の環境上でのみ実行されます
-- * カメラ本体をUseすると、写真を撮影します
-- * 撮影される写真のプレビューは、カメラ本体の背面のディスプレイに表示されます
-- * 撮影した写真は、カメラ本体下のディスプレイに表示されます
 
local cameraName = "Camera"
local cameraLensAnchorName = "LensAnchor"
 
local wideButtonName = "ButtonWide"
local wideButtonTransform = vci.assets.GetTransform(wideButtonName)
local wideButtonAnchorTransform = vci.assets.GetTransform("ButtonWideAnchor")
local isWideButtonUsed = false
 
local teleButtonName = "ButtonTele"
local teleButtonTransform = vci.assets.GetTransform(teleButtonName)
local teleButtonAnchorTransform = vci.assets.GetTransform("ButtonTeleAnchor")
local isTeleButtonUsed = false
 
local fovStateName = "FOV"
local initialFov = 60
local minFov = 10
local maxFov = 170
local fovStep = 2
 
local previewMaterialName = "Display"
local photoMaterialName = "Photo"
 
local isInitialized = false
local photographyCamera = nil
 
-- 写真撮影時のコールバック
-- * ExportPhotographyCamera.SetOnTakePhotoCallbackにこの関数を渡すことで、 
--   ExportPhotographyCamera.TakePhotograph実行時にこの関数が呼ばれます。
-- * 引数のphotoMetadataの中に、撮影したテクスチャを示すIDが入っています。
-- * そのテクスチャIDをvci.assets.material.SetTextureに渡すことで写真を表示します
-- * また、撮影した写真は5秒間の間のみ表示され、その後真っ黒になります。
function onTakePhotoCallback(photoMetadata)
    local photoTextureId = photoMetadata.textureId
    vci.assets.material.SetTexture(photoMaterialName, photoTextureId)
end
 
-- 写真撮影用カメラ生成
-- * 写真撮影用カメラが生成され、"LensAnchor"のTransformに追従するようになります。
local lensTransform = vci.assets.GetTransform(cameraLensAnchorName)
photographyCamera = vci.cameraSystem.CreatePhotographyCamera(lensTransform)
 
-- プレビュー描画
-- * GetCameraPreviewTextureIdでカメラのプレビューのテクスチャを示すIDを取得します。
-- * このテクスチャIDをvci.assets.material.SetTextureに渡すことでプレビューを表示します。
local previewTextureId = photographyCamera.GetCameraPreviewTextureId()
vci.assets.material.SetTexture(previewMaterialName, previewTextureId)
 
-- 写真撮影時のコールバックをセット
-- * ExportPhotographyCamera.TakePhotograph実行時に、ここで渡した関数が実行されます。
photographyCamera.SetOnTakePhotoCallback(onTakePhotoCallback)
 
-- アイテム内同期変数を初期化
-- * 自身がこのVCIの所有権を持っているときのみ実行します。
if vci.assets.IsMine then
    local isFovInitialized = vci.state.Get(fovStateName) ~= nil
-- カメラの fov が初期化されていない場合、初期化処理を実行する
    if not isFovInitialized then
        print("initialize fov...")
        vci.state.Set(fovStateName, initialFov)
    end
end
 
local initCameraStateCoroutine = coroutine.create(
    function()
        -- アイテム内同期変数の初期化を待つ
        while true do
            local initialFov = vci.state.Get(fovStateName)
            local isFovInitialized = initialFov ~= nil
            if isFovInitialized then
                print("state initialized.")
                -- カメラの垂直FOVの初期値をセット
                photographyCamera.SetVerticalFieldOfView(initialFov)
                break
            end
            print("waiting for state init...")
            coroutine.yield()
        end
        -- カメラの初期化完了
        isInitialized = true
    end
)
 
-- カメラの状態の同期をコルーチンで待つ
vci.StartCoroutine(initCameraStateCoroutine)
 
function updateAll()
    -- ズームアウトのボタンをカメラ本体に追従させる
    -- * 追従処理は、ズームアウトボタンの所有権を持っているユーザーの環境上でのみ行われます。
    if wideButtonTransform.IsMine then
        wideButtonAnchorPos = wideButtonAnchorTransform.GetPosition()
        wideButtonTransform.SetPosition(wideButtonAnchorPos)
        wideButtonAnchorRot = wideButtonAnchorTransform.GetRotation()
        wideButtonTransform.SetRotation(wideButtonAnchorRot)
    end    
 
    -- ズームインのボタンをカメラ本体に追従させる
    -- * 追従処理は、ズームインボタンの所有権を持っているユーザーの環境上でのみ行われます。
    if teleButtonTransform.IsMine then
        teleButtonAnchorPos = teleButtonAnchorTransform.GetPosition()
        teleButtonTransform.SetPosition(teleButtonAnchorPos)
        teleButtonAnchorRot = teleButtonAnchorTransform.GetRotation()
        teleButtonTransform.SetRotation(teleButtonAnchorRot)
    end
 
    -- カメラの初期化が終わってない場合、これ以降の処理をスキップする
    if not isInitialized then
        return
    end
 
    -- vci.state から垂直FOVを取得してローカルに反映する
    local currentFov = vci.state.Get(fovStateName)
    photographyCamera.SetVerticalFieldOfView(currentFov)
 
    -- ズームアウトボタンが押されている場合、vci.stateのFOVを更新する
    if isWideButtonUsed then
        local updatedFov = math.min(maxFov, currentFov + fovStep)
        vci.state.Set(fovStateName, updatedFov)
    end
 
    -- ズームインボタンが押されている場合、vci.stateのFOVを更新する
    if isTeleButtonUsed then
        local updatedFov = math.max(minFov, currentFov - fovStep)
        vci.state.Set(fovStateName, updatedFov)
    end
end
 
function onUse(item)
    -- カメラの初期化が終わってない場合、これ以降の処理をスキップする
    if not isInitialized then
        return
    end
 
    -- カメラ本体がUseされた
    if item == cameraName then
        -- 写真撮影を実行する
        photographyCamera.TakePhotograph()
    end
 
    -- ズームアウトボタンがUseされた
    if item == wideButtonName then
        isWideButtonUsed = true
    end
 
    -- ズームインボタンがUseされた
    if item == teleButtonName then
        isTeleButtonUsed = true
    end
end
 
function onUnuse(item)
    -- カメラの初期化が終わってない場合、これ以降の処理をスキップする
    if not isInitialized then
        return
    end
 
    -- ズームアウトボタンがUnuseされた
    if item == wideButtonName then
        isWideButtonUsed = false
    end
 
    -- ズームインボタンがUnuseされた
    if item == teleButtonName then
        isTeleButtonUsed = false
    end
end