์•ˆ๋…•ํ•˜์„ธ์š”
์œ ๋‹ˆํ‹ฐ Jobsystem , Burst ์ด์šฉํ•ด์„œ ์ž์ฒด ์ถฉ๋Œ์ฒด ๋งŒ๋“œ๋Š”๊ฑธ ๋ชฉํ‘œ๋กœ ๊ธ€์„ ํ•œ๋ฒˆ ์จ๋ณผ๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
์ด๋ฒˆ์— ๊ฒŒ์ž„ ๋งŒ๋“ค๋ฉด์„œ ์ž์ฒด ์ถฉ๋Œ์ฒด๊ฐ€ ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค. ใ… ใ… 
๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ๋„์›€์ด ๋˜๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ €๋„ ์‹ค๋ ฅ์ด ๋ถ€์กฑํ•œ์ง€๋ผ.. ๋ง‰ ์ฝ”๋“œ ์„ฑ๋Šฅ์ด ์—„์ฒญ ์ข‹๋‹ค ์ด๋Ÿฐ๊ฑด ์žฅ๋‹ด๋ชปํ•ฉ๋‹ˆ๋‹ค.. ใ… ใ… 
์ผ๋‹จ ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ์Šคํฌ๋ฆฝํŠธ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด ์ค์‹œ๋‹ค ์ €๋Š” CollisionSystemV2 ์œผ๋กœ ์ด๋ฆ„์„ ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
public class CollisionSystemV2 : MonoBehaviour
{
public static CollisionSystemV2 ins#tance; #์€ ์ง€์šฐ๊ณ  ์“ฐ์„ธ์š” ๊ธˆ์ง€์–ด๋•Œ๋ฌธ์—
private void Awake()
{
if(ins#tance != null)
{
if(ins#tance != this)
{
Destroy(ins#tance);
}
}
ins#tance = this;
}
}
๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ์˜ ์ถฉ๋Œ์ฒด๊ฐ€ ๋  ํด๋ž˜์Šค ํ•˜๋‚˜ ๋” ๋งŒ๋“ค์–ด์ค„๊ฒŒ์š”
public class NativeCollider
{
public int id; //์ถฉ๋Œ์ฒด์˜ ID
public object entity; //์ถฉ๋Œ์ฒด์˜ ๋ฌผ์ฒด
public bool isCircle; //์ถฉ๋Œ์ฒด๊ฐ€ ์›์ธ๊ฐ€?
public bool isDynamic; //๊ณ„์† ์›€์ง์ด๋Š” ์ถฉ๋Œ์ฒด์ธ๊ฐ€
public Vector2 position; //์ถฉ๋Œ์ฒด์˜ ์œ„์น˜
public Vector2 size; //์ถฉ๋Œ์ฒด์˜ ์‚ฌ์ด์ฆˆ
}
์ด๋Ÿฐ์‹์œผ๋กœ ๊ตฌ์กฐ๋ฅผ ์งœ์คฌ์Šต๋‹ˆ๋‹ค.
์ด์ œ ์ด ์ถฉ๋Œ์ฒด๋“ค์„ ๋‹ด์•„๋†”์•ผ, ์—ฐ์‚ฐ์„ ํ•˜๋“  ๋ญ๋“  ํ• ํ…Œ๋‹ˆ
์šฐ๋ฆฌ ์•„๊นŒ ๋งŒ๋“  ์‹ฑ๊ธ€ํ†ค ํด๋ž˜์Šค์—๋‹ค๊ฐ€ ๋‹ด์„ ๋ณ€์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์ค์‹œ๋‹ค.
public List<NativeCollider> entityList;
์ด์ œ ์—ฌ๊ธฐ๋‹ค๊ฐ€ ์ถฉ๋Œ์ฒด๋“ค์„ ๋‹ด์•„๋†“์„๊ฑฐ์˜ˆ์š”. ์ €๋Š” ์ถฉ๋Œ์ฒด ID๊ธฐ์ค€์„ List์— ๋“ค์–ด๊ฐ„ Index๋กœ ์žก๊ณ ์‹ถ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๊ธฐ์œ„ํ•ด์„  FreeList์„ ์ด์šฉํ• ๊ฒ๋‹ˆ๋‹ค. (์ด๊ฒŒ ๋ช…์นญ์ด ๋งž๋Š”์ง€๋Š” ๋ชจ๋ฅด๊ฒ ์–ด์š” , ์™ธ๊ตญ์‚ฌ์ดํŠธ์—์„œ ์ฐพ์€๊ฑฐ๋ผ์„œ ใ…Žใ…Ž)
์ €๋Š” FreeList๋ผ๊ณ  ๋ถ€๋ฅผ๊ฒŒ์š”
FreeList๋Š”
C# List์‚ฌ์šฉ์‹œ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•˜๋ฉด ๊ธธ์ด๊ฐ€ ๋‹ฌ๋ผ์ง€์ž–์•„์š”.
์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•˜์ง€์•Š๊ณ  ๊ทธ ์š”์†Œ Index๋ถ€๋ถ„๋งŒ null๋กœ ๋ฐ”๊ฟ”์„œ index์œ„์น˜๊ฐ’๋งŒ ๋‹ค๋ฅธ๊ณณ์— ์ €์žฅํ•ด๋†“๊ณ  ๋‹ค์Œ์— ๋‹ค๋ฅธ ์š”์†Œ๊ฐ€ ์ ‘๊ทผํ• ๋•Œ ์ €์žฅ๋œ index์„ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.
์ด๋ ‡๊ฒŒํ•˜๋ฉด id๋ถ€๋ถ„์ด ๋ณด์žฅ์ด๋ฉ๋‹ˆ๋‹ค. ์ œ๊ฐ€ ์„ค๋ช…์„ ์ž˜๋ชปํ•ด์„œ ใ…Žใ…Ž ์ดํ•ด๋ชปํ•˜์…จ์œผ๋ฉด ์ฝ”๋“œ๋กœ ๋ด๋ฐ”์š”
private void AddEntityList(NativeCollider entity)
{
int index = 0;
if(entityFreeList.Count > 0)
{
index = entityFreeList[entityFreeList.Count - 1];
entityFreeList.RemoveAtSwapBack(entityFreeList.Count - 1);
entityList[index] = entity;
}
else
{
entityList.Add(entity);
index = entityList.Count - 1;
}
entity.id = index;
}
private void RemoveEntityList(NativeCollider entity)
{
entityList[entity.id] = null;
entityFreeList.Add(entity.id);
}
์ด๋Ÿฐ์‹์œผ๋กœ ์‹ฑ๊ธ€ํ†คํด๋ž˜์Šค์— ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์คฌ์Šต๋‹ˆ๋‹ค.
public List<int> entityFreeList; ๋ณ€์ˆ˜๋„ ์ถ”๊ฐ€ํ•ด์คฌ์Šต๋‹ˆ๋‹ค.
์—ฌ๊ธฐ์„œ ์ถ”๊ฐ€๋œ entityFreeList๋Š” entityList ๋ณ€์ˆ˜์—์„œ ๋‚˜์˜จ ๋นˆ index์„ ์ €์žฅํ•˜๋Š”๊ณณ ์ž…๋‹ˆ๋‹ค.
์ฝ”๋“œ๋ฅผ ๋ณด์‹œ๋ฉด ๋Œ€์ถฉ ์ดํ•ด๊ฐ€ ๋˜๋‚˜์š”??
์ด์ œ๋ถ€ํ„ฐ๋Š” ์ƒˆ๋กœ์šด ์ถฉ๋Œ์ฒด๋ฅผ ์ถ”๊ฐ€ํ• ๋•Œ๋Š” ๋ฐ”๋กœ ๋ฆฌ์ŠคํŠธ์—๋‹ค๊ฐ€ ์ถ”๊ฐ€ํ•˜์ง€๋ง๊ณ  ์œ„์— ์ฝ”๋“œ์ฒ˜๋Ÿผ ์ถ”๊ฐ€,์‚ญ์ œ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
์ž ์ด์–ด์„œ ์ด์ œ JobSystem์„ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ๊ตฌ์กฐ์ฒด๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์ค์‹œ๋‹ค.
์Šคํƒ์— ์ €์žฅ๋˜๋Š” ํ˜•์‹์œผ๋กœ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ž…๋‹ˆ๋‹ค.
(์žก์‹œ์Šคํ…œ์„ ์ด์šฉํ• ๋ ค๋ฉด ๊ฐ’ํƒ€์ž…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค!)
public struct ColliderBody
{
public int id;
public bool isCircle;
public float2 position;
public float2 size;
public ColliderBody(int id, bool isCircle,float2 position, float2 size)
{
this.id = id;
this.isCircle = isCircle;
this.position = position;
this.size = size;
}
}
์ž ์ด์ œ ์ด ๊ตฌ์กฐ์ฒด๋Š” ์šฐ๋ฆฌ ์•„๊นŒ ๋งŒ๋“  ์ถฉ๋Œ์ฒด ํด๋ž˜์Šค์˜ ์—ฐ์‚ฐ์„ ์œ„ํ•œ ์ •๋ณด๋ฅผ ๋‹ด๊ณ ์žˆ๋Š” ๊ตฌ์กฐ์ฒด์ž…๋‹ˆ๋‹ค.
์ด์ œ ์‹ฑ๊ธ€ํ†ค ํด๋ž˜์Šค์— ์ด ๊ตฌ์กฐ์ฒด๋ฅผ ๋‹ด์„ ๋ณ€์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์ค์‹œ๋‹ค.
public NativeAr#ray<ColliderBody> bodys;
NativeAr#ray๋Š” Persistent๋กœ ์„ ์–ธํ•ด์ค˜ํ•ด์•ผํ•ด์š”!! ๊ณ„์† ์“ธ๊ฑฐ์ž…๋‹ˆ๋‹ค.
ํ˜น์‹œ ๋ชจ๋ฅด๋‹ˆ๊น ์Šคํฌ๋ฆฝํŠธ ๊บผ์งˆ๋•Œ Dispose๋„ ํ•ด์ฃผ์„ธ์š”
์ด์ œ ์ถฉ๋Œ์ฒด ํด๋ž˜์Šค์— ColliderBody์„ ํŽธํ•˜๊ฒŒ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์ค์‹œ๋‹ค.
public ColliderBody GetBody()
{
return new ColliderBody(id, isCircle, position, size);
}
๊ทธ๋ฆฌ๊ณ  ์•„๊นŒ ์‹ฑ๊ธ€ํ†คํด๋ž˜์Šค์—์„œ ๋งŒ๋“  ์ถฉ๋Œ์ฒด ์ถ”๊ฐ€, ์ œ๊ฑฐ ํ•จ์ˆ˜๋ถ€๋ถ„์„ ์ˆ˜์ •ํ•ด์„œ ColliderBody ๋‹ด๊ณ ์žˆ๋Š” bodys๋ณ€์ˆ˜ ์—๋‹ค๊ฐ€
์ถ”๊ฐ€๋˜๊ฒŒ๋” ๋งŒ๋“ค์–ด์ค์‹œ๋‹ค.
bodys[index] = entity.GetBody();
private void AddEntityList(NativeCollider entity)
{
int index = 0;
if(entityFreeList.Count > 0)
{
index = entityFreeList[entityFreeList.Count - 1];
entityFreeList.RemoveAtSwapBack(entityFreeList.Count - 1);
entityList[index] = entity;
}
else
{
entityList.Add(entity);
index = entityList.Count - 1;
}
entity.id = index;
bodys[index] = entity.GetBody();
}
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ด์ œ ๊ธฐ๋ณธ๊ตฌ์กฐ๋Š” ๋์ž…๋‹ˆ๋‹ค.
๋‹ค์Œ๊ธ€์—์„  ์ด์ œ ์ด ๊ตฌ์กฐ๋ฅผ ์ด์šฉํ•ด์„œ ๋ณ‘๋ ฌ ์ถฉ๋Œ ์—ฐ์‚ฐ ํ•ด๋ด…์‹œ๋‹ค! ๊ทธ ์ดํ›„์— ๋ ˆ์ด์–ด๋งˆ์Šคํฌ, OnEnter,OnExit,OnStay ์ด๋ฒคํŠธ๋ฐœ๋™ ๊นŒ์ง€ ๊ตฌํ˜„ํ•ด๋ณผ๊ฒŒ์š”.
๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.