1. ก่อนเริ่มต้น
บทคัดย่อ
Codelab นี้จะสอนวิธีใช้ข้อมูลจาก Google Maps Platform เพื่อแสดงสถานที่ใกล้เคียงในเทคโนโลยีความจริงเสริม (AR) บน Android
ข้อกำหนดเบื้องต้น
- มีความเข้าใจพื้นฐานเกี่ยวกับการพัฒนา Android โดยใช้ Android Studio
- คุ้นเคยกับ Kotlin
สิ่งที่คุณจะได้เรียนรู้
- ขอสิทธิ์จากผู้ใช้เพื่อเข้าถึงกล้องและตำแหน่งของอุปกรณ์
- ผสานรวมกับ Places API เพื่อดึงข้อมูลสถานที่ใกล้เคียงรอบตำแหน่งของอุปกรณ์
- ผสานรวมกับ ARCore เพื่อค้นหาพื้นผิวระนาบแนวนอนเพื่อให้สามารถยึดและวางวัตถุเสมือนในพื้นที่ 3 มิติโดยใช้ Sceneform
- รวบรวมข้อมูลเกี่ยวกับตำแหน่งของอุปกรณ์ในพื้นที่โดยใช้ SensorManager และใช้ Maps SDK สำหรับ Android Utility Library เพื่อวางตำแหน่งออบเจ็กต์เสมือนในส่วนหัวที่ถูกต้อง
สิ่งที่ต้องมี
- Android Studio 2020.3.1 ขึ้นไป
- เครื่องพัฒนาที่รองรับ OpenGL ES 3.0 ขึ้นไป
- อุปกรณ์ที่รองรับ ARCore หรือโปรแกรมจำลอง Android ที่เปิดใช้ ARCore (ดูวิธีการได้ในขั้นตอนถัดไป)
2. ตั้งค่า
Android Studio
Codelab นี้ใช้ Android 10.0 (API ระดับ 29) และกำหนดให้คุณต้องติดตั้งบริการ Google Play ใน Android Studio หากต้องการติดตั้งทั้ง 2 รายการนี้ ให้ทำตามขั้นตอนต่อไปนี้
- ไปที่ SDK Manager ซึ่งคุณเข้าถึงได้โดยคลิกเครื่องมือ > SDK Manager
- ตรวจสอบว่าติดตั้ง Android 10.0 แล้ว หากยังไม่ได้ติดตั้ง ให้เลือกช่องทําเครื่องหมายข้าง Android 10.0 (Q) แล้วคลิกตกลง จากนั้นคลิกตกลงอีกครั้งในกล่องโต้ตอบที่ปรากฏขึ้น
- สุดท้าย ให้ติดตั้งบริการ Google Play โดยไปที่แท็บ SDK Tools เลือกช่องทําเครื่องหมายข้าง Google Play services คลิก OK แล้วเลือก OK อีกครั้งในกล่องโต้ตอบที่ปรากฏขึ้น**
API ที่จำเป็น
ในขั้นตอนที่ 3 ของส่วนต่อไปนี้ ให้เปิดใช้ Maps SDK สำหรับ Android และ Places API สำหรับ Codelab นี้
เริ่มต้นใช้งาน Google Maps Platform
หากคุณยังไม่เคยใช้ Google Maps Platform มาก่อน ให้ทำตามคู่มือการเริ่มต้นใช้งาน Google Maps Platform หรือดูเพลย์ลิสต์การเริ่มต้นใช้งาน Google Maps Platform เพื่อทำตามขั้นตอนต่อไปนี้
- สร้างบัญชีสำหรับการเรียกเก็บเงิน
- สร้างโปรเจ็กต์
- เปิดใช้ Google Maps Platform API และ SDK (แสดงอยู่ในส่วนก่อนหน้า)
- สร้างคีย์ API
ไม่บังคับ: โปรแกรมจำลอง Android
หากไม่มีอุปกรณ์ที่รองรับ ARCore คุณสามารถใช้โปรแกรมจำลอง Android เพื่อจำลองฉาก AR รวมถึงจำลองตำแหน่งของอุปกรณ์แทนได้ เนื่องจากคุณจะใช้ Sceneform ในแบบฝึกหัดนี้ด้วย คุณจึงต้องทำตามขั้นตอนในส่วน "กำหนดค่าโปรแกรมจำลองเพื่อรองรับ Sceneform" ด้วย
3. การเริ่มใช้งานอย่างง่าย
เรามีโค้ดเริ่มต้นที่จะช่วยให้คุณเริ่มต้นใช้งานได้อย่างรวดเร็วที่สุด และช่วยให้คุณทำตาม Codelab นี้ได้ คุณสามารถข้ามไปยังวิธีแก้ปัญหาได้ แต่หากต้องการดูขั้นตอนทั้งหมด โปรดอ่านต่อ
คุณสามารถโคลนที่เก็บได้หากติดตั้ง git
ไว้
git clone https://github.com/googlecodelabs/display-nearby-places-ar-android.git
หรือจะคลิกปุ่มด้านล่างเพื่อดาวน์โหลดซอร์สโค้ดก็ได้
เมื่อได้รับรหัสแล้ว ให้เปิดโปรเจ็กต์ที่อยู่ในไดเรกทอรี starter
4. ภาพรวมโครงการ
สำรวจโค้ดที่คุณดาวน์โหลดจากขั้นตอนก่อนหน้า ภายในที่เก็บนี้ คุณควรจะเห็นโมดูลเดียวชื่อ app
ซึ่งมีแพ็กเกจ com.google.codelabs.findnearbyplacesar
AndroidManifest.xml
แอตทริบิวต์ต่อไปนี้จะประกาศในไฟล์ AndroidManifest.xml
เพื่อให้คุณใช้ฟีเจอร์ที่จำเป็นในโค้ดแล็บนี้ได้
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Sceneform requires OpenGL ES 3.0 or later. -->
<uses-feature
android:glEsVersion="0x00030000"
android:required="true" />
<!-- Indicates that app requires ARCore ("AR Required"). Ensures the app is visible only in the Google Play Store on devices that support ARCore. For "AR Optional" apps remove this line. -->
<uses-feature android:name="android.hardware.camera.ar" />
สำหรับ uses-permission
ซึ่งระบุสิทธิ์ที่ผู้ใช้ต้องให้ก่อนจึงจะใช้ความสามารถเหล่านั้นได้ เราได้ประกาศสิ่งต่อไปนี้
android.permission.INTERNET
- เพื่อให้แอปของคุณดำเนินการเครือข่ายและดึงข้อมูลผ่านอินเทอร์เน็ตได้ เช่น ข้อมูลสถานที่ผ่าน Places APIandroid.permission.CAMERA
- ต้องมีสิทธิ์เข้าถึงกล้องเพื่อให้คุณใช้กล้องของอุปกรณ์เพื่อแสดงวัตถุใน Augmented Reality ได้android.permission.ACCESS_FINE_LOCATION
—ต้องมีสิทธิ์เข้าถึงตำแหน่งเพื่อให้คุณดึงข้อมูลสถานที่ใกล้เคียงที่สัมพันธ์กับตำแหน่งของอุปกรณ์ได้
สำหรับ uses-feature
ซึ่งระบุว่าแอปนี้ต้องใช้ฟีเจอร์ฮาร์ดแวร์ใดบ้าง จะมีการประกาศดังนี้
- ต้องใช้ OpenGL ES เวอร์ชัน 3.0
- ต้องใช้อุปกรณ์ที่รองรับ ARCore
นอกจากนี้ ระบบจะเพิ่มแท็กข้อมูลเมตาต่อไปนี้ภายใต้วัตถุแอปพลิเคชัน
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--
Indicates that this app requires Google Play Services for AR ("AR Required") and causes
the Google Play Store to download and install Google Play Services for AR along with
the app. For an "AR Optional" app, specify "optional" instead of "required".
-->
<meta-data
android:name="com.google.ar.core"
android:value="required" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<!-- Additional elements here -->
</application>
รายการข้อมูลเมตาแรกคือการระบุว่า ARCore เป็นข้อกำหนดสำหรับแอปนี้ในการเรียกใช้ และรายการที่ 2 คือวิธีที่คุณระบุคีย์ API ของ Google Maps Platform ให้กับ Maps SDK สำหรับ Android
build.gradle
ใน build.gradle
จะมีการระบุทรัพยากร Dependency เพิ่มเติมต่อไปนี้
dependencies {
// Maps & Location
implementation 'com.google.android.gms:play-services-location:17.0.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'com.google.maps.android:maps-utils-ktx:1.7.0'
// ARCore
implementation "com.google.ar.sceneform.ux:sceneform-ux:1.15.0"
// Retrofit
implementation "com.squareup.retrofit2:retrofit:2.7.1"
implementation "com.squareup.retrofit2:converter-gson:2.7.1"
}
ต่อไปนี้คือคำอธิบายโดยย่อของการขึ้นต่อกันแต่ละรายการ
- ไลบรารีที่มีรหัสกลุ่ม
com.google.android.gms
ได้แก่play-services-location
และplay-services-maps
ใช้เพื่อเข้าถึงข้อมูลตำแหน่งของอุปกรณ์และเข้าถึงฟังก์ชันการทำงานที่เกี่ยวข้องกับ Google Maps com.google.maps.android:maps-utils-ktx
คือไลบรารีส่วนขยาย Kotlin (KTX) สำหรับไลบรารียูทิลิตีของ Maps SDK สำหรับ Android ระบบจะใช้ฟังก์ชันการทำงานในไลบรารีนี้เพื่อจัดตำแหน่งออบเจ็กต์เสมือนในพื้นที่จริงในภายหลังcom.google.ar.sceneform.ux:sceneform-ux
คือไลบรารี Sceneform ซึ่งจะช่วยให้คุณแสดงฉาก 3 มิติที่สมจริงได้โดยไม่ต้องเรียนรู้ OpenGL- การอ้างอิงภายในรหัสกลุ่ม
com.squareup.retrofit2
คือการอ้างอิง Retrofit ซึ่งช่วยให้คุณเขียนไคลเอ็นต์ HTTP เพื่อโต้ตอบกับ Places API ได้อย่างรวดเร็ว
โครงสร้างโปรเจ็กต์
คุณจะเห็นแพ็กเกจและไฟล์ต่อไปนี้
- **api -**แพ็กเกจนี้มีคลาสที่ใช้ในการโต้ตอบกับ Places API โดยใช้ Retrofit
- **ar -**แพ็กเกจนี้มีไฟล์ทั้งหมดที่เกี่ยวข้องกับ ARCore
- **model -**แพ็กเกจนี้มีคลาสข้อมูลเดียว
Place
ซึ่งใช้ในการแคปซูลสถานที่เดียวตามที่ Places API แสดงผล - MainActivity.kt - นี่คือ
Activity
รายการเดียวที่อยู่ในแอปของคุณ ซึ่งจะแสดงแผนที่และมุมมองกล้อง
5. การตั้งค่าฉาก
เจาะลึกคอมโพเนนต์หลักของแอปโดยเริ่มจากชิ้นส่วนของเทคโนโลยีความจริงเสริม
MainActivity
มี SupportMapFragment
ซึ่งจะจัดการการแสดงออบเจ็กต์แผนที่ และคลาสย่อยของ ArFragment
—PlacesArFragment
—ซึ่งจะจัดการการแสดงฉากความเป็นจริงเสริม
การตั้งค่า Augmented Reality
นอกเหนือจากการแสดงฉาก Augmented Reality แล้ว PlacesArFragment
ยังจัดการการขอสิทธิ์เข้าถึงกล้องจากผู้ใช้ด้วย หากยังไม่ได้รับสิทธิ์ นอกจากนี้ยังขอสิทธิ์เพิ่มเติมได้โดยการลบล้างเมธอด getAdditionalPermissions
เนื่องจากคุณต้องได้รับสิทธิ์เข้าถึงตำแหน่งด้วย ให้ระบุสิทธิ์ดังกล่าวและลบล้างเมธอด getAdditionalPermissions
ดังนี้
class PlacesArFragment : ArFragment() {
override fun getAdditionalPermissions(): Array<String> =
listOf(Manifest.permission.ACCESS_FINE_LOCATION)
.toTypedArray()
}
เรียกใช้
เปิดโค้ดโครงร่างในไดเรกทอรี starter
ใน Android Studio หากคลิกเรียกใช้ > เรียกใช้ "แอป" จากแถบเครื่องมือและติดตั้งใช้งานแอปในอุปกรณ์หรือโปรแกรมจำลอง คุณควรได้รับแจ้งให้เปิดใช้สิทธิ์เข้าถึงตำแหน่งและกล้องก่อน คลิกอนุญาต แล้วคุณจะเห็นมุมมองกล้องและมุมมองแผนที่อยู่ข้างกันดังนี้
การตรวจจับเครื่องบิน
เมื่อมองไปรอบๆ สภาพแวดล้อมที่คุณอยู่ด้วยกล้อง คุณอาจเห็นจุดสีขาว 2 จุดซ้อนทับบนพื้นผิวแนวนอน คล้ายกับจุดสีขาวบนพรมในรูปภาพนี้
จุดสีขาวเหล่านี้คือแนวทางที่ ARCore ระบุเพื่อแสดงว่าตรวจพบระนาบแนวนอนแล้ว ระนาบที่ตรวจพบเหล่านี้ช่วยให้คุณสร้างสิ่งที่เรียกว่า "Anchor" เพื่อวางตำแหน่งออบเจ็กต์เสมือนในพื้นที่จริงได้
อ่านข้อมูลเพิ่มเติมเกี่ยวกับ ARCore และวิธีที่ ARCore เข้าใจสภาพแวดล้อมรอบตัวคุณได้ที่แนวคิดพื้นฐานของ ARCore
6. รับข้อมูลสถานที่ใกล้เคียง
จากนั้นคุณจะต้องเข้าถึงและแสดงตำแหน่งปัจจุบันของอุปกรณ์ แล้วดึงข้อมูลสถานที่ใกล้เคียงโดยใช้ Places API
การตั้งค่า Maps
คีย์ API ของ Google Maps Platform
ก่อนหน้านี้ คุณได้สร้างคีย์ API ของ Google Maps Platform เพื่อเปิดใช้การค้นหา Places API และเพื่อให้ใช้ Maps SDK สำหรับ Android ได้ เปิดไฟล์ gradle.properties
แล้วแทนที่สตริง "YOUR API KEY HERE"
ด้วยคีย์ API ที่คุณสร้างขึ้น
แสดงตำแหน่งอุปกรณ์บนแผนที่
เมื่อเพิ่มคีย์ API แล้ว ให้เพิ่มตัวช่วยในแผนที่เพื่อช่วยให้ผู้ใช้ทราบตำแหน่งของตนเองเมื่อเทียบกับแผนที่ โดยไปที่setUpMaps
method แล้วตั้งค่า googleMap.isMyLocationEnabled
เป็น true.
ภายใน mapFragment.getMapAsync
call การดำเนินการนี้จะแสดงจุดสีน้ำเงินบนแผนที่
private fun setUpMaps() {
mapFragment.getMapAsync { googleMap ->
googleMap.isMyLocationEnabled = true
// ...
}
}
รับตำแหน่งปัจจุบัน
หากต้องการทราบตำแหน่งของอุปกรณ์ คุณจะต้องใช้คลาส FusedLocationProviderClient
เราได้ดำเนินการขออินสแตนซ์นี้แล้วในเมธอด onCreate
ของ MainActivity
หากต้องการใช้ออบเจ็กต์นี้ ให้กรอกข้อมูลในเมธอด getCurrentLocation
ซึ่งรับอาร์กิวเมนต์ Lambda เพื่อให้ส่งตำแหน่งไปยังผู้เรียกเมธอดนี้ได้
หากต้องการใช้วิธีนี้ให้เสร็จสมบูรณ์ คุณสามารถเข้าถึงพร็อพเพอร์ตี้ lastLocation
ของออบเจ็กต์ FusedLocationProviderClient
แล้วเพิ่ม addOnSuccessListener
ดังนี้
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
currentLocation = location
onSuccess(location)
}.addOnFailureListener {
Log.e(TAG, "Could not get location")
}
เมธอด getCurrentLocation
จะเรียกใช้จากภายใน Lambda ที่ระบุใน getMapAsync
ในเมธอด setUpMaps
ซึ่งจะดึงข้อมูลสถานที่ใกล้เคียง
เริ่มการเรียกเครือข่าย Places
ในgetNearbyPlaces
การเรียกเมธอด โปรดทราบว่าระบบจะส่งพารามิเตอร์ต่อไปนี้ไปยังเมธอด placesServices.nearbyPlaces
ซึ่งได้แก่ คีย์ API, ตำแหน่งของอุปกรณ์, รัศมีเป็นเมตร (ซึ่งตั้งค่าเป็น 2 กม.) และประเภทสถานที่ (ปัจจุบันตั้งค่าเป็น park
)
val apiKey = "YOUR API KEY"
placesService.nearbyPlaces(
apiKey = apiKey,
location = "${location.latitude},${location.longitude}",
radiusInMeters = 2000,
placeType = "park"
)
หากต้องการทำการเรียกเครือข่ายให้เสร็จสมบูรณ์ ให้ส่งคีย์ API ที่คุณกำหนดไว้ในไฟล์ gradle.properties
ข้อมูลโค้ดต่อไปนี้กำหนดไว้ในไฟล์ build.gradle
ภายใต้การกำหนดค่า android > defaultConfig
android {
defaultConfig {
resValue "string", "google_maps_key", (project.findProperty("GOOGLE_MAPS_API_KEY") ?: "")
}
}
ซึ่งจะทำให้ค่าทรัพยากรสตริง google_maps_key
พร้อมใช้งานในเวลาบิลด์
หากต้องการทำการเรียกเครือข่ายให้เสร็จสมบูรณ์ คุณเพียงแค่อ่านทรัพยากรสตริงนี้ผ่าน getString
ในออบเจ็กต์ Context
val apiKey = this.getString(R.string.google_maps_key)
7. สถานที่ใน AR
จนถึงตอนนี้ คุณได้ทำสิ่งต่อไปนี้แล้ว
- ขอสิทธิ์เข้าถึงกล้องและตำแหน่งจากผู้ใช้เมื่อเรียกใช้แอปเป็นครั้งแรก
- ตั้งค่า ARCore เพื่อเริ่มติดตามระนาบแนวนอน
- ตั้งค่า Maps SDK ด้วยคีย์ API
- รับตำแหน่งปัจจุบันของอุปกรณ์
- ดึงข้อมูลสถานที่ใกล้เคียง (โดยเฉพาะสวนสาธารณะ) โดยใช้ Places API
ขั้นตอนที่เหลือในการทำแบบฝึกหัดนี้ให้เสร็จสมบูรณ์คือการวางตำแหน่งสถานที่ที่คุณดึงข้อมูลในเทคโนโลยีความจริงเสริม
การทำความเข้าใจฉาก
ARCore สามารถทำความเข้าใจฉากในโลกจริงผ่านกล้องของอุปกรณ์ได้โดยการตรวจจับจุดที่น่าสนใจและโดดเด่นซึ่งเรียกว่าจุดฟีเจอร์ในแต่ละเฟรมของรูปภาพ เมื่อจัดกลุ่มจุดฟีเจอร์เหล่านี้และปรากฏว่าอยู่บนระนาบแนวนอนร่วมกัน เช่น โต๊ะและพื้น ARCore จะทำให้ฟีเจอร์นี้พร้อมใช้งานในแอปเป็นระนาบแนวนอน
ดังที่เห็นก่อนหน้านี้ ARCore จะช่วยแนะนำผู้ใช้เมื่อตรวจพบระนาบโดยการแสดงจุดสีขาว
การเพิ่มแองเคอร์
เมื่อตรวจพบระนาบแล้ว คุณจะแนบออบเจ็กต์ที่เรียกว่าจุดยึดได้ คุณสามารถวางออบเจ็กต์เสมือนและรับประกันว่าออบเจ็กต์เหล่านั้นจะปรากฏในตำแหน่งเดิมในพื้นที่ได้ผ่าน Anchor แก้ไขโค้ดเพื่อแนบโมเดลเมื่อตรวจพบเครื่องบิน
ใน setUpAr
จะมี OnTapArPlaneListener
แนบมากับ PlacesArFragment
ระบบจะเรียกใช้ Listener นี้ทุกครั้งที่มีการแตะระนาบในฉาก AR ในการเรียกนี้ คุณสามารถสร้าง Anchor
และ AnchorNode
จาก HitResult
ที่ระบุไว้ใน Listener ได้ดังนี้
arFragment.setOnTapArPlaneListener { hitResult, _, _ ->
val anchor = hitResult.createAnchor()
anchorNode = AnchorNode(anchor)
anchorNode?.setParent(arFragment.arSceneView.scene)
addPlaces(anchorNode!!)
}
AnchorNode
คือตำแหน่งที่คุณจะแนบออบเจ็กต์โหนดลูก PlaceNode
อินสแตนซ์ ในฉากซึ่งจัดการในการเรียกเมธอด addPlaces
เรียกใช้
หากคุณเรียกใช้แอปที่มีการแก้ไขข้างต้น ให้มองไปรอบๆ จนกว่าจะตรวจพบเครื่องบิน แตะจุดสีขาวที่ระบุเครื่องบินได้เลย เมื่อทำตามขั้นตอนดังกล่าวแล้ว คุณควรจะเห็นเครื่องหมายบนแผนที่สำหรับสวนสาธารณะที่ใกล้ที่สุดทั้งหมดรอบตัวคุณ อย่างไรก็ตาม หากสังเกตดีๆ คุณจะเห็นว่าออบเจ็กต์เสมือนจะติดอยู่กับสมอที่สร้างขึ้นและไม่ได้วางไว้เทียบกับตำแหน่งที่สวนสาธารณะเหล่านั้นอยู่ในอวกาศ
ในขั้นตอนสุดท้าย คุณจะแก้ไขปัญหานี้ได้โดยใช้ไลบรารียูทิลิตี Maps SDK สำหรับ Android และ SensorManager ในอุปกรณ์
8. การกำหนดตำแหน่งสถานที่
หากต้องการวางไอคอนสถานที่เสมือนจริงในเทคโนโลยีความจริงเสริมให้ตรงกับส่วนหัวที่ถูกต้อง คุณจะต้องมีข้อมูล 2 อย่าง ได้แก่
- ตำแหน่งทิศเหนือจริง
- มุมระหว่างทิศเหนือกับแต่ละสถานที่
การระบุทิศเหนือ
คุณสามารถระบุทิศเหนือได้โดยใช้เซ็นเซอร์ตำแหน่ง (สนามแม่เหล็กโลกและตัวตรวจวัดความเร่ง) ที่มีในอุปกรณ์ เมื่อใช้เซ็นเซอร์ทั้ง 2 ตัวนี้ คุณจะรวบรวมข้อมูลแบบเรียลไทม์เกี่ยวกับตำแหน่งของอุปกรณ์ในพื้นที่ได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับเซ็นเซอร์ตำแหน่งได้ที่คำนวณการวางแนวของอุปกรณ์
หากต้องการเข้าถึงเซ็นเซอร์เหล่านี้ คุณจะต้องขอรับ SensorManager
จากนั้นลงทะเบียน SensorEventListener
ในเซ็นเซอร์เหล่านั้น ระบบจะดำเนินการตามขั้นตอนเหล่านี้ให้คุณแล้วในเมธอดวงจรของ MainActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
sensorManager = getSystemService()!!
// ...
}
override fun onResume() {
super.onResume()
sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)?.also {
sensorManager.registerListener(
this,
it,
SensorManager.SENSOR_DELAY_NORMAL
)
}
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)?.also {
sensorManager.registerListener(
this,
it,
SensorManager.SENSOR_DELAY_NORMAL
)
}
}
override fun onPause() {
super.onPause()
sensorManager.unregisterListener(this)
}
ในonSensorChanged
เมธอด จะมีออบเจ็กต์ SensorEvent
ซึ่งมีรายละเอียดเกี่ยวกับข้อมูลของเซ็นเซอร์ที่กำหนดเมื่อมีการเปลี่ยนแปลงตามช่วงเวลา โปรดเพิ่มโค้ดต่อไปนี้ลงในเมธอดนั้น
override fun onSensorChanged(event: SensorEvent?) {
if (event == null) {
return
}
if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
System.arraycopy(event.values, 0, accelerometerReading, 0, accelerometerReading.size)
} else if (event.sensor.type == Sensor.TYPE_MAGNETIC_FIELD) {
System.arraycopy(event.values, 0, magnetometerReading, 0, magnetometerReading.size)
}
// Update rotation matrix, which is needed to update orientation angles.
SensorManager.getRotationMatrix(
rotationMatrix,
null,
accelerometerReading,
magnetometerReading
)
SensorManager.getOrientation(rotationMatrix, orientationAngles)
}
โค้ดด้านบนจะตรวจสอบประเภทเซ็นเซอร์ และจะอัปเดตค่าเซ็นเซอร์ที่เหมาะสม (ค่าจากตัวตรวจวัดความเร่งหรือแมกนีโตมิเตอร์) โดยขึ้นอยู่กับประเภท การใช้ค่าที่อ่านได้จากเซ็นเซอร์เหล่านี้จะช่วยให้ทราบค่าขององศาจากทิศเหนือที่สัมพันธ์กับอุปกรณ์ (เช่น ค่าของ orientationAngles[0]
)
ส่วนหัวทรงกลม
เมื่อกำหนดทิศเหนือแล้ว ขั้นตอนถัดไปคือการกำหนดมุมระหว่างทิศเหนือกับแต่ละสถานที่ จากนั้นใช้ข้อมูลดังกล่าวเพื่อจัดตำแหน่งสถานที่ในส่วนหัวที่ถูกต้องในเทคโนโลยีความจริงเสริม
หากต้องการคำนวณส่วนหัว คุณจะต้องใช้ไลบรารียูทิลิตีของ Maps SDK สำหรับ Android ซึ่งมีฟังก์ชันช่วย 2-3 ฟังก์ชันสำหรับการคำนวณระยะทางและส่วนหัวผ่านรูปทรงเรขาคณิตทรงกลม ดูข้อมูลเพิ่มเติมได้ที่ภาพรวมของไลบรารีนี้
จากนั้นคุณจะใช้เมธอด sphericalHeading
ในไลบรารียูทิลิตี ซึ่งจะคำนวณส่วนหัว/แบริ่งระหว่างออบเจ็กต์ LatLng
2 รายการ ต้องมีข้อมูลนี้ภายในเมธอด getPositionVector
ที่กำหนดไว้ใน Place.kt
ในท้ายที่สุด เมธอดนี้จะแสดงออบเจ็กต์ Vector3
ซึ่ง PlaceNode
แต่ละรายการจะใช้เป็นตำแหน่งในพื้นที่ AR
จากนั้นแทนที่คำจำกัดความของส่วนหัวในเมธอดนั้นด้วยคำจำกัดความต่อไปนี้
val heading = latLng.sphericalHeading(placeLatLng)
การดำเนินการดังกล่าวจะทำให้เกิดการกำหนดเมธอดต่อไปนี้
fun Place.getPositionVector(azimuth: Float, latLng: LatLng): Vector3 {
val placeLatLng = this.geometry.location.latLng
val heading = latLng.sphericalHeading(placeLatLng)
val r = -2f
val x = r * sin(azimuth + heading).toFloat()
val y = 1f
val z = r * cos(azimuth + heading).toFloat()
return Vector3(x, y, z)
}
ตำแหน่งในเครื่อง
ขั้นตอนสุดท้ายในการวางแนวสถานที่อย่างถูกต้องใน AR คือการใช้ผลลัพธ์ของ getPositionVector
เมื่อมีการเพิ่มออบเจ็กต์ PlaceNode
ลงในฉาก ไปที่ addPlaces
ใน MainActivity
ตรงใต้บรรทัดที่ตั้งค่าองค์กรระดับบนในแต่ละ placeNode
(ใต้ placeNode.setParent(anchorNode)
) ตั้งค่า localPosition
ของ placeNode
เป็นผลลัพธ์ของการเรียกใช้ getPositionVector
ดังนี้
val placeNode = PlaceNode(this, place)
placeNode.setParent(anchorNode)
placeNode.localPosition = place.getPositionVector(orientationAngles[0], currentLocation.latLng)
โดยค่าเริ่มต้น เมธอด getPositionVector
จะตั้งค่าระยะทาง y ของโหนดเป็น 1 เมตรตามที่ระบุโดยค่า y
ในเมธอด getPositionVector
หากต้องการปรับระยะนี้ เช่น เป็น 2 เมตร ให้แก้ไขค่าดังกล่าวตามต้องการ
การเปลี่ยนแปลงนี้จะทำให้PlaceNode
ออบเจ็กต์ที่เพิ่มเข้ามาอยู่ในส่วนหัวที่ถูกต้อง ตอนนี้ให้เรียกใช้แอปเพื่อดูผลลัพธ์
9. ขอแสดงความยินดี
ขอแสดงความยินดีที่มาไกลถึงจุดนี้