์ด๋ฒ ๊ธ์์๋ ARCore ์์ฑํด์ฃผ๋ ๋ฐ๋ฅ(Plane)์ ์ด๋ป๊ฒ ๋ค๋ฃจ๊ณ ๋ฐ๋ฅ์ ๋๋์ฅ๋ฅผ ์์ฑํ๋ ๊ฒ ๊น์ง ์จ๋ณด๋ ค๊ณ ํ๋ค.
์ผ๋จ ์ด๋ฒ๊ธ๊น์ง ์ฝ์ผ๋ฉด ์๋ ๋์์ ๊น์ง ๋ง๋๋๋ฐ๋ ๋ฌธ์ ์์๊บผ๋ค.
1. Frame ํด๋์ค
์ฐ๋ฆฌ๊ฐ ํ์ํ Plane๋ค์ ์ป์์ ์๋ ํด๋์ค์ด๋ค.
์์ ๋ฅผ ๋ณด๋ฉด
Update ๋ฌธ์์ย Frame.GetPlanes ํจ์๋ก ๋งค ํ๋ ์๋ง๋ค ์์ฑ๋ Plane๋ค์ ๊ฐ์ ธ์จ๋ค.
๊ตฌ๋๋๋ ํ์์ ์์ ์์ค๋ฅผ ๋ณด๋ฉด ๋๊ฐ ์๊บผ๊ณ ์ฐ๋ฆฌ๊ฐ ์ง์ค์ ์ผ๋ก ๋ด์ผํ ๊ฒ์ย
GetPlanes ํจ์๋ก ์ป์ด์ค๋ย TrackedPlane ํด๋์ค์ด๋ค.
Plane์ ํฌ์ง์ , ๋กํ ์ด์ , Extent, Boundary Polygon ๋ฑ์ ์ ๊ณตํด์ค๋ค.
๊ทธ๋ฆผ์ผ๋ก ์ค๋ช ํ๋ฉด ๋๊ฐ ์ด๋ ๋ค.
(๊ทธ๋ฆผ ํ์ณ์จ๊ฑฐ๋ผ ์ ์ ์น ์์์๊ฐ ์์ง๋ง ๋๊ฐ ์์๋ค์ด๋ผ)
ARCore๊ฐ ์ฌ์ฉํ๋ 1Unit = 1m ์ด๊ธฐ ๋๋ฌธ์ ExtentX, ExtentZ๊ฐ 1, 1 ๋ก ๋ฐ์์ ์ง๋ค๋ฉด
ํด๋น Plane์ ํฌ๊ธฐ๊ฐ 1m x 1m ๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
์ด๊ฑด ์ ๋ํฐ์์ ํ์ํด์ฃผ๋ 3D์ค๋ธ ์ ํธ๋ ๋ง์น๊ฐ์ง์ธ๋ฐย
3D ์ค๋ธ์ ํธ์ ํฌ๊ธฐ๊ฐ 1:1๋ก ๋งค์นญ๋์ด ์ฆ๊ฐํ์ค ๋๋ฏ๋ก ์ค์ ํ์๋
ํฌ๊ธฐ๋ฅผ ์๋ก ์ธก์ ํด์ ์ ์ ํ๋ฉด๋๋ค.
๊ทธ๋ฌ๋ฉด ๋๋์ง๋ฅผ ์์ฑํ๋ ์ฝ๋๋ฅผ ๋ง๋ค์ด๋ณด์.
Plane Position์์ย ExtentX,ExtentZ ๋งํผ์ ๋๋ฐฐ์ ํฌ๊ธฐ๋ฅผ 0.3m๋ง๋คย
ํ์ํ์ฌ ์ด๋ฏธ ๊ฐ๊น์ด๊ณณ์ ๋๋์ง๊ฐ ์์ผ๋ฉดย ์์ฑํ๊ณ
์์ผ๋ฉด ๋ฌด์ํ๊ฒ ๋ง๋ค๋ฉด๋๋ค.
ย - Plane Polygonboundary ๋ฐ์์๋ ๋๋์ง๋ ์์ฑํ์ง ์๊ฒ ์ถ๊ฐํ๋ค.
๋์๋ ์ฝ๋ ๋ถ์ฌ๋ฃ๋๊ฒ ์๋๊ฑธ๊น
for (float x = -m_AllPlanes[i].ExtentX; x < m_AllPlanes[i].ExtentX; x += moleGap)
{
for (float z = -m_AllPlanes[i].ExtentZ; z < m_AllPlanes[i].ExtentZ; z += moleGap)
{
Vector3 pos = new Vector3(m_AllPlanes[i].Position.x + x, m_AllPlanes[i].Position.y, m_AllPlanes[i].Position.z + z);
bool isContain = ContainsPoint(polygon, pos);
if (isContain)
{
bool isNearAnchor = IsNearAnchor(pos, moleGap);
if (isNearAnchor == false)
{
// ๋๋์ง ์์ฑ
}
}
}
}
์ฝ๋๊ฐ ๋นํจ์จ์ ์ด์ง๋ง ๋ฌด์ํด๋ผ.
moleGap์ ํ์ํ ๊ฑฐ๋ฆฌ ๊ฐญ ์ด๋ผ๊ณ ์๊ฐํ๋ฉด๋๋ค.
์ฌ๊ธฐ๊น์ง๊ฐ ๋๋์ง๋ฅผ ์์ฑํ ์์น๋ฅผ ์ฐพ๋๊ฑฐ๊ณ ์ด์ ๋๋์ง๋ฅผ ์์ฑํด๋ณด์.
2. ๋๋์ง ์์ฑ๊ณผ Anchor
AR์์ ์นด๋ฉ๋ผ๋ ์ฌ์ฉ์๊ฐ ๊ณ์ ์์ง์ฌ์ ์ฐ๋ฆฌ๊ฐ ์ฐพ์๋์ Plane์ ๋๋์ง ์์ฑ์ง์ ์ด ๊ณ์ ๋ณํ๋๋ฐ
์ด๋ ์ด๊ฒ์ ๋ณด์ ํด ์ฃผ๋๊ฒ์ด Anchor ์ด๋ค. (UI์ต์ปค๋ผ๊ณ ์๊ฐํ๋ฉด ํธํ๋ค.)
๋ณด์ ์ด๋ผ๋๊ฒ ๊ฑฐ์ฐฝํด ๋ณด์ด์ง๋ง Anchor ๊ฐ ํ๋์ผ์ ๊ทธ๋ฅ Plane ์ค๋ธ์ ํธ์ ์์์ผ๋ก ๋ค์ด๊ฐ ์๋๊ฒ ๋ฟ์ด๋ค.
์ฐ๋ฆฌ๋ Anchor ์ค๋ธ์ ํธ๋ฅผ ์์ฑํ๊ณ Anchor์ ์์์ผ๋ก ๋๋์ง๋ฅผ ๋ฃ์ผ๋ฉด ๋๋๋ค.
์๋๋ ๋๋์ง๋ฅผ ์์ฑํ๋ ์ฝ๋์ด๋ค. ์์ ์ฝ๋๋ฅผ ๊ฑฐ์ ๊ทธ๋๋ก ๊ฐ์ ธ๋ค ์จ์ ์์ ๊บผ ๋ด๋ ๋๋ค.
Pose pose = new Pose(new Vector3(m_AllPlanes[i].Position.x + x, m_AllPlanes[i].Position.y, m_AllPlanes[i].Position.z + z), m_AllPlanes[i].Rotation);
var moleObject = Instantiate(molePrefab, pose.position, pose.rotation);
var anchor = m_AllPlanes[i].CreateAnchor(pose);
moleObject.transform.LookAt(FirstPersonCamera.transform);
moleObject.transform.rotation = Quaternion.Euler(0.0f,
moleObject.transform.rotation.eulerAngles.y, moleObject.transform.rotation.z);
moleObject.transform.parent = anchor.transform;
์์์ Pose ํด๋์ค๊ฐ ์๋๋ฐ Position Rotation์ ๊ฐ์ด ๊ฐ์ง๊ณ ์๋ ํด๋์ค๋ผ๊ณ ๋ณด๋ฉด๋๋ค.
m_AllPlanes[i].CreateAnchor(pose); ์ฌ๊ธฐ์ ์ต์ปค๋ฅผ ์์ฑํ๋๋ฐ ์ด๊ฑด ์ฐ๋ฆฌ๊ฐ ๊ตฌํ Plane์ ์ต์ปค๋ก ๋ถ์ด๊ฒ ๋ค๋ ๋ง์ด๋ค.
์ด๊ฑฐ์ ๋ค๋ฅด๊ฒ ์๋ ์ขํ์์๋ Anchor๋ฅผ ๊ฑธ์์๋๋ฐ
Session.CreateWorldAnchor(pose); ์ด๋ฐ์์ผ๋ก ์๋ Anchor๋ ์์ฑํ ์์๋ค.
์ฝ๊ฒ ๋ฌด์จ์ฐจ์ด๋๋ฉด ๋๊ฐ ๋ฐ๋ฅ์ ์ค์บํด์ ๊ณ์ํ์ฅ์์ผ ๋๊ฐ๋ย
Plane์ Anchor๋ย ์์น ๊ฐ์ ๊ณ์ ๋ณด์ ๋ฐ์์ ์ ์ ์ ํํด์ง์ง๋ง World์ Anchor๋ ๊ทธ๋ด๊ฒ ์์ผ๋ฏ๋ก ์ ์ ์ด๊ธ๋๋ค.
์๋๋ถ๋ถ์ ์นด๋ฉ๋ผ ์ชฝ์ ๋ฐ๋ผ๋ณด๊ฒ ํ์ ์์ผ์ฃผ๋๊ฑฐ๋ผ ๋ณ๋ก ์ ๊ฒฝ์ธํ์์๋ค.
moleObject.transform.LookAt(FirstPersonCamera.transform);
moleObject.transform.rotation = Quaternion.Euler(0.0f,
moleObject.transform.rotation.eulerAngles.y, moleObject.transform.rotation.z);
์๋ ์ฝ๋์ฒ๋ผ anchor์ ์์์ค๋ธ์ ํธ๋ก ๋ฃ์ด์ผ ์์น, ํ์ ๋ณด์ ์ ๊ณ์ ๋ฐ์์ ์๋ค.
moleObject.transform.parent = anchor.transform;
์ฌ๊ธฐ ๊น์งํ๋ฉด ๋ฐ๋ฅ์ ์ค์บํ์๋ ๋๋์ง๋ฅผ moleGap๋งํผ ๋จ์ด์ง๊ฒ ์์ฑํ ์ ์๋ค.
์ด ๊ธ์ ๋๋์ง๊ฒ์์ ์ด๋ฏธ ๊ฑฐ์ ์์ฑ๋๊ฑธ ๊ธฐ์ค์ผ๋ก ํ๊ธฐ ๋๋ฌธ์ ์ก๋คํ๊ฑด ์์์ ๋ง๋ค๋ฉด๋๋ค.
๋ค์์๋ ๋ฐ๋ฅ์ ์ฐพ๋ ๊ฐ์ด๋๋ฅผ ์ด๋ป๊ฒ ๋ง๋๋์ง ์จ๋ณผ๊ป
์ค AR์ ์ํ์ง๋ง ์ข์ ๊ธ์ธ๊ฑฐ ๊ฐ๋ค
ar๊ฒ ์ฌ๋ฐ์ง