using System.Collections;
using UnityEngine;
public class MovingObjcet : MonoBehaviour
{
//케릭터 이동속도
public float speed;
//픽셀 단위로 움직이기 구현
public int walkCount;
protected int currentWalkCount;
protected bool npcCanMove = true;
//벡터(케릭터의 이동 방향)
protected Vector3 vector;//protected는 부모자식간에 참조는 가능하지만 인스펙터창과 외부클레스는 접근불가
public BoxCollider2D boxCollider;//박스콜라이더
public LayerMask layerMask;//통과불가 에이리어 설정
public Animator animator;//애니메이터
protected void Move(string _dir, int _frequency)
{
npcCanMove = false;
StartCoroutine(MoveCoroutine(_dir, _frequency));
}
IEnumerator MoveCoroutine(string _dir, int _frequency)
{
vector.Set(0, 0, vector.z);
switch (_dir)
{
case "UP":
vector.y = 1f;
break;
case "DOWN":
vector.y = -1f;
break;
case "RIGHT":
vector.x = 1f;
break;
case "LEFT":
vector.x = -1f;
break;
}
//에니메이터 불러오기
animator.SetFloat("DirX", vector.x);
animator.SetFloat("DirY", vector.y);
animator.SetBool("Walking", true);
while (currentWalkCount < walkCount)
{
transform.Translate(vector.x * speed, vector.y * speed, 0);
currentWalkCount++;
yield return new WaitForSeconds(0.01f);
}
currentWalkCount = 0;
if (_frequency != 5)
{
animator.SetBool("Walking", false);
}
animator.SetBool("Walking", false);
npcCanMove = true;
}
protected bool CheckCollsion()
{
RaycastHit2D hit;//레이케스트
Vector2 start = transform.position; //캐릭터의 현제 위치 값
Vector2 end = start + new Vector2(vector.x * speed * walkCount, vector.y * speed * walkCount);
//캐릭터가 이동하고자하는 위치 값 그리고 사이즈
boxCollider.enabled = false;
hit = Physics2D.Linecast(start, end, layerMask);
boxCollider.enabled = true;
if (hit.transform != null)
return true;
return false;
}
}
using System.Collections;
using UnityEngine;
public class PlayerManager : MovingObjcet
{
static public PlayerManager instance;
//public string currentMapName;
public string walkSound_1;
public string walkSound_2;
public string walkSound_3;
public string walkSound_4;
private AudioManager theAudio;
//public AudioClip walkSound_1;//사운드 파일
//public AudioClip walkSound_2;
private AudioSource audioSource;//사운드 플레이어
//뛰기,평범하게 걷기
public float runSpeed;
private float applyRunSpeed;
private bool applyRunFlag = false;
//한칸한칸 이동할때 플레그 형식으로 구현
private bool canMove = true;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
if (instance == null)
{
DontDestroyOnLoad(this.gameObject);
boxCollider = GetComponent<BoxCollider2D>();
//audioSource = GetComponent<AudioSource>();
animator = GetComponent<Animator>();
theAudio = FindAnyObjectByType<AudioManager>();
instance = this;
}
else
{
Destroy(this.gameObject);
}
}
//코루틴으로 이동제어 한칸 한칸 이동하게
IEnumerator MoveCoroutine()
{
while (Input.GetAxisRaw("Vertical") != 0 || Input.GetAxisRaw("Horizontal") != 0)
{
//시프트 키 입력 여부에 따라 뛰기 걷기 구분
if (Input.GetKey(KeyCode.LeftShift))
{
applyRunSpeed = runSpeed;
applyRunFlag = true;
}
else
{
applyRunSpeed = 0;
applyRunFlag = false;
}
//이동방향 벡터 움직임 구현
vector.Set(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"), transform.position.z);
//좌상,좌하 등 대각선 방향이동 장금
if (vector.x != 0)
vector.y = 0;
//에니메이터 불러오기
animator.SetFloat("DirX", vector.x);
animator.SetFloat("DirY", vector.y);
bool checkCollsionFlag = base.CheckCollsion();
if (checkCollsionFlag)
break;
animator.SetBool("Walking", true);
int temp = Random.Range(1, 4);
switch (temp)
{
case 1:
theAudio.Play(walkSound_1);
break;
case 2:
theAudio.Play(walkSound_2);
break;
case 3:
theAudio.Play(walkSound_3);
break;
case 4:
theAudio.Play(walkSound_4);
break;
}
theAudio.SetVolumn(walkSound_2, 0.5f);
//캐릭터 이동구현 코드
while (currentWalkCount < walkCount)
{
if (vector.x != 0)
{
//Translate는 현제 값에서 +를 해주는 코드
transform.Translate(vector.x * (speed + applyRunSpeed), 0, 0);
}
else if (vector.y != 0)
{
transform.Translate(0, vector.y * (speed + applyRunSpeed), 0);
}
if (applyRunFlag)
currentWalkCount++;//위의 applyRunFlas가 되면 추가되는 카운트 만약 아니라면 더해지지 않음
currentWalkCount++;//위의 카운트와는 별개의 카운트로 구분 됨
yield return new WaitForSeconds(0.01f);//0.01초마다 대기
/*if(currentWalkCount % 9 == 2)
{
int temp = Random.Range(1, 2);
switch (temp)
{
case 1:
//audioSource.clip = walkSound_1;
//audioSource.Play();
break;
case 2:
//audioSource.clip = walkSound_2;
//audioSource.Play();
break;
}
}*/
}
currentWalkCount = 0;//0을 넣어서 반복문 초기화
}
animator.SetBool("Walking", false);
//한칸한칸 이동할때 bool값
canMove = true;
}
//매 프레임마다 이동명령을 받음
void Update()
{
if (canMove)
{
//이동 방향키 입력을 할때 쯔구르 처럼 상하좌우 구분하게 하는 코드
if (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0)
{
//한칸 한칸 이동할때 bool값으로 canMove를 이용함
canMove = false;
StartCoroutine(MoveCoroutine());
}
}
}
}
이번 장에서는 PlayerManager에서 MovingObject에 넣을 함수를 마저 넣을 것이다
PlayerManager에서 MovingObject에 레이케스트 히트로 쯔구르 처럼 이동하게 하면서 이동에 제한을 걸어주는 부분을 MovingObject를 넣어준다
그리고 원본과 이 부분이 차이가 있으니 수정해준다
protected로 인스팩터에는 드러내지 않으면서 스크립트에서는 참조하게 바꿔준다
그리고 bool로 참과 거짓을 나눈다
즉 새로운 함수를 만드는 것이다
그리고 기존의 레이케스트 히트가 있던 PlayerManager에는 이렇게 적어준다
bool checkCollsionFlag = base.CheckCollsion();은
임시로 선언해준 함수이고 PlayerManager에는 MovingObject가 참조가 되어 있으니
base.CheckCollsion(); 함수로 호출한다
그 뒤 if(checkCollsionFlag)를 조건문으로 걸어서 true가 되면 트루가 되면서 이동을 멈추가 된다
만약 true가 아니라면 break가 걸리지 않고 아래의 함수가 실행된다
'쯔꾸르식 유니티 게임 공부' 카테고리의 다른 글
12.NPC 충돌방지(Box콜라이더 이동) (0) | 2025.01.16 |
---|---|
11.이벤트 캐릭터 이동명령 이벤트 (0) | 2025.01.15 |
10.NPC구현하기 (0) | 2025.01.10 |
6.씬과 씬 이동 개량 완료 (0) | 2025.01.09 |
6.개량 씬과 씬 이동하면서 위치 지정하기 (0) | 2025.01.05 |