สร้างและโต้ตอบกับฉาก

หน้านี้มีเคล็ดลับทั่วไปสําหรับการสร้าง Scene และการโต้ตอบกับหน้า

แสดงผลฉากโดยไม่มี AR

คลาส SceneView ช่วยให้คุณแสดงผลฉาก 3 มิติได้โดยไม่ต้องใช้กล้องหรือเซสชัน AR ซึ่งเป็นประโยชน์ในการแสดงตัวอย่างวัตถุ 3 มิติในแอปโดยไม่ใช้ AR หรือจะให้ฟังก์ชันการทํางานทางเลือกในอุปกรณ์ที่ไม่รองรับ 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 ลําดับของการเผยแพร่มีดังนี้

  1. ระบบจะส่งเหตุการณ์ไปให้ผู้ฟังที่เพิ่มลงใน scene.addOnPeekTouchListener()

    ซึ่งคล้ายกับ viewGroup.intercept() เว้นแต่ว่าฉากใน Listener การแสดงชั่วครู่จะใช้เหตุการณ์นี้ไม่ได้

  2. ระบบจะส่งเหตุการณ์ไปยังโหนดแรกที่แกนรังสี

    • โหนดนี้อาจใช้เหตุการณ์ได้โดยการกําหนดชุดเมธอด onTouchEvent() ที่แสดงผล true
    • หากเมธอด onTouchEvent() แสดงผล false หรือไม่มีการกําหนด Listener เหตุการณ์จะได้รับการถ่ายทอดไปยังระดับบนสุดของโหนด กระบวนการนี้จะดําเนินต่อไปจนกว่าจะใช้เหตุการณ์เสร็จสิ้นหรือจนกว่าจะถึงฉาก
  3. สุดท้าย หากไม่มี Listener ที่ใช้งานเหตุการณ์ ระบบจะส่งเหตุการณ์ไปยัง scene.onTouchListener()

ตรวจจับท่าทางสัมผัส

ArFragment รองรับการแตะ (การเลือก) ลาก (เลื่อน) บีบ (ปรับขนาด) และบิด (หมุน) ท่าทางสัมผัสในตัว

เช่น ดู HelloSceneformActivity.java ในแอปตัวอย่าง HelloSceneform

สร้างโหนดที่กําหนดเอง

โดยสามารถสร้างโหนดที่กําหนดเองได้ด้วยคลาสย่อย Node สถานการณ์ต่อไปนี้คุณอาจต้องการสร้างโหนดที่กําหนดเอง

  • คุณต้องการเข้าถึงเหตุการณ์ในวงจรของโหนด เช่น onUpdate(), onActivate และ onDeactivate()
  • และต้องการสร้างโหนดที่ประกอบด้วยกลุ่มโหนด
  • คุณกําลังสร้างรหัสซ้ําจํานวนมากและอาจทําให้มีการใช้คลาสย่อย

คุณสามารถดูตัวอย่างได้ที่ Planet.java ในแอปตัวอย่างระบบสุริยะ

ทําให้โหนดเคลื่อนไหว

การทําให้โหนดเคลื่อนไหวได้มี 2 วิธีดังนี้

สร้างภาพเคลื่อนไหวด้วย 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 ที่ไฮไลต์ Planes เมื่อ ARCore ตรวจพบ ซึ่งมีลักษณะดังนี้

คุณสามารถแก้ไขวัสดุและพื้นผิวเริ่มต้นที่ใช้แสดงผลเครื่องบินที่ตรวจพบได้ ด้านล่างนี้เป็นวิธีเปลี่ยนพื้นผิว

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() เพื่อปิด

หากแสดงผลได้ทั้งการแคสต์และเงา แคสต์จะแคสต์เงาได้ด้วยตัวเอง