Chapter 4. 체력 : Status UI
카테고리: Unity Lesson 3
태그: Unity Game Engine
인프런에 있는 케이디님의 [유니티 3D] 실전! 생존게임 만들기 - Advanced 강의를 듣고 정리한 필기입니다. 😀
🌜 강의 들으러 가기 Click
Chapter 4. 허기와 갈증, 스태미나와 체력
🚖 상태 UI 만들기
이미지 UI 생성
- 하나의 부모 이미지에 6 개의 자식 이미지를 만든다.
Status_Base
- HP 나타내는 이미지
- DP 나타내는 이미지
- SP 나타내는 이미지
- 배고픔 나타내는 이미지
- 목마름 나타내는 이미지
- 만족감 나타내는 이미지
Status_Base
부모 이미지
Status_Base
위에 배치한 6 개의 자식 이미지- 가운데 초록 바는 SP 나타내는 이미지다.
이미지 컴포넌트 설정
- Source Image
- 텍스처 타입을 Sprite(2D and UI)로 적용시켜주어야 이미지 UI 에 할당할 수 있다.
- Max Size를 이미지 크기에 맞게 설정
- Width, Height는 실제 Source Image 이미지 크기와 동일하게 해준다.
- 알맞는
Status_Base
자리에 배치될 수 있도록 위치시켜 준다. - Image Type
Filled
👉 상태 값에 따라 이미지 게이지가 채워지도록 한다. (어떻게 동작하는지 Fill Amount를 이리저리 드래그 해서 확인해보자)dp
,sp
,hp
는 상태 값에 따라 아래서부터 시작하여 수직 방향으로 이미지가 채워져 그려질 수 있도록Vertical
,Bottom
으로 설정 해 준다.hungry
,thirsy
는 상태 값에 따라 90 도 방향(오른쪽)에서 시작하여 시계 방향으로 360 도로 이미지가 채워져 그려질 수 있도록Radial 360
,Right
,Clockwise
체크 로 설정해주자.satisfy
는 상태 값에 따라 270 도 방향(왼쪽)에서 시작하여 시계 방향으로 360 도로 이미지가 채워져 그려질 수 있도록Radial 360
,Left
,Clockwise
체크 로 설정해주자.
🚖 상태 업데이트
모든 상태의 공통 부분
📜StatusController.cs
// 필요한 이미지
[SerializeField]
private Image[] images_Gauge;
// 각 상태를 대표하는 인덱스
private const int HP = 0, DP = 1, SP = 2, HUNGRY = 3, THIRSTY = 4, SATISFY = 5;
void Start()
{
currentHp = hp;
currentDp = dp;
currentSp = sp;
currentHungry = hungry;
currentThirsty = thirsty;
currentSatisfy = satisfy;
}
void Update()
{
Hungry();
Thirsty();
SPRechargeTime();
SPRecover();
GaugeUpdate();
}
private void GaugeUpdate()
{
images_Gauge[HP].fillAmount = (float)currentHp / hp;
images_Gauge[SP].fillAmount = (float)currentSp / sp;
images_Gauge[DP].fillAmount = (float)currentHp / dp;
images_Gauge[HUNGRY].fillAmount = (float)currentHungry / hungry;
images_Gauge[THIRSTY].fillAmount = (float)currentThirsty / thirsty;
images_Gauge[SATISFY].fillAmount = (float)currentSatisfy / satisfy;
}
images_Gauge
- 각각의 상태를 대표하는 이미지 6 개가 배열로 관리 될 것
- enum 처럼 배열의 인덱스가 각각 어떤 상태인지 알 수 있도록 아래와 같이 선언해주었다.
private const int HP = 0, DP = 1, SP = 2, HUNGRY = 3, THIRSTY = 4, SATISFY = 5;
- Start()
- 게임이 시작 되면 6 개의 현재 상태값들 초기화
- 최대 값으로 초기화 한다. 현재 체력을 최대 체력으로 업뎃 등등
- 게임이 시작 되면 6 개의 현재 상태값들 초기화
- Update()
-
매 프레임마다 자동으로 계속해서 업데이트 되야할 것은 1️⃣ 배고픔, 2️⃣ 목마름, 3️⃣ SP 회복해도 될지 시간 업뎃, 4️⃣ SP 회복(스태미나) 이며 마지막으로 5️⃣ 이미지 게이지 업데이트
- 배고픔, 목마름은 일정 시간 지날 때마다 감소되게 할 것이라 그렇다.
-
- GaugeUpdate()
- 이미지 게이지 업데이트
- (현재 상태 값 / 최대 상태 값) 👉 이 값만큼 해당 이미지를 채운다.
- Image 의
fillAmount
이미지 채울 값. 이미지 컴포넌트에 Filled 슬라이더 값
- 이미지 게이지 업데이트
1️⃣ 배고픔
📜StatusController.cs
// 배고픔
[SerializeField]
private int hungry; // 최대 배고픔. 유니티 에디터 슬롯에서 지정할 것.
private int currentHungry;
// 배고픔이 줄어드는 속도
[SerializeField]
private int hungryDecreaseTime;
private int currentHungryDecreaseTime;
private void Hungry()
{
if (currentHungry > 0)
{
if (currentHungryDecreaseTime <= hungryDecreaseTime)
currentHungryDecreaseTime++;
else
{
currentHungry--;
currentHungryDecreaseTime = 0;
}
}
else
Debug.Log("배고픔 수치가 0 이 되었습니다.");
}
public void IncreaseHungry(int _count)
{
if (currentHungry + _count < hungry)
currentHungry += _count;
else
currentHungry = hungry;
}
public void DecreaseHungry(int _count)
{
if (currentHungry - _count < 0)
currentHungry = 0;
else
currentHungry -= _count;
}
- Hungry()
- 업데이트 문 안에서 매 프레임마다 실행 된다.
- 매프레임마다 일정 시간 씩 지나면 자연스럽게 배고픔 수치가 떨어지도록 할 것이다.
- 현재 배고픔 수치가 0 보다 크다면 👉
currentHungryDecreaseTime
가hungryDecreaseTime
가 도달 했다면 현재 배고픔currentHungry
수치를 감소시키고currentHungryDecreaseTime
을 다시 0 으로 만든다.currentHungryDecreaseTime
가hungryDecreaseTime
가 도달 하지 못했다면 계속 1 씩 증가하도록 한다.
- 현재 배고픔 수치가 0 이하라면
- 플레이어가 죽어서 게임이 종료되는 등등의 처리를 해주면 좋을 것 같다.
- 업데이트 문 안에서 매 프레임마다 실행 된다.
- IncreaseHungry(int _count)
- 다른 곳에서 배고픔 증가 처리를 하고자 할 때 사용할 public 함수
- 현재 배고픔에서 인수로 들어온
_count
만큼 증가시킨다.- 단, 현재 배고픔에서
_count
를 더한다고 가정했을 때 최대 배고픔hungry
를 넘는다면 현재 배고픔을 최대 배고픔인hungry
로 설정해준다. - 그런게 아니라면 그냥 현재 배고픔에서
_count
를 더해준다.
- 단, 현재 배고픔에서
- 현재 배고픔에서 인수로 들어온
- 다른 곳에서 배고픔 증가 처리를 하고자 할 때 사용할 public 함수
- DecreaseHungry(int _count)
- 다른 곳에서 배고픔 증가 처리를 하고자 할 때 사용할 public 함수
- 현재 배고픔에서 인수로 들어온
_count
만큼 차감시킨다.- 단, 현재 배고픔에서
_count
를 뺀다고 가정했을 때0
보다 작아진다면 현재 배고픔을 음수가 되지 않도록0
으로 설정해준다. - 그런게 아니라면 그냥 현재 배고픔에서
_count
를 빼준다.
- 단, 현재 배고픔에서
- 현재 배고픔에서 인수로 들어온
- 다른 곳에서 배고픔 증가 처리를 하고자 할 때 사용할 public 함수
2️⃣ 목마름
📜StatusController.cs
// 목마름
[SerializeField]
private int thirsty; // 최대 목마름. 유니티 에디터 슬롯에서 지정할 것.
private int currentThirsty;
// 목마름이 줄어드는 속도
[SerializeField]
private int thirstyDecreaseTime;
private int currentThirstyDecreaseTime;
private void Thirsty()
{
if (currentThirsty > 0)
{
if (currentThirstyDecreaseTime <= thirstyDecreaseTime)
currentThirstyDecreaseTime++;
else
{
currentThirsty--;
currentThirstyDecreaseTime = 0;
}
}
else
Debug.Log("목마름 수치가 0 이 되었습니다.");
}
public void IncreaseThirsty(int _count)
{
if (currentThirsty + _count < thirsty)
currentThirsty += _count;
else
currentThirsty = thirsty;
}
public void DecreaseThirsty(int _count)
{
if (currentThirsty - _count < 0)
currentThirsty = 0;
else
currentThirsty -= _count;
}
- Thirsty()
- 업데이트 문 안에서 매 프레임마다 실행 된다.
- 매프레임마다 일정 시간 씩 지나면 자연스럽게 목마름 수치가 떨어지도록 할 것이다.
- 업데이트 문 안에서 매 프레임마다 실행 된다.
- 다른 것들도 다 배고픔이랑 똑같다.
3️⃣ 만족감
📜StatusController.cs
// 만족감
[SerializeField]
private int satisfy; // 최대 만족감. 유니티 에디터 슬롯에서 지정할 것.
private int currentSatisfy;
나머지 구현 아직 X
4️⃣ HP
📜StatusController.cs
// 체력
[SerializeField]
private int hp; // 최대 체력. 유니티 에디터 슬롯에서 지정할 것.
private int currentHp;
public void IncreaseHP(int _count)
{
if (currentHp + _count < hp)
currentHp += _count;
else
currentHp = hp;
}
public void DecreaseHP(int _count)
{
if(currentDp > 0)
{
DecreaseDP(_count);
return;
}
currentHp -= _count;
if (currentHp <= 0)
Debug.Log("캐릭터의 체력이 0이 되었습니다!!");
}
- IncreaseHP(int _count)
- 배고픔 목마름과 비슷
- DecreaseHP(int _count)
- 방어력이 있을 땐 체력을 깎지 않고 대신 방어력을 깎고 종료시킨다.
- DecreaseDP(_count) 호출
- 방어력이 없을 때만 체력을 깎는다.
- 방어력이 있을 땐 체력을 깎지 않고 대신 방어력을 깎고 종료시킨다.
5️⃣ DP
방어력
📜StatusController.cs
// 방어력
[SerializeField]
private int dp; // 최대 방어력. 유니티 에디터 슬롯에서 지정할 것.
private int currentDp;
public void IncreaseDP(int _count)
{
if (currentDp + _count < dp)
currentDp += _count;
else
currentDp = dp;
}
public void DecreaseDP(int _count)
{
currentDp -= _count;
if (currentDp <= 0)
Debug.Log("캐릭터의 방어력이 0이 되었습니다!!");
}
6️⃣ SP
스태미나
📜StatusController.cs
// 스태미나
[SerializeField]
private int sp; // 최대 스태미나. 유니티 에디터 슬롯에서 지정할 것.
private int currentSp;
// 스태미나 증가량
[SerializeField]
private int spIncreaseSpeed;
// 스태미나 재회복 딜레이 시간
[SerializeField]
private int spRechargeTime;
private int currentSpRechargeTime;
// 스태미나 감소 여부
private bool spUsed;
public void DecreaseStamina(int _count)
{
spUsed = true;
currentSpRechargeTime = 0;
if (currentSp - _count > 0)
{
currentSp -= _count;
}
else
currentSp = 0;
}
private void SPRechargeTime()
{
if (spUsed)
{
if (currentSpRechargeTime < spRechargeTime)
currentSpRechargeTime++;
else
spUsed = false;
}
}
private void SPRecover()
{
if (!spUsed && currentSp < sp)
{
currentSp += spIncreaseSpeed;
}
}
public int GetCurrentSP()
{
return currentSp;
}
- 스태미나는 점프, 달리기에 의해 감소된다.
- 스태미나가 0 이 되면 점프, 달리기를 할 수 없다.
- 감소된 스태미나는 일정 시간이 지나고 난 후에 최대 스태미나로 회복을 시작한다.
- DecreaseStamina(int _count)
- 스태미나가 감소 되었었다는 표시를 해주기 위해
spUsed
을 True로 업데이트 해준다. - 인수만큼 스태미나를 차감해준다. 음수가 되자 않도록 0 보다 떨어지면 0 으로 설정한다.
- 스태미나가 감소 되었었다는 표시를 해주기 위해
- SPRechargeTime()
- 업데이트 문 안에서 매프레임마다 실행된다.
- 스태미나가 감소된 이후 ~ 스태미나가 재충전 될 수 있는 시작 점 까지의 시간을 재어 스태미나가 다시 재충전 될 수 있는지를 확인한다.
- 스태미나가 감소된적이 있는 경우에만 if (spUsed)
currentSpRechargeTime
가spRechargeTime
에 도달할 때까지 1 씩 증가시킨다. 도달했다면spUsed
를 False로 업데이트 한다.
- SPRecover()
- 업데이트 문 안에서 매프레임마다 실행된다.
- 재충전 할 수 있을 타이밍이고 (
!spUsed
) 현재 스태미나가 최대 스태미나를 넘지 않는다면spIncreaseSpeed
만큼 스테미나를 매 프레임마다 회복 시켜 나간다.
- GetCurrentSP()
- 현재 스태미나 리턴
📜PlayerController.cs
private StatusController theStatusController;
void Start()
{
// ...
theStatusController = FindObjectOfType<StatusController>();
// ...
}
// 점프 시도
private void TryJump()
{
if (Input.GetKeyDown(KeyCode.Space) && isGround && theStatusController.GetCurrentSP() > 0)
{
Jump();
}
}
// 점프
private void Jump()
{
if (isCrouch)
Crouch();
theStatusController.DecreaseStamina(100);
myRigid.velocity = transform.up * jumpForce;
}
// 달리기 시도
private void TryRun()
{
if (Input.GetKey(KeyCode.LeftShift) && theStatusController.GetCurrentSP() > 0)
{
Running();
}
if (Input.GetKeyUp(KeyCode.LeftShift) || theStatusController.GetCurrentSP() <= 0)
{
RunningCancel();
}
}
// 달리기
private void Running()
{
if (isCrouch)
Crouch();
theGunController.CancelFineSight();
isRun = true;
theCrosshair.RunningAnimation(isRun);
theStatusController.DecreaseStamina(10);
applySpeed = runSpeed;
}
- Start() 에서
theStatusControlelr
에 📜StatusController.cs 가져 오기 - 점프를 시도하려 할 때
- theStatusController.GetCurrentSP() > 0 현재 스태미나가 0 보다 클 때만 가능하도록 한다.
- 점프 할 때
- theStatusController.DecreaseStamina(100) 스태미나 값 100 씩 감소시킴
- 달리기 시도하려 할 때
- theStatusController.GetCurrentSP() > 0 현재 스태미나가 0 보다 클 때만 가능하도록 한다.
- theStatusController.GetCurrentSP() <= 0 현재 스태미나가 0 이하일 때도 RunningCancel() 을 실행하도록 하자.
- 더 이상 달리지 못하도록
- 점프 할 때
- theStatusController.DecreaseStamina(100) 스태미나 값 10 씩 감소시킴
🚔 전체 코드
📜StatusController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class StatusController : MonoBehaviour
{
// 체력
[SerializeField]
private int hp; // 최대 체력. 유니티 에디터 슬롯에서 지정할 것.
private int currentHp;
// 스태미나
[SerializeField]
private int sp; // 최대 스태미나. 유니티 에디터 슬롯에서 지정할 것.
private int currentSp;
// 스태미나 증가량
[SerializeField]
private int spIncreaseSpeed;
// 스태미나 재회복 딜레이 시간
[SerializeField]
private int spRechargeTime;
private int currentSpRechargeTime;
// 스태미나 감소 여부
private bool spUsed;
// 방어력
[SerializeField]
private int dp; // 최대 방어력. 유니티 에디터 슬롯에서 지정할 것.
private int currentDp;
// 배고픔
[SerializeField]
private int hungry; // 최대 배고픔. 유니티 에디터 슬롯에서 지정할 것.
private int currentHungry;
// 배고픔이 줄어드는 속도
[SerializeField]
private int hungryDecreaseTime;
private int currentHungryDecreaseTime;
// 목마름
[SerializeField]
private int thirsty; // 최대 목마름. 유니티 에디터 슬롯에서 지정할 것.
private int currentThirsty;
// 목마름이 줄어드는 속도
[SerializeField]
private int thirstyDecreaseTime;
private int currentThirstyDecreaseTime;
// 만족감
[SerializeField]
private int satisfy; // 최대 만족감. 유니티 에디터 슬롯에서 지정할 것.
private int currentSatisfy;
// 필요한 이미지
[SerializeField]
private Image[] images_Gauge;
// 각 상태를 대표하는 인덱스
private const int HP = 0, DP = 1, SP = 2, HUNGRY = 3, THIRSTY = 4, SATISFY = 5;
void Start()
{
currentHp = hp;
currentDp = dp;
currentSp = sp;
currentHungry = hungry;
currentThirsty = thirsty;
currentSatisfy = satisfy;
}
void Update()
{
Hungry();
Thirsty();
SPRechargeTime();
SPRecover();
GaugeUpdate();
}
private void GaugeUpdate()
{
images_Gauge[HP].fillAmount = (float)currentHp / hp;
images_Gauge[SP].fillAmount = (float)currentSp / sp;
images_Gauge[DP].fillAmount = (float)currentHp / dp;
images_Gauge[HUNGRY].fillAmount = (float)currentHungry / hungry;
images_Gauge[THIRSTY].fillAmount = (float)currentThirsty / thirsty;
images_Gauge[SATISFY].fillAmount = (float)currentSatisfy / satisfy;
}
private void Hungry()
{
if (currentHungry > 0)
{
if (currentHungryDecreaseTime <= hungryDecreaseTime)
currentHungryDecreaseTime++;
else
{
currentHungry--;
currentHungryDecreaseTime = 0;
}
}
else
Debug.Log("배고픔 수치가 0 이 되었습니다.");
}
private void Thirsty()
{
if (currentThirsty > 0)
{
if (currentThirstyDecreaseTime <= thirstyDecreaseTime)
currentThirstyDecreaseTime++;
else
{
currentThirsty--;
currentThirstyDecreaseTime = 0;
}
}
else
Debug.Log("목마름 수치가 0 이 되었습니다.");
}
public void IncreaseHP(int _count)
{
if (currentHp + _count < hp)
currentHp += _count;
else
currentHp = hp;
}
public void DecreaseHP(int _count)
{
if(currentDp > 0)
{
DecreaseDP(_count);
return;
}
currentHp -= _count;
if (currentHp <= 0)
Debug.Log("캐릭터의 체력이 0이 되었습니다!!");
}
public void IncreaseDP(int _count)
{
if (currentDp + _count < dp)
currentDp += _count;
else
currentDp = dp;
}
public void DecreaseDP(int _count)
{
currentDp -= _count;
if (currentDp <= 0)
Debug.Log("캐릭터의 방어력이 0이 되었습니다!!");
}
public void IncreaseHungry(int _count)
{
if (currentHungry + _count < hungry)
currentHungry += _count;
else
currentHungry = hungry;
}
public void DecreaseHungry(int _count)
{
if (currentHungry - _count < 0)
currentHungry = 0;
else
currentHungry -= _count;
}
public void IncreaseThirsty(int _count)
{
if (currentThirsty + _count < thirsty)
currentThirsty += _count;
else
currentThirsty = thirsty;
}
public void DecreaseThirsty(int _count)
{
if (currentThirsty - _count < 0)
currentThirsty = 0;
else
currentThirsty -= _count;
}
public void DecreaseStamina(int _count)
{
spUsed = true;
currentSpRechargeTime = 0;
if (currentSp - _count > 0)
{
currentSp -= _count;
}
else
currentSp = 0;
}
private void SPRechargeTime()
{
if (spUsed)
{
if (currentSpRechargeTime < spRechargeTime)
currentSpRechargeTime++;
else
spUsed = false;
}
}
private void SPRecover()
{
if (!spUsed && currentSp < sp)
{
currentSp += spIncreaseSpeed;
}
}
public int GetCurrentSP()
{
return currentSp;
}
}
📜PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
// 스피드 조정 변수
[SerializeField]
private float walkSpeed;
[SerializeField]
private float runSpeed;
[SerializeField]
private float crouchSpeed;
private float applySpeed;
[SerializeField]
private float jumpForce;
// 상태 변수
private bool isWalk = false;
private bool isRun = false;
private bool isGround = true;
private bool isCrouch = false;
// 움직임 체크 변수
private Vector3 lastPos; // 전 프레임의 위치. 현재 프레임의 위치와 비교했을 때 달라지면 움직임이 있었던 것이다.
// 앉았을 때 얼마나 앉을지 결정하는 변수
[SerializeField]
private float crouchPosY;
private float originPosY;
private float applyCrouchPosY;
// 민감도
[SerializeField]
private float lookSensitivity;
// 카메라 한계
[SerializeField]
private float cameraRotationLimit;
private float currentCameraRotationX;
// 필요한 컴포넌트
[SerializeField]
private Camera theCamera;
private Rigidbody myRigid;
private CapsuleCollider capsuleCollider;
private GunController theGunController;
private Crosshair theCrosshair;
private StatusController theStatusController;
void Start()
{
// 컴포넌트 할당
capsuleCollider = GetComponent<CapsuleCollider>();
myRigid = GetComponent<Rigidbody>();
theGunController = FindObjectOfType<GunController>();
theCrosshair = FindObjectOfType<Crosshair>();
theStatusController = FindObjectOfType<StatusController>();
applySpeed = walkSpeed;
originPosY = theCamera.transform.localPosition.y;
applyCrouchPosY = originPosY;
}
void Update()
{
IsGround();
TryJump();
TryRun();
TryCrouch();
Move();
MoveCheck();
CameraRotation();
CharacterRotation();
}
// 지면 체크
private void IsGround()
{
isGround = Physics.Raycast(transform.position, Vector3.down, capsuleCollider.bounds.extents.y + 0.1f);
theCrosshair.JumpingAnimation(!isGround);
}
// 점프 시도
private void TryJump()
{
if (Input.GetKeyDown(KeyCode.Space) && isGround && theStatusController.GetCurrentSP() > 0)
{
Jump();
}
}
// 점프
private void Jump()
{
if (isCrouch)
Crouch();
theStatusController.DecreaseStamina(100);
myRigid.velocity = transform.up * jumpForce;
}
// 달리기 시도
private void TryRun()
{
if (Input.GetKey(KeyCode.LeftShift) && theStatusController.GetCurrentSP() > 0)
{
Running();
}
if (Input.GetKeyUp(KeyCode.LeftShift) || theStatusController.GetCurrentSP() <= 0)
{
RunningCancel();
}
}
// 달리기
private void Running()
{
if (isCrouch)
Crouch();
theGunController.CancelFineSight();
isRun = true;
theCrosshair.RunningAnimation(isRun);
theStatusController.DecreaseStamina(10);
applySpeed = runSpeed;
}
// 달리기 취소
private void RunningCancel()
{
isRun = false;
theCrosshair.RunningAnimation(isRun);
applySpeed = walkSpeed;
}
// 앉기 시도
private void TryCrouch()
{
if (Input.GetKeyDown(KeyCode.LeftControl))
{
Crouch();
}
}
// 앉기 동작
private void Crouch()
{
isCrouch = !isCrouch;
theCrosshair.CrouchingAnimation(isCrouch);
if (isCrouch)
{
applySpeed = crouchSpeed;
applyCrouchPosY = crouchPosY;
}
else
{
applySpeed = walkSpeed;
applyCrouchPosY = originPosY;
}
StartCoroutine(CrouchCoroutine());
}
// 부드러운 앉기 동작
IEnumerator CrouchCoroutine()
{
float _posY = theCamera.transform.localPosition.y;
int count = 0;
while(_posY != applyCrouchPosY)
{
count++;
_posY = Mathf.Lerp(_posY, applyCrouchPosY, 0.2f);
theCamera.transform.localPosition = new Vector3(0, _posY, 0);
if(count > 15)
break;
yield return null;
}
theCamera.transform.localPosition = new Vector3(0, applyCrouchPosY, 0);
}
private void Move()
{
float _moveDirX = Input.GetAxisRaw("Horizontal");
float _moveDirZ = Input.GetAxisRaw("Vertical");
Vector3 _moveHorizontal = transform.right * _moveDirX;
Vector3 _moveVertical = transform.forward * _moveDirZ;
Vector3 _velocity = (_moveHorizontal + _moveVertical).normalized * applySpeed;
myRigid.MovePosition(transform.position + _velocity * Time.deltaTime);
}
private void MoveCheck()
{
if (!isRun && !isCrouch && isGround)
{
if (Vector3.Distance(lastPos, transform.position) >= 0.01f)
isWalk = true;
else
isWalk = false;
theCrosshair.WalkingAnimation(isWalk);
lastPos = transform.position;
}
}
private bool pauseCameraRotation = false;
private void CameraRotation()
{
if (!pauseCameraRotation)
{
float _xRotation = Input.GetAxisRaw("Mouse Y");
float _cameraRotationX = _xRotation * lookSensitivity;
currentCameraRotationX -= _cameraRotationX;
currentCameraRotationX = Mathf.Clamp(currentCameraRotationX, -cameraRotationLimit, cameraRotationLimit);
theCamera.transform.localEulerAngles = new Vector3(currentCameraRotationX, 0f, 0f);
}
}
public IEnumerator TreeLookCoroutine(Vector3 _target)
{
pauseCameraRotation = true;
Quaternion direction = Quaternion.LookRotation(_target - theCamera.transform.position);
Vector3 eulerValue = direction.eulerAngles;
float destinationX = eulerValue.x;
while(Mathf.Abs(destinationX - currentCameraRotationX) >= 0.5f)
{
eulerValue = Quaternion.Lerp(theCamera.transform.localRotation, direction, 0.3f).eulerAngles;
theCamera.transform.localRotation = Quaternion.Euler(eulerValue.x, 0f, 0f);
currentCameraRotationX = theCamera.transform.localEulerAngles.x;
yield return null;
}
pauseCameraRotation = false;
}
private void CharacterRotation()
{
float _yRotation = Input.GetAxisRaw("Mouse X");
Vector3 _characterRotationY = new Vector3(0f, _yRotation, 0f) * lookSensitivity;
myRigid.MoveRotation(myRigid.rotation * Quaternion.Euler(_characterRotationY));
}
}
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기