[4Idle - Gazzlers] 플레이어 오른손 기능 구현(총 쏘기+ 데미지 텍스트 효과)
오른손 기능
RT - 총 발사
=> 오른손의 Index Trigger를 누르는 동안 플레이어가 들고있는 총에서 레이저 샷을 정면으로 발사시킨다.
(이 때, 완전한 정면이 아니라 포물선을 그리며 약간 아래방향으로 날아가게 된다.)
-총구에서 레이저 빔이 날아가는 것으로, 레이저 빔의 끝부분에서 충돌처리가 일어난다.
레이저 모델 생성
-임의로 총 모델 대신 큐브를 사용하여 넣어주고, 오른손의 자식으로 ShootTrans를 빈 오브젝트로 생성해주었다.
-생성한 ShootTrans를 RightHandController의 Shoot Trans로 할당하였다. 레이저가 발사되는 위치이다.
-RIghtHandController는 오른손 오브젝트에 부착한다.
-gunLaserGo는 생성될 레이저빔 프리팹을 넣어준다.
-생성된 레이저 빔은 오른손의 index Trigger를 누를때에만 SetActive(true)가 된다.
-총 모델을 변경한 후 결과를 확인해주었다.
총 발사 충돌처리
-이제 총이 쏴질 때 충돌처리를 해주어야한다. 현재는 레이저 모델만 보여질뿐, 실제로 충돌처리는 하고있지 않다.
-충돌처리를 위해 Ray를 사용할 것이다.
-Layer에 Monster를 추가하고, 테스트용 캡슐 오브젝트의 layer를 몬스터로 설정해주었다.
-타격된 물체는 흰 막같은게 생기는 것과 동시에 데미지 텍스트가 띄워지면서 플레이어에게 타격되고 있다는 정보를 준다.
=> 먼저 타격 이펙트부터 생성한다.
타격 이펙트 생성
-타격 이펙트는 Start할때 생성해두고 필요할때 껐다 켰다 하도록한다.
=> 만약 여러개의 타격 이펙트가 필요해지면 오브젝트 풀링을 사용해 코드를 수정할 예정이다.
-충돌 지점까지만 레이저 빔이 생성되어야 하므로 ParticleSystemRenderer.lenthScale을 조절해주었다.
-hit.distance값을 lengthScale에 넣어주면 충돌되는 지점까지의 거리만큼만 생성된다.
-플레이어가 타고있는 탈것에는 타격되더라도 이펙트가 표시되지 않도록 하기 위해 코드 수정
타격 시 데미지 텍스트 생성
- 몬스터가 타격되면 데미지 텍스트가 띄워져야 한다. 또한 몬스터는 HP Bar가 존재한다.
- 데미지 텍스트는 UI이다. 따라서 캔버스 안에 존재한다.
- UI는 캔버스 안에있고, 데미지 텍스트가 보여져야 할 위치는 World좌표이므로 이 둘의 서로 다른 좌표 체계에 대해 고려해야 한다.
=> 예를 들어 몬스터가 움직이고 있더라도, 몬스터의 위치에 따라서 UI의 위치도 변경되어야한다.
-캔버스의 이름을 WorldCanvas로 변경한다. World캔버스는 Render Mode 가 WorldSpace이다.
-WorldCanvas의 자식으로 HPBar 오브젝트와 DamageText오브젝트를 생성해준다.
-생성한 두 오브젝트는 프리팹으로 만들고, 씬에서는 없애도로한다.
-새로운 캔버스를 추가해 EnemyCanvas라 명명해두고, RenderMode는 Overlay가 되도록한다.
- Enemy 오브젝트에 EnemyController.cs를 새로 생성해 넣어준다.
- EnemyController 스크립트는 Player로부터 GetHit 상태가 되는지 확인하는 역할을 한다.
- 방금 프리팹으로 만들어둔 HPBar가 생성되게 될 위치로 Enemy의 자식으로 빈 오브젝트를 생성해 HPBarPos라 했다.
=> 이 HPBarPos는 월드상의 좌표를 UI상의 캔버스 좌표로 변환해야한다.
좌표 변환이 잘 되는지 확인하기 위해 HPBar가 위치를 잘 받는지 먼저 만들어보았다.
https://docs.unity3d.com/ScriptReference/Camera.WorldToScreenPoint.html
-RectTransformUtility를 사용해 월드 포인트를 스크린 포인트로 변경할 수 있다.
-Documentation에 따르면 카메라는 null이어도 되므로 할당하지않았고, 위에서 EnemyCanvas를 Overlay로 설정해준것은 이 API때문이다.
-EnemyController에서 미리 hpBar프리팹을 생성해두되, UpdateHPBarPos 메서드를 통해 위치가 변경되도록 코드를 작성하였다.
-RectTransformUtility.WorldToScreenPoint와 RectTransformUtility.ScreenPointToLocalPointInRectangle을 사용해 좌표 위치를 받는다.
-EnemyController에 다음과 같이 할당한다.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
=> ㅋㅋ이건 overlay로 했을 때 라서, 3d 프로젝트할때 overlay모드 카메라의 경우 이렇게 하면 되지만 오큘러스의 경우 world Space를 사용해야하므로 이것이 필요하지 않다. 그러나 overlay일때는 사용해야하므로 참고해두자.
https://www.youtube.com/watch?v=Bgt90Gu305c&list=PLTFRwWXfOIYA5sIfnHL78hlTU-jwcTLA6&t=217s
https://haseungbong.blogspot.com/2018/10/worldtoscreenpos-in-ugui.html
https://tsubakit1.hateblo.jp/entry/2018/10/16/231300
-hpBar 프리팹의 사이즈를 적절히 바꿔주고, 기존에 작성한 코드를 간단히 고쳤다. world Space므로 따로 월드좌표로 변환하지 않아도 된다.
데미지 텍스트 구현
-이제 hpBar에서 위치를 받은것을 참고해 타격 위치에 DamageText 프리팹이 타격될때마다 나타나게 구현하면된다.
-인수가 1개(매개변수로 Vector3를 받는)대리자를 호출하여 EnemyController에서 적이 타격된것을 알게 하였다.
-DamageText 프리팹의 크기도 적절히 조절해주었다.
-EnemyController에서 hit된 상태인 것을 전달받으면 데미지 텍스트를 띄우도록 코루틴함수를 생성하였다.
-데미지 텍스트 오브젝트는 start할때 생성해두어 false해두었다가, Hit될때마다 코루틴을 호출해 0.3초동안 활성화되도록하였다.
-이제 데이터를 생성해서 UI와 연결해줄 필요가 있다. 다음 포스팅에서 정리할 것이다.