▷LeftHand - 방패(Shield)잡기 구현
▼구현할 부분(왼손 방패)
▼구현할 것
- 왼 손을 쥐고 있으면 (LeftIndexTrigger를 누르는 동안) 방패 생성
- LeftIndexTrigger를 누르는 동안 방패 게이지(UI)가 줄어듦
(MaxGauge : 100%)
- 왼 손을 펴면 방패 사라짐 & 방패 게이지 충전
▼구현 과정
(방식)
- 컨트롤러의 트리거 (LeftIndexTrigger)를 누르면 손 프리팹 변경
(목표)
==> 기본 왼손을 쥐면(LeftIndexTrigger를 누르면) 방패를 쥔 왼손으로 프리팹 바꾸기
==> 다시 손을 피면(LeftIndexTrigger를 떼면) 기본 왼손 프리팹으로 돌아오기
▶기본 왼손
- MainCamera 삭제 후 OVRCameraRig 붙이기
- OVRCameraRig ->TrackingSpace -> LeftHandAnchor에 빈오브젝트 'HandLeftParent' 추가
- 'HandLeftParent'에 다운 받은 손 에셋 중 맘에 드는 손을 골라 자식으로 붙이고 'HandLeft'(기본 왼손)로 이름 바꾸기



▶방패든 왼손
- 기본 왼손을 복사 붙여넣기 하고 이름을 'HandLeft(Shield)'로 변경
- 다운받은 이펙트 에셋 중에 맘에드는 것을 골라 'HandLeft(Shield)의 자식으로 붙여주기(이름도 'Shield'로 변경)

- 자꾸 손이 펴지는 것을 방지
--> 기존에 부착되어 있던 Animator 체크 해제

- 원작과 비슷하게 방패의 위치 및 회전율 조정하기


▶방패 게이지 UI
- Canvas -> Text_TMPPro 생성하기
- 손(GameObject)옆에 붙어있을 것이므로 ==> Canvas -> Render Mode를 'World Space'로 변경!!

- Text_TMPPro 부분도 폰트, 글자 크기 등 알맞게 조정

▼ 1차 완성본
: 방패 및 방패게이지UI 보이기
: 손을 쥐면 초당 1%씩 게이지 감소, 다시 펴면 초당 1%씩 게이지 회복

▶ ▶ 수정 및 보완
(수정)
- 손을 쥘때만 방패게이지UI 보이기 --> 방패게이지 UI 상시 보이기
- 방패게이지 닳고 회복하는 속도 조정하기
(보완)
방패 역할 구현
- 총알이 방패에 닿으면 총알 없애기
- 닿은 총알 개수 당 방패게이지UI의 게이지 수치 -10%씩 닳기
▶ 방패게이지UI 상시 보이기
- 'LeftHandShield' 스크립트의 트리거를 누르고 뗄 때 넣었던 Action 제거하기
(UI 활성, 비활성화 제어했던 것을 제거)
▶ 게이지 수치 속도 조정
- 기존에 'LeftHandShield' 부분의 게이지 시간을 조절하는 Time.deltaTime 부분에 speed 변수 곱해주기
▶ 총알 없애고 방패게이지 감소시키기
- 팀원이 만든 Enemy 프리팹 가져와서 배치

- 기존에 만든 Shield 프리팹에 총알과 Trigger체크를 할 'Shield' 스크립트 및 Collider 부착하기

- 총알에 닿으면 게이지 10%씩 닳게 하도록 기존에 작성했던 'LeftHandShield' 스크립트 수정하기
private float timeSpeed = 4f;
private float recoverSpeed = 7f;
void Start()
{
this.shieldValue = this.shieldMaxValue;
this.onChangeValue(this.shieldValue);
//방패와 총알이 닿으면 방패게이지 -10 감소
this.shield.onTriggerBullet = () =>
{
this.shieldValue -= 10;
Debug.LogFormat("<color=red>{0}</color>",shieldValue);
};
}
▶스크립트
- LeftIndexTrigger를 입력을 받아 왼손 프리팹을 교체해줄 스크립트
- 방패게이지(UI)를 관리할 스크립트 : 방패 게이지 100%에서 초마다 따라 게이지가 1%씩 줄어듦
.
.
.
LeftHandShield
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace LJE
{
public class LeftHandShield : MonoBehaviour
{
[SerializeField] private GameObject leftHand;
[SerializeField] private GameObject leftHandShield;
[SerializeField] private Shield shield;
public System.Action<int> onChangeValue;
private int shieldMaxValue = 100;
private int shieldValue = 0;
private float elapsedTime;
private float timeSpeed = 4f;
private float recoverSpeed = 7f;
void Start()
{
this.shieldValue = this.shieldMaxValue;
this.onChangeValue(this.shieldValue);
//방패와 총알이 닿으면 방패게이지 -10 감소
this.shield.onTriggerBullet = () =>
{
this.shieldValue -= 10;
Debug.LogFormat("<color=red>{0}</color>",shieldValue);
};
}
void Update()
{
//왼손을 쥐면 방패쥔 손으로 변경
if (OVRInput.Get(OVRInput.Button.PrimaryIndexTrigger))
{
this.leftHand.SetActive(false);
this.leftHandShield.SetActive(true);
//방패가 나타나는 동안 방패게이지 감소
this.elapsedTime += (Time.deltaTime * this.timeSpeed);
if (this.elapsedTime >= 1)
{
this.shieldValue--;
this.onChangeValue(this.shieldValue);
this.elapsedTime = 0f;
}
}
//손을 다시 펴면 원래 왼손으로 변경
else if (OVRInput.GetUp(OVRInput.Button.PrimaryIndexTrigger))
{
this.leftHand.SetActive(true);
this.leftHandShield.SetActive(false);
this.elapsedTime = 0;
//this.shieldValue = shieldMaxValue;
this.onChangeValue(this.shieldValue);
}
else
{
//손을 피면 감소했던 게이지 다시 회복
this.elapsedTime += (Time.deltaTime * this.recoverSpeed);
if (this.elapsedTime >= 1)
{
this.shieldValue++;
this.onChangeValue(this.shieldValue);
this.elapsedTime = 0f;
//방패게이지가 최대게이지를 넘어가지 않도록
if (this.shieldValue > this.shieldMaxValue)
{
this.shieldValue = this.shieldMaxValue;
this.onChangeValue(this.shieldValue);
}
}
}
}
}
}
Shield
using LJE;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shield : MonoBehaviour
{
[SerializeField] private LeftHandShield leftHandShield;
public System.Action onTriggerBullet;
//총알과 트리거 체크
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Bullet"))
{
//총알 제거
Destroy(other.gameObject);
//총알이 제거되었으니 게이지 닳게하도록 LeftHandShield에게 알리기
this.onTriggerBullet();
}
}
}
ShieldGaugeUI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using System.Runtime.CompilerServices;
namespace LJE
{
public class ShieldGaugeUI : MonoBehaviour
{
[SerializeField] private TMP_Text shieldGauge;
[SerializeField] private LeftHandShield leftShield;
void Start()
{
//value값이 변할때마다 출력
this.leftShield.onChangeValue = (value) =>
{
this.shieldGauge.text = string.Format("{0}%", value);
};
}
// Update is called once per frame
void Update()
{
//게이지txt 위치 조정
this.transform.position = this.leftShield.transform.position + Vector3.right * 0.
}
}
}
- 알맞은 곳에 스크립트 부착


▼완성본

'VR 팀프로젝트 > [GroundZero] 제작 일지' 카테고리의 다른 글
GroundZero 제작일지 - GameOverScene 구현 (1) | 2023.12.21 |
---|---|
GroundZero 제작일지 - 날아다니는 적(Enemy 3) 이동 구현 (0) | 2023.12.12 |
GroundZero 제작일지 - 오른손 총 구현(바주카포) (0) | 2023.11.30 |
GroundZero 제작일지 - 아이템 비행체 구현 (0) | 2023.11.16 |
GroundZero 제작일지 - 레퍼런스 게임 Gazzlers 분석 (1) | 2023.11.02 |