์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ARCore ์ƒ์„ฑํ•ด์ฃผ๋Š” ๋ฐ”๋‹ฅ(Plane)์„ ์–ด๋–ป๊ฒŒ ๋‹ค๋ฃจ๊ณ  ๋ฐ”๋‹ฅ์— ๋‘๋”์ฅ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ ๊นŒ์ง€ ์จ๋ณด๋ ค๊ณ ํ•œ๋‹ค.


์ผ๋‹จ ์ด๋ฒˆ๊ธ€๊นŒ์ง€ ์ฝ์œผ๋ฉด ์•„๋ž˜ ๋™์˜์ƒ ๊นŒ์ง€ ๋งŒ๋“œ๋Š”๋ฐ๋Š” ๋ฌธ์ œ ์—†์„๊บผ๋‹ค.




1. Frame ํด๋ž˜์Šค

์šฐ๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ Plane๋“ค์„ ์–ป์„์ˆ˜ ์žˆ๋Š” ํด๋ž˜์Šค์ด๋‹ค.


์˜ˆ์ œ๋ฅผ ๋ณด๋ฉด

Update ๋ฌธ์—์„œย Frame.GetPlanes ํ•จ์ˆ˜๋กœ ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ์ƒ์„ฑ๋œ Plane๋“ค์„ ๊ฐ€์ ธ์˜จ๋‹ค.


๊ตฌ๋™๋˜๋Š” ํ˜•์‹์€ ์˜ˆ์ œ ์†Œ์Šค๋ฅผ ๋ณด๋ฉด ๋Œ€๊ฐ• ์•Œ๊บผ๊ณ  ์šฐ๋ฆฌ๊ฐ€ ์ง‘์ค‘์ ์œผ๋กœ ๋ด์•ผํ•  ๊ฒƒ์€ย 

GetPlanes ํ•จ์ˆ˜๋กœ ์–ป์–ด์˜ค๋Š”ย TrackedPlane ํด๋ž˜์Šค์ด๋‹ค.

Plane์˜ ํฌ์ง€์…˜, ๋กœํ…Œ์ด์…˜, Extent, Boundary Polygon ๋“ฑ์„ ์ œ๊ณตํ•ด์ค€๋‹ค.


๊ทธ๋ฆผ์œผ๋กœ ์„ค๋ช…ํ•˜๋ฉด ๋Œ€๊ฐ• ์ด๋ ‡๋‹ค.

viewimage.php?id=2abcdd23dad63db0&no=24b0d769e1d32ca73fef87fa11d028313cb65f50fe50c4dcac889073db7c93630c95f8aed5d14bd0cfd28e9cd6bf841ea50e8e6176f413694f3d28815b61ad1af0f7f3

(๊ทธ๋ฆผ ํ›”์ณ์˜จ๊ฑฐ๋ผ ์ ์ ˆ์น˜ ์•Š์„์ˆ˜๊ฐ€ ์žˆ์ง€๋งŒ ๋Œ€๊ฐ• ์•Œ์•„๋“ค์–ด๋ผ)


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๋งŒํผ ๋–จ์–ด์ง€๊ฒŒ ์ƒ์„ฑํ• ์ˆ˜ ์žˆ๋‹ค.


์ด ๊ธ€์€ ๋‘๋”์ง€๊ฒŒ์ž„์€ ์ด๋ฏธ ๊ฑฐ์˜ ์™„์„ฑ๋œ๊ฑธ ๊ธฐ์ค€์œผ๋กœ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์žก๋‹คํ•œ๊ฑด ์•Œ์•„์„œ ๋งŒ๋“ค๋ฉด๋œ๋‹ค.



๋‹ค์Œ์—๋Š” ๋ฐ”๋‹ฅ์„ ์ฐพ๋Š” ๊ฐ€์ด๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ๋งŒ๋“œ๋Š”์ง€ ์จ๋ณผ๊ป˜