URL
EMBED
Page 0:
Page 1: 게임 플레이어에게 의사 충격을 효율적으로 전달하는 방법에 관 한 연구
Making Game More Spicy ARN Gamez 김도완
Page 2: 요약문
• 현실 세계에서 타격, 혹은 피격 행동을 취했을 때 행동을 취한 사람은 시각, 청각, 촉각으로 충격의 느낌을 받는다. • 게임에서 폭력 액션이 존재하는 게임은 필연적으로 타격, 피격행동이 존재하며 이 때 플레이어는 실제로 받는 느 낌과 유사한 의사 충격을 받는다. 보통 타격감이라고 표 현하는 이것은, 플레이어가 게임에 몰입하는 데 도움을 주는 요소임과 동시에, 플레이이어에게 카타르시스를 느 끼게 해 주는 요소이다. • 본 강연은, 사람의 3가지 감각을 통해 의사충격을 보다 더 효율적이고 현장감이 있게 플레어에게 전달하는 방법 에 대하여 말하고 있다.
Page 3: 목차
• • • • • 개요 영상에 의한 표현 음향효과에 의한 표현 촉각에 의한 표현 결론
Page 4: 개요
Page 5: 개요 – 타격감의 정의
• 타격감 : 때리거나, 맞을 때 느끼는 충격 • 시각, 청각, 촉각, 통각으로 표현됨
– 게임에서는 통각이 없다
• 게임에 의해 쾌감을 플레이어에게 직접적 으로 전달하는 효과적인 매개체 • 플레이어의 타격, 피격에 모두 적용된다
Page 6: 충격
• 충격은 짧고, 굵게 느낄수록 효과적
– 인생과 비슷하다
• 충격의 여운 : 굵고 짧은 충격 뒤에 오는 여파
– 인간은 시각의 경우 유지시간 약40ms 이하의 영상은 보더라도 느끼지 못함 – 통각의 경우 : 칼에 베였을 때 실제적인 통증은 약 4-5초 이후에 온다 – 청각은 즉각적으로 반응함 : 공기의 운동에너지가 감각기관에 직 접적으로 에너지를 전달하기 때문. 고막의 진동으로 여운이 남아 짧고 굵은 소리로도 충격을 느낄 수 있다. – 고막 외에도 강한 공기의 진동을 피부로 느낌 : 촉각
• 인간의 정보 입수는 대부분이 시각에 의존
– 전체를 100으로 보았을 때 약 70을 시각에 의존 – Simulation Sickness(FPS멀미)는 시각만으로 인간의 평형감각 을 마비시킬 정도다
Page 7: 의사 충격
• • • • 게임에 있어 폭력성 액션이 발생할 때 느끼는 충격
– 진짜가 아니다 – 진짜보다 못하다 : 아픔이 없다
진짜보다 못하기 때문에 다른 요소를 실제보다 과장되게 증폭하여 마치 플레이어가 충격을 받는 것처럼 표현함 플레이어가 공격할 때의 충격 표현이 맞을 때보다 더 중요함
– 게임에서의 폭력은 카타르시스이기 때문이다
시각, 청각이 주 요소. 인풋 디바이스의 발달로 촉각도 사용가능
– 그러나 함으로 – 제대로 충격을 – 충격과 인간의 정보이해 특성과 인풋 디바이스를 통한 촉각표현의 부실 인해 가장 중요한 요소는 시각 표현이다 된 의사 충격으로 타격감을 표현하려면 소리 끄고 화면만 봐도 받는 느낌이 나야 한다 충격의 여운을 시각적으로 잘 표현하는 것이 중요
Page 8: 영상에 의한 충격의 표현
Page 9: 프레임 조작
• 타격 순간 프레임을 정지한다 • 프레임 스킵과 프레임 프리즈 두 가지 • 자칫 잘못하면 타격감이 아니라 프레임이 뚝뚝 끊겨서 불쾌감을 유발할 수 있음
– 특히 키보드, 마우스 입력 폴링을 렌더링 스레드에서 한다면 조 작감의 영향도 줄 수 있다
• 캡콤 게임에서 자주 사용함
– 파이널 파이트, 스트리트 파이터 등 : 프레임 프리즈 기법
• 두들겨 패는 게임에 어울린다 • FPS에서도 사용 가능하나 제한적
– 너무 오래 프레임을 정지시키면 조작감에 치명적인 악영향 – 한 방에 머리가 날아가는 게임인만큼 프레임 정지가 조작감 및 플레이어의 시야를 방해해서는 안 된다 – 프레임 프리즈는 사용하기 어렵다
Page 10: 프레임 스킵
• 타격 순간 애니메이션을 일정 시간 정지 • 정지 후 애니메이션을 진행할 때 정지시간만큼 을 더해서 애니메이션을 진행함 • 전체적으로는 애니메이션의 흐름을 방해하지 않 는다
– 애니메이션의 원래 런타임에 영향을 주지 않기 때문
• 맞고 날아가는 적의 이동을 순간 빠르게 해 주어 박력을 더하게 하는 효과도 있음 • 과다하게 스킵 시간을 줄 수 없다
– 심하면 무슨 행동이 일어났는지조차 알 수 없으므로
Page 11: 프레임 프리즈
• 타격 순간 애니메이션을 일정 시간 정지하는 것 은 프레임 스킵과 동일함 • 정지 후 정지시간동안 흘러갔던 애니메이션 delta를 고려하지 않는다
– 말 그대로 얼음땡
• 프레임 스킵에 비해서 정지시간을 길게 줄 수 있 다
– 애니메이션의 시각적 표현에 영향을 주지 않으므로
• 애니메이션의 런타임에 영항을 줌 : 길어진다
– 원래 런닝타임 + 정지시간 – 애니메이션 제작 당시부터 이것을 고려해야 함
Page 12: 프레임 조작(2)
• 베는 것이 아닌 때리거나 쏘는 게임에서는 효과가 크다 • 정지시간을 길게 줌으로서 충격의 여운을 표현하는 효과 가 늘어난다 • 아무리 짧은 정지라도 인간에게 있어서는 눈에 거슬림
– 정지 시간동안 모든 것이 정지해서는 안 된다 – 타격/피격 이펙트는 그대로 돌리고 캐릭터만 정지시키자 – 맞은 캐릭터, 때린 캐릭터 외에는 모두 제대로 움직이고 있어야 함 – 이 조건이 만족 안되면 프레임 정지는 타격감 향상이 아니라 단 순한 화면 끊김현상으로밖에 인식되지 않음
• 정지시간동안 캐릭터도 가만히 있지 말자
– 단순한 부르르도 효과가 있음 : 화면끊김 짜증 해소 및 타격느낌 증가 – 더 효과적인 방법은 타격점 계산에 의한 방향성 부르르
Page 13: 프레임 조작(3)
• • 프레임 정지시간동안의 캐릭터 진동 무방향성 진동
– – – – 렌더링 시 캐릭터 피봇을 무작위로 흔듬 Pivot(xnew, ynew, znew) = (xorg, yorg, zorg) + (rand() % MARGIN, rand() % MARGIN, rand() % MARGIN) 또는 : Mattransform = D3DXMatrixTranslation(Matold_transform, rand() % MARGIN, rand() % MARGIN, 0) 흔들리는 범위는 2픽셀 이내가 적당함 : 너무 흔들면 방정맞음 단순한 무작위 진동이 아닌, 캐릭터의 타격방향을 고려 타격방향
• • 공격자 : Direction(x, y, z) = AttkPoint(x, y, z) – Attker(x, y, z) 피격자 : Direction(x, y, z) = Victim(x, y, z) - AttkPoint(x, y, z) Pivot(xnew, ynew, znew) = Pivot(xorg, yorg, zorg) + D3DXVec3Normalize(Direction(x, y, z)) * (rand() % MARGIN) MARGIN의 크기는 적절히 조절 타격, 피격 방향으로 캐릭터가 흔들림 Rand() % MARGIN 대신 delta * (delta - FREEZE_LENGTH) * MARGIN을 쓸 수 있다. 이 경우 캐릭터의 진동은 뒤로 물 러섰다가 다시 돌아오는 스윙현상을 보인다. 날카로운 타격감은 rand(), 둔기의 충격 같은 느낌을 표현하는데 이차함수가 적당하다.
•
방향성 진동
– – –
Pivot
• • • • •
•
주의사항 : 진동을 섞을 경우에는 프레임 정지 시간을 길게 잡지 말 것
– 진동이 눈으로 보일 정도로 느껴질만큼 정지시간이 길어지면 오히려 거부감이 든다.
Page 14: 타격 파티클의 표현(1)
• • • • • 타격의 느낌을 조금 더 강조하는 양념 실제로 존재하는 현상이 아님
– 만화나 만화영화의 영향으로 친숙해짐 – 맞았을때 순간적으로 눈이 번쩍하는 느낌에서 유래한 것이 아닐까?
타격이 발생했다고 느끼는 순간 발생 프레임 정지기법과 동시에 사용할 때 사용자로 하여금 불쾌한 느낌 이 들지 않게 하는 역할도 겸한다
– 프레임이 끊긴다는 느낌을 주지 않게 한다
부가적인 파티클
– 피가 튀거나 이빨이 튀기는 등의 효과
• 특히 FPS게임에서 효과를 발휘함 • FPS에서 헤드샷이 났을 때 피가 높이 튀거나 영등위가 허가하는 한에서 사 지가 퍽 하고 터지는 느낌을 주면 효과가 크다
– 탄환의 궤적
• FPS에서 궤적의 표현은 총을 쏘는 느낌을 배가시킨다
Page 15: 타격 파티클의 표현(2)
• 파티클의 형태
•일반적인 타격 형태 •가볍고 빠른 공격, 가벼운 타격 무기(각목, 톤파, 쌍절곤 등)에 적합 •번쩍 하고 순식간에 사라지는 느낌으로 표현하는것이 효과적 •지면을 내려치는 느낌, 혹은 지면을 박차는 느낌 •타격 외의 점프액션의 박진감을 강조하는 데도 사용 가능 •지속시간을 비교적 짧게, 프레임정지도 짧게. •일렬로 사용해 지면을 질질 끄는 느낌으로 사용해도 좋다 •대종을 치는 느낌, 둔기로 두드 리는 느낌을 표현하는 데 효과 적 •원 형태의 충격파가 주위로 퍼 지는 느낌으로 표현 •프레임 정지를 길게, 피격자는 깊게 흔들리거나 깨지는 느낌의 애니메이션으로 표현 •방향성이 있는 충격의 발산 혹 은 반사 •날카롭게 찌르는 느낌, 혹은 공 격을 방어하는 느낌을 표현 •프레임 정지는 짧게, 단 방어형 태에서는 방어자의 경직을 플레 이어가 느낄 수 있는 정도로 표 현 •폭발하는 느낌, 사용이 제한적이다 •폭파형 무기, 성형작약식 근접무기 등을 표현 •다른 파티클보다 오래 표현하고 프 레임정지 사용시 지속시간을 조금 길게 준다
Page 16: Directional Light
• • • 타격점에서 파티클과 함께 사용 파티클을 하나의 밝은 광원으로 인지 프로시저
– (1) 파티클을 표현하는 시간 동 안 강제적으로 공격자와 피격자 의 라이트 방향을 타격점으로 전 환 – (2) 라이트의 RGB값도 원래의 라이트보다 강하게 주고 – 공격이 끝나면 원래의 라이팅으 로 바꾼다
• •
무척 간단하고 효과적인 방법 큰 공격의 표현에는 추가적으로 화면 전체를 Flash시키는 방법도 사용할 수 있다
Page 17: 화면 굴절(1)
• • • • • • • 닌자가이덴 등에서 사용하고 있음 화면에서 타격점이 표시되는 부분에 수면파 같은 파동을 일으킨다 기본 원리는 Scene을 RenderToTexture로서 화면에 표시하기 위한 텍스처에 그리고 그것을 변형하는 것 화면에 그리기 위해 바둑판 형태의 Mesh를 준비함 이지러짐은 화면용 Mesh의 Vertex들의 UV, 혹은 z값을 변형하는 것으로 구현 잔잔한 수면에서 원형 물결이 퍼져나가는 형태로 구현 파동방정식에 준거
– 파동방정식은 가우스함수를 기반으로 한다
Page 18: 화면 굴절(2)
• 수면파를 위한 가우스함수
– – – – – h는 파고의 시작 높이 t는 파고 시작시부터 현재까지 진행된 시간 r은 파고의 최대 전파 거리(파도원의 반지름) d는 파동원으로부터의 현 지점의 거리 2 F(z) = max(h(t / r + 1)e-(d-t) , h(t / r + 1)e-(d2 t) ) (1) 화면 표시용 Mesh를 생성한다. (2) 필요한 순간에 수면파원을 삽입한다 (3) 현재의 뷰포트를 화면 표시용 Texture로 설정한다. (4) 화면에 그려야 할 내용을 화면 표시용 Texture에 RenderToTexture()한다 (5) 뷰포트를 비디오 카드의 프레임 버퍼로 설 정한다 (5) 렌더링 최종 단계에서 화면 표시용 mesh 에 현재 진행되고 있는 수면파원을 적용, F(z) 에 의해 mesh의 z값 혹은 UV값을 누적 감산 한다.(DX좌표계의 경우) (6) RenderToTexture()로 화면 표시용 mesh 에 렌더링한다. (7) 메인 뷰포트를 present()한다
#define max(a, b) a > b ? a : b struct WaveElement { float fX, fY; //굴절파 발생지점 float fRound; //파가 번지는 최대 반지름 float fMaxHeight; //파의 최초 높이 (z값) float fDelta; //현재 진행된 시간(및 현재 파의 반지름) }; std::list<WaveElement> s_listWaveElement;//파동원 리스트 struct Vertex { float fPos[3]; //화면 메시의 xyz float fUV[2]; //화면 메시의 uv }; //전역변수들 static Vertex* s_pVertices = NULL; static Vertex* s_pStaticVertices = NULL; static int s_iXRes, s_iYRes; //화면의 해상도 static int s_iXResOfDisplayMesh, s_iYResOfDisplayMesh; //화면 매시의 격자 수 //초기화함수 void Init(int iXResOfDisplayMesh, int iYResOfDisplayMesh, int iScreenXRes, int iScreenYRes) { if(s_pVertices != NULL) delete s_pVertices; if(s_pVertices != NULL) delete s_pStaticVertices; //파동원 리스트의 초기화 s_listWaveElement.clear(); //전역변수 초기화 s_iXResOfDisplayMesh = iXResOfDisplayMesh; s_iYResOfDisplayMesh = iYResOfDisplayMesh; s_iXRes = iScreenXRes; s_iYRes = iScreenXRes; //화면 버텍스 버퍼 만들기 s_pVertices = new Vertex[iXResOfDisplayMesh * iYResOfDisplayMesh]; s_pStaticVertices = new Vertex[iXResOfDisplayMesh * iYResOfDisplayMesh]; for(int nCount = 0; nCount != iYResOfDisplayMesh; ++nCount)
•
수행 과정
– – – – – –
– –
Page 19: 화면 굴절(3)
{ for(int nCount2 = 0; nCount2 != iXResOfDisplayMesh; ++nCount2) { s_pStaticVertices[nCount * iYResOfDisplayMesh + nCount2].fPos[0] = ((float)nCount2 / (float)iXResOfDisplayMesh) * (float)s_iXRes; s_pStaticVertices[nCount * iYResOfDisplayMesh + nCount2].fPos[1] = ((float)nCount / (float)iYResOfDisplayMesh) * (float)s_iYRes; s_pStaticVertices[nCount * iYResOfDisplayMesh + nCount2].fPos[2] = 0.0f; s_pStaticVertices[nCount * iYResOfDisplayMesh + nCount2].fUV[0] = ((float)nCount2 / (float)iXResOfDisplayMesh); s_pStaticVertices[nCount * iYResOfDisplayMesh + nCount2].fUV[1] = ((float)nCount / (float)iYResOfDisplayMesh); } } memcpy(s_pVertices, s_pStaticVertices, sizeof(Vertex) * iXResOfDisplayMesh * iYResOfDisplayMesh); } //새로운 파동원을 넣는다 void InsertWave(float fX, float fY, float fRound, float fMaxHeight) { WaveElement _Wave; _Wave.fX = fX; _Wave.fY = fX; _Wave.fRound = fRound; _Wave.fMaxHeight = fMaxHeight; _Wave.fDelta = 0.0f; s_listWaveElement.push_back(_Wave); } float GetDistance(float fXOrg, float fYOrg, float fX, float fY) { return sqrt((fXOrg - fX) * (fXOrg - fX) + (fYOrg - fY) * (fYOrg - fY)); } //현재 시간진행 fDelta에 따라 화면 mesh를 업데이트한다 void Update(float fDelta) { std::list<WaveElement>::iterator it = s_listWaveElement.begin(); memcpy(s_pVertices, s_pStaticVertices, sizeof(Vertex) * s_iXResOfDisplayMesh * s_iYResOfDisplayMesh); while(it != s_listWaveElement.end()) { (*it).fDelta += fDelta; for(int nCount = 0; nCount != s_iYResOfDisplayMesh; ++nCount) { for(int nCount2 = 0; nCount2 != s_iXResOfDisplayMesh; ++nCount2) { float fDistance = GetDistance((*it).fX, (*it).fY, s_pVertices[nCount * s_iYResOfDisplayMesh + nCount2].fPos[0], s_pVertices[nCount * s_iYResOfDisplayMesh + nCount2].fPos[1]); //파동원으로부터의 거리가 임계점을 넘는다면 skip한다 if(fDistance > (*it).fRound) continue; //가우스함수 float fCurrentHeight = max(exp(-(fDistance - (*it).fDelta) * (fDistance - (*it).fDelta)), exp(-(fDistance + (*it).fDelta) * (fDistance + (*it).fDelta))); fCurrentHeight *= (*it).fMaxHeight * ((*it).fDelta / (*it). fRound + 1); //여러 파동원이 만드는 파고의 값을 누적해서 버텍스의 z값을 더한다 s_pVertices[nCount * s_iYResOfDisplayMesh + nCount2].fPos[2] -= fCurrentHeight; } } //임계시간이 지난 파동은 삭제한다 if((*it).fDelta < (*it).fRound) it = s_listWaveElement.erase(it); else ++it; } }
Page 20: 화면 굴절(4)
• Real World에는 있을 수 없는 현상
– 과도한 연출은 오히려 실감을 떨어뜨린다
• 새로운 시도로서 참신함을 강조함 • 가우스함수 기반으로 계산량이 많다
– 가우스함수 대신 1차함수를 사용할 수 있다 – -abs((h / r) * (d – t)) + h – 형태는 이등변삼각형 형태
• 적절한 mesh의 밀도를 지정
– 밀도가 너무 낮으면 수면파가 거칠고 너무 높으면 계 산량이 많아짐
Page 21: 애니메이션(1)
• 공격자, 피격자가 타격을 주고받았을 때 취하는 움직임 • 가장 중요한 부분 • 피격자의 애니메이션이 공격자보다 더 중요하다
– 정말 아픈것처럼 보이게 하는 것이 중요 – 진짜로 저렇게 맞으면 정말 아프겠다라는 생각을 플 레이어에게 주게 해야 한다
• 실세계의 물리법칙보다 과장되게 표현한다 • 하지만 애니메이션 자체는 프로그래머의 영역이 아님
Page 22: 애니메이션(2)
• 프로그래밍적인 양념
– 애니메이션의 delta 제어
• 시간은 기울기 1의 1차방정식이다. 중요한 건 애니메이션 종료시점이 delta를 제어하지 않았을 때와 같으면 되는 것이다. • 피격 애니메이션 진행을 처음에는 빠르게, 나중에는 느리게 한다
– f(delta) = sqrt(fAnimLength * delta) – 맞고 날아갈 때 처음에는 좀 빠르게, 나중에는 천천히 날아가게 함 – 빠르고 가벼운 공격 등에 어울린다
• 피격 애니메이션 진행을 처음에는 느리게, 나중에는 빠르게 한다
– f(delta) = delta * delta / fAnimLength – 맞을 때 처음에는 천천히 날아가다 점점 가속된다 : Real World에는 있을 수 없다 – 무거운 공격을 맞았을 때의 둔중한 느낌을 표현하기 적합하다
– 피격자의 Roll, Pitch, Yaw조절
• 피격되어 날아갈 때 빙글빙글 도는 느낌 : 카툰적인 표현 • 휘두르는 공격에 맞았을 때 피격을 과장하는 효과가 있다 • 애니메이션 끝 시점에서 제대로 하늘을 보고 누워 있게 도는 속도를 조절해야 함
– 타격했을 때 피격자와 타격자의 방향
• 당연히 서로 마주보게 만든다 • 공격자보다는 피격자의 방향을 바꾼다
Page 23: 모션블러
• • 대쉬형 돌진기술에 첨가하면 시원 한 느낌을 낼 수 있다 DX9은 StretchRect()로 현재 프레 임 버퍼의 내용을 가져올 수 있다 : 매우 저렴한 기법. GPU의 1 %도 사용하지 않음. 단 지원하지 않는 하드웨어는 있을 수 있다 충분한 수의 텍스처가 있으면 최근 몇 프레임의 내용을 히스토리로 저 장해 두고 이것을 가산으로 찍어서 모션블러를 쉽게 구현 가능하다 프레임 히스토리는 최소 5장 이상 사용하는 것이 좋다 StretchRect()는 이 외에도 Full Scene Glow에도 편리하게 이용할 수 있다
•
• •
Page 24: 카메라워크
• • 타격시 화면 전체를 흔든다 FPS게임에서 총을 쏠 때 특히 효과가 있다
– FPS는 다른 장르에 비해 상대적으로 사용할 만한 기법이 마땅치 않기 때문에 카메라의 흔들림이 중요하다 – 부가적으로 총도 같이 흔든다
•
카메라 매트릭스의 _42 element을 조작 : y방향으로 흔든다
– f(x) = fPower * fDelta * (float)(sin(timeGetTime() * PI / 1000.0f) + 0.5f * sin(timeGetTime() * PI / 500.0f) + 0.3 * sin(timeGetTime() * PI / 33.0f)); – fPower는 흔드는 힘, fDeltal는 흔들기 시작한이후로의 진행시간, PI는 원주율
• •
흔드는 시간은 300ms이하로 할 것 약하게 흔들릴때는 상대적으로 흔드는 시간도 더 짧게 조절해야 한 다
Page 25: 음향에 의한 충격의 표현
Page 26: 타격음 (1)
• 피격이 발생하였을 때 재생하는 충격음 • 종류
– 목재, 석재 둔기 타격음, 격돌음 – 금속제 둔기 타격음, 격돌음 – 날이 있는 무기끼리 마주쳤을 때 금속음 – 총성, 포성 – 화약무기의 폭발음 – 파공성
Page 27: 타격음 (2)
• 타격음의 특성에 따른 주파수 강조 대역
– 30Hz : 바람이 약하게 부는 소리, 깃발이 펄럭이는 소리 – 120Hz : 군용모포를 방망이로 두드리는 소리, 둔기로 엉덩이를 치는 소리 – 250Hz : 드럼의 퍼커션 소리, 공사현장에서 콘크리트에 말뚝을 박는 소리 – 500Hz : 병원의 계단을 올라가는 소리 – 1KHz : 거칠게 바람을 가르는 소리 – 2KHz : 각목끼리 부딪치는 소리, 목탁치는 소리 – 4KHz : 손가락 딱 치는 소리
• 120~250Hz대역과 2KHz대역의 특성에 따라 타격음의 느낌이 많은 차이를 보임
– 느리고 무게 실린 공격은 120Hz근처가 강조됨 – 빠르고 날카로운 공격은 2KHz대역이 강조됨
Page 28: 몇 가지 tips
• 여러 명을 동시에 타격할 때
– 카운트를 사용, 한 번에 타격된 피격자의 숫자를 센다 – 동일한 타격음을 카운트수만큼 재생 : 따다닥 하는 느낌으로
• 타격음은 가급적 샘플링 레이트를 떨어뜨리지 않는다
– 고음 부분이 감쇠될 경우 금속성 타격음은 현장감이 많이 떨어진 다 – 둔기음도 샘플링 레이트가 떨어지면 깔끔한 타격음이 살지 않는 다 : 전기기타의 디스토션 같은 음이 낀다
• 가급적 런타임을 짧게 플레이한다
– 짧을수록 딱 끊어치는 느낌이 난다 : 둔기음, 금속음 모두 해당됨
Page 29: 촉각에 의한 충격의 표현
Page 30: 효과음의 부수적인 효과
• 우퍼와 같은 하드웨어가 있으면 저주파 진 동에 의해 플레이어에게 깊은 느낌의 충격 을 전달할 수 있다 • 60Hz이하의 저진동에서 효과를 나타낸다 • 충격음에 믹싱을 하지 말고 별도의 채널로 서 출력하게 하자
– 아주 짧게, 그리고 굵게 – 저주파 채널은 항상 볼륨을 MAX로
Page 31: 포스 피드백 디바이스
• 진동추 모터를 장착한 게임 컨트롤러
– – – – – 2개의 모터 끝에 원기둥을 세로로 자른 형태의 진동추를 장착 모터가 회전하면 추의 맥동이 발생. 이것에 의해 roll, pitch의 2축진동을 구현 돌진공격은 y축(pitch), 회전공격은 x축(roll)의 진동추를 구동하게 할 수 있다 2축간 진동의 차이는 뚜렷하게 느껴지지 않는다 떨고 있다는 느낌을 표현하기 적절함 레이싱 핸들에 충격을 충격을 게임 전용 서보 모터를 장착, 플레이어에게 역토크를 주어 실제 차의 핸들링을 흉내낸 하드웨어 구현하는데는 적합하지 않다 구현하려면 핸들의 서보 모터와는 별도로 진동추를 달아야 함
•
핸들 컨트롤러
– – – –
•
포스 피드백 조이스틱
– – – – 플라이트 시뮬레이터용으로 주로 사용 역시 콘트롤 스틱의 묵직함을 구현하기 위해서 만들어짐. 충격 전달의 목적으로 만들어진 것 이 아님 빠르게 스틱의 절대위치를 변경할 수 있기 때문에 순간적인 충격을 구현할 수 있다 가격이 고가이고 일반적인 액션 게임에는 잘 맞지 않는다
Page 32: 진동자는 과연 효과적인가
• 역치효과
– 인간은 특정 외부자극이 지속되면 더 큰 자극에만 반응하고 지속 적인 자극에는 반응하지 않는다
• 손의 감각효과
– 통점이 인체 모든 부위를 통틀어 가장 많다 – 가장 민감하게 촉각적으로 반응하는 부위 – 진동자를 느끼기에는 적합한 부위
• 게임에 집중하고 있을 때 느껴지는 진동
– 시각적인 요소에서 벗어나 있는 진동은 크게 효과를 보기 어렵다 – 모터는 소형의 것을 사용, 강한 충격을 구현하는 데는 무리가 있 다 – 역치효과 또한 진동으로 충격을 느끼는 데 방해 요소로 작용한다
Page 33: 결론
Page 34: 결론
• • 타격감은 개인차가 있는 감각이다
– 보편적으로 의사 충격을 부여하기 위해서는 많은 임상 실험이 필요. – 특히 대상자가 다양하고 수도 많은 실험군을 통해 실험해야 한다.
시각 효과를 주로, 다양한 방법을 동원할 필요가 있다
– 방법의 수를 다양화하고 이들을 잘 튜닝할 필요가 있다 – 과하기만 한 방법은 오히려 현실감이나 현장감을 떨어뜨리는 것에 주의 해야 한다 : 지나치면 모자람만 못하다
•
가장 중요한 것은 잘 디자인된 애니메이션과 잘 정제된 타격음
– 프로그래머가 할 수 있는 일은 제한적이라는 것을 염두해 두고, 다른 파 트에 이러한 사실을 주지시켜야 함 – 타격감은 폭력을 포함하고 있는 게임에서는 필수적이라는 것을 다른 파 트의 개발자들에게 강하게 인식시켜야 함
Page 35: