VioletaBabel
42. 시야 가리는 벽 반투명 본문
카메라에 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 |