Unity
[Unity] 3차 Study : MovingBlock Script
mooni_
2024. 3. 12. 12:22
[MovingBlock]
변수 선언부
public float moveX = 0.0f; //X축 이동 거리
public float moveY = 0.0f; //Y축 이동 거리
public float times = 0.0f; //출발점부터 도착점까지 이동 시간
public float weight = 0.0f; //편도 후 정지 시간
public bool isMoveWhenOn = false; //플레이어 접촉 여부에 따라 이동할 것인가?
public bool isCanMove = true; //이동이 가능한가?
float perDX; //1프레임당 X축 이동 값
float perDY; //1프레임당 Y축 이동 값
Vector3 defPos; //초기 위치
bool isReverse = false; //반전 여부
isMoveWhenOn : 이동 조건을 플레이어와의 접촉으로 할 것인가
isCanMove : 이동이 가능한가
Start()
void Start()
{
defPos = transform.position; //moving block 초기 위치
float timestep = Time.fixedDeltaTime; //호출 간격?
perDX = moveX * timestep / times; //식1)
perDY = moveY / (1.0f / timestep * times); //식2)
if (isMoveWhenOn)
{
isCanMove = false; //플레이어 접촉 시 이동이 가능하다면 시작 시 블록 이동 금지
}
}
Update 함수와 deltaTime
Update() : 매 프레임 마다 호출, 간격이 일정하지 않음
FixedUpdate() : 일정한 간격을 보장함, 물리적 충돌 등을 여기서 다룸
deltaTime → Update()에서 사용
fixedDeltaTime → FixedUpdate()에서 사용
+) perDX, perDY 구하는 식이 이해가 너무 안돼서 스터디원과 머리를 싸맴,,,
교재는 식2를 사용하였고 과정을 이해하다 도출해낸 식1도 문제 없이 실행되는 듯이후 이슈가 발견되면 수정
* 위의 경우는 Start()에서 fixedDeltaTime을 사용했는데 이건 뭘까,,, FixedUpdate()에서 다루는 변수인건가?
FixedUpdate()
private void FixedUpdate()
{
if(isCanMove) //이동 가능한 경우에만 FixedUpdate()내용 실행
{
float x = transform.position.x; //초기 위치값을 받음
float y = transform.position.y;
bool endX = false; //끝지점인가 여부
bool endY = false;
if(isReverse) //역방향일 경우에
{
//초기 위치값과 현재 위치값이 동일한 경우 == 시작지점 도착
//endX = true
if((perDX >= 0.0f && x <= defPos.x) || (perDX < 0.0f && x >= defPos.x))
{
endX = true;
}
if((perDY >= 0.0f && y <= defPos.y) || (perDY < 0.0f && y >= defPos.y))
{
endY = true;
}
//블록 역방향 이동
transform.Translate(new Vector3(-perDX, -perDY, defPos.z));
}
else //정방향일 경우에
{
//초기 위치값 + 이동거리와 현재 위치값이 동일한 경우 == 끝지점 도착
if((perDX >= 0.0f && x >= defPos.x + moveX) || (perDX < 0.0f && x <= defPos.x + moveX))
{
endX = true;
}
if((perDY >= 0.0f && y >= defPos.y + moveY) || (perDY < 0.0f && y <= defPos.y + moveY))
{
endY = true;
}
//블록 정방향 이동
Vector3 v = new Vector3(perDX, perDY, defPos.z);
transform.Translate(v);
}
if(endX && endY) //시작지점 | 끝지점에서
{
if(isReverse) //역방향이면
{
transform.position = defPos; //현재 포지션은 초기값
}
isReverse = !isReverse; //역방향 해제
isCanMove = false; //블록 멈추기
if(isMoveWhenOn == false) //플레이어와 접촉 상호작용을 받지 않으면 1초 후에 다시 움직임
{
Invoke("Move", weight);
}
}
}
}
시작지점, 끝지점을 체크해서 블록을 이동시킴
Move() Stop() OnCollisionEnter2D(Collision2D collision) OnCollisionExit2D(Collision2D collision)
public void Move()
{
isCanMove = true; //이동 가능
}
public void Stop()
{
isCanMove = false; //이동 불가
}
private void OnCollisionEnter2D(Collision2D collision) //충돌 발생
{
if(collision.gameObject.tag == "Player") //대상이 Player라면
{
collision.transform.SetParent(transform); //Player를 이동블럭의 자식으로 만들기
if(isMoveWhenOn)
{
isCanMove = true;
}
}
}
private void OnCollisionExit2D(Collision2D collision) //충돌 해제
{
if(collision.gameObject.tag == "Player") //대상이 Player라면
{
collision.transform.SetParent(null); //Player를 이동블럭의 자식에서 해제
}
}
Move(), Stop()은 스위치 연동 블록을 만들 때 사용함
충돌 함수는 블록을 플레이어의 부모로 설정하여 이동 중일 때 플레이어가 제자리에서 떨어지지 않도록 함
*교재 : 누구나 할 수 있는 유니티 2D 게임 제작