本頁提供打造 Scene
並與其互動的常見問題。
在沒有 AR 的情況下轉譯情境
SceneView
類別可讓您轉譯 3D 場景,而不必使用裝置的相機或 AR 工作階段。這種做法可讓您在不使用 AR 的情況下,在應用程式中預覽 3D 物件,或在不支援 AR 的裝置上提供替代功能。
根據預設,SceneView
不會顯示 AR 相機的影像,並使用黑色背景。如要變更背景顏色,您可以呼叫 view.setBackgroundColor()
或定義版面配置中的背景顏色,如下所示:
<com.google.ar.sceneform.SceneView
android:id="@+id/scene_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/deep_teal"/>
情境的 Camera
節點位於來源 (位置 0,0,0) 且朝向 (方向 0,0,-1)。由於相機的位置和旋轉資訊不會與 AR 動作追蹤建立關聯,你可以像任何其他節點一樣重新定位或為其建立動畫。
Camera camera = sceneView.getScene().getCamera();
camera.setLocalRotation(Quaternion.axisAngle(Vector3.right(), -30.0f));
互動
處理使用者觸控行為
使用者輕觸螢幕時,Sceneform 會將觸控事件傳播至事件處理常式和附加至節點的事件監聽器。這個行為與 Android 中檢視畫面和檢視區塊群組的傳播事件類似。套用順序如下:
系統會將事件傳送至在
scene.addOnPeekTouchListener()
中新增的任何事件監聽器。這個做法與
viewGroup.intercept()
類似,差別在於有觸控式事件監聽器的場景無法消耗該事件。該事件會傳送至陰影中第一個第一個節點。
- 節點可定義傳回
true
的onTouchEvent()
方法集,以取用事件。 - 如果
onTouchEvent()
方法傳回false
,或是未定義任何事件監聽器,事件就會套用到節點的父項。直到取用事件或觸及場景為止。
- 節點可定義傳回
最後,如果事件監聽器沒有取用該事件,事件會傳遞至
scene.onTouchListener()
。
偵測手勢
ArFragment
內建支援輕觸 (選取)、拖曳 (移動)、雙指撥動 (縮放) 和扭動 (旋轉) 手勢。
例如,請參閱 HelloSceneform 範例應用程式中的 HelloSceneformActivity.java
。
建立自訂節點
與建立自訂 Android 檢視區塊類似,您可以為子類別建立 Node
來建立自訂節點。在下列情況下,您可以建立自訂節點:
- 您想要存取節點生命週期中的事件,例如
onUpdate()
、onActivate
和onDeactivate()
。 - 您想要建立由一組節點組成的節點。
- 您要複製大量程式碼,而且可能會將子類別分到子類別。
如需範例,請參閱 Solar System 範例應用程式中的 Planet.java
。
為節點建立動畫
為節點建立動畫的方法有兩種:
- 使用標準 Android Animation API 中的
ObjectAnimator
。 - 建立自訂節點類別並覆寫
onUpdate()
使用 ObjectAnimator 建立動畫
下列為動畫焦點的動畫效果範例:
final int durationInMilliseconds = 1000;
final float minimumIntensity = 1000.0f;
final float maximumIntensity = 3000.0f;
ValueAnimator intensityAnimator =
ObjectAnimator.ofFloat(
spotlightNode.getLight(), "intensity", minimumIntensity, maximumIntensity);
intensityAnimator.setDuration(durationInMilliseconds);
intensityAnimator.setRepeatCount(ValueAnimator.INFINITE);
intensityAnimator.setRepeatMode(ValueAnimator.REVERSE);
intensityAnimator.start();
詳情請參閱「使用 ObjectAnimator 建立動畫」。
onUpdate 中的動畫
覆寫節點的 onUpdate()
,藉此建立畫格來為畫格建立動畫。以下範例展示在 太陽能系統範例應用程式中的 Planet.java
中,即使地球旋轉,還會將每個畫面資訊卡調整為符合使用者的畫面。
@Override
public void onUpdate(FrameTime frameTime) {
Vector3 cameraPosition = getScene().getCamera().getWorldPosition();
Vector3 cardPosition = infoCard.getWorldPosition();
Vector3 direction = Vector3.subtract(cameraPosition, cardPosition);
Quaternion lookRotation = Quaternion.lookRotation(direction, Vector3.up());
infoCard.setWorldRotation(lookRotation);
}
新增燈具
您可以將 Lights
附加至情境中的任何節點。根據預設,每個場景的場景都包含 Sun
節點,而且其中包含一個方向指引。
你可以修改日光,也可以為場景加入光線。以下範例會新增焦點:
Light spotLightYellow =
Light.builder(this, Light.Type.FOCUSED_SPOTLIGHT)
.setColor(new Color(android.graphics.Color.YELLOW))
.setShadowCastingEnabled(true)
.build();
然後呼叫 setLight()
將其附加至節點。
自訂飛機視覺化圖表
根據預設,情境中的 PlaneRenderer
會在 ARCore 偵測到時醒目顯示 Planes
。這是訂閱按鈕的圖示:
您可以修改用於顯示偵測到平面的預設材質和材質。如何變更紋理:
Texture.Sampler sampler =
Texture.Sampler.builder()
.setMinFilter(Texture.Sampler.MinFilter.LINEAR)
.setWrapMode(Texture.Sampler.WrapMode.REPEAT)
.build();
// R.drawable.custom_texture is a .png file in src/main/res/drawable
Texture.builder()
.setSource(this, R.drawable.custom_texture)
.setSampler(sampler)
.build()
.thenAccept(texture -> {
arSceneView.getPlaneRenderer()
.getMaterial().thenAccept(material ->
material.setTexture(PlaneRenderer.MATERIAL_TEXTURE, texture));
});
陰影
陰影會在世界上算繪可視區域,並提供使用者深度和空間的感受。
在場景中,可以投射陰影的物件和可接收陰影的物件。
Lights
和Renderables
可以投射陰影陰影會在日出時啟用,但光源並未啟用。呼叫
setShadowCastingEnabled()
即可開啟這項功能。Renderables
和PlaneRenderer
可以接收陰影。陰影接收功能預設為啟用。撥打
setShadowReceiver()
即可關閉。
如果可繪項目同時投放及接收陰影,即可自行投射陰影。