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

หน้านี้มีเคล็ดลับทั่วไปสําหรับการสร้าง 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() เพื่อปิด

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