VioletaBabel

42. 시야 가리는 벽 반투명 본문

BCA/6. Unity RPG 따라하기
42. 시야 가리는 벽 반투명
Beabletoet 2018. 6. 15. 15:06

카메라에 BgmOnOff는 있는데 볼륨 조절이 없으니

BGM.cs에 setVolume(float vol) 함수를 만들어 볼륨을 저장

그렇게 사운드 조절과 퀄리티 세팅도 다 넣어주자.


===


게임씬이라는 애를 만든다.

시작 버튼 누를 시 그 씬으로 가도록 이어준다.


===


터레인을 만들고 주인공을 넣는다.

카메라가 주인공을 따라가게 하자.

FollowCamera.cs를 만든다.

그 다음 주인공을 public gameobject로 받아온 후 주인공의 포지션과 카메라의 포지션을 벡터3로 각각 저장한다(heroPos, camPos)

그리고 카메라의 포지션을 주인공에게서 일정 위치로 떨어뜨려놓는다.(우선은 주인공이 어디를 보든 상관없이 한 쪽으로 카메라 고정)


===

그리고 주인공의 움직임을 다룰 스크립트를 만들자.

MoveCharacter.cs를 만들어 주인공에게 넣고 

Vector3로 주인공의 위치를 받아온 후 누르는 키(wasd)에 따라 값(스피드값*time.deltatime)을 더하고 빼준다.


===


카메라가 주인공을 그냥 따라만 가므로 FollowCamera.cs에Mathf.SmoothDamp를 이용해보자.

transform.position = Vector3.SmoothDamp(transform.position,camPos,ref velocity,smoothTime);

//현재 위치, 도착할 위치, 현재 속도, 타겟에 도착하는 대략적인 시간(값이 작을수록 더 빠르게 도착), 최대속도 고정, 이 함수가 마지막에 호출되고 나서의 경과 시간)

ref를 앞에 붙이는 건 레퍼런스로 받아오는 것(c++에서의 레퍼런스 변수라고 생각하면 될 듯)


이제 카메라가 되게 자연스럽게 따라온다.


===


그리고 우선 바깥에 벽을 깔자. 1스테이지니 간단한 미로를 생성.

window의 navigation을 켜고 바닥은 navigation tab의 navigation Area를 walkable, 장애물들은 not walkable로 한다.

캐릭터에게 nav mash agent를 넣고, bake의 agent radius를 좀 크게 잡은 후 bake한다.(캐릭터가 벽을 파고드는 현상을 방지)


===


키를 누르면 지금은 이동만 하되 한 방향만 보고 있다.

각 키마다 어떤 방향을 보는 지도 넣어보자.

이건 필기는 생략


===


이제 카메라에 걸쳐지는 사물은 페이드하는 것을 해보자

FollowCamera.cs에 FadeOutWall() 함수를 private하게 만든다.

그리고 빔에 맞은 애들을 저장해두고 빔에 쏘이지 않게 되면 투명하게 풀려야 함.

그러므로 mTransparentWalls와 newAddedWall이라는 리스트를 미리 전역으로 만들어둔다.

그 후 FadeOutWall() 함수에


Vector3 ScreenPos = Camera.main.WorldToScreenPoint(mHero.transform.position)

Ray ray = Camera.main.ScreenPointToRay(ScreenPos);

RaycastHit[] hits = Physics.RaycastAll(ray);

foreach(RaycastHit hit in hits)

{

if(hit.collider.gameObject != mHero.gameObject && hit.collider.tag != "Terrain")

{

bool bFind = false;

foreach(GameObject saved in mTransparentWalls)

if(saved == hit.collider.gameObject)

bFind=true;

}

if(bFind==false)

{

GameObject hitWall = hit.collider.gameObject;

hitWall.GetComponent<MeshRenderer>().DoFade(0,1.0f);

mTransparentWalls.Add(hitWall);

newAddedWall.Add(hitWall);

}

foreach(GameObject oldWall in mTransparentWalls)

{

bool bFInd = false;

foreach(GameObject newWall in nowAddedWall)

{

if(newQall==oldWall)

{

bFInd = true;

break;

}

}

}

if(bFind==false)

{

oldWall.GetComponent<MeshRenderer>().material.DOFade(1f,1f);

mTransparentWalls.Remove(oldWall);

}

}

해준다.


===


리스트를 지울 때 Clear()를 써주면 new나 delete가 안들어가기 때문에 속도 저하가 웬만하면 없음.

new는 빈번하게 쓰면 안됨.

수동으로 지울 시 가비지 컬렉터가 매 번 새로 불리는데, 그냥 clear로 포인터 저장된 것만 비워두면 안 쓰는 메모리가 쌓이다가 가비지 컬렉터가 한 번 불릴 때만 프레임이 드랍되기에 이게 훨씬 이득.

Ray같은 것도 그 때 그 때 new 하지 말고 만들어둔 후 계속 재탕하면 됨.


'BCA > 6. Unity RPG 따라하기' 카테고리의 다른 글

46. 데이터 세이브 로드, HP바, EXP바  (0) 2018.06.21
45. 몬스터 공격, 해의 순환  (0) 2018.06.20
44. 몹 움직이기  (0) 2018.06.19
43. 몹 패기  (0) 2018.06.18
41. 시작화면, 설정  (0) 2018.06.14
Comments