- transform을 이용해 플레이어 이동을 구현
- transform을 이용하므로 Time.deltaTime을 꼭 사용해야함.
float h = Input.GetAxisRaw("Horizontal"); float v = Input.GetAxisRaw("Vertical"); Vector3 curPos = transform.position; Vector3 nextPos = new Vector3(h, v, 0) * speed * Time.deltaTime; transform.position = curPos + nextPos;
- 보통 종스크롤 슈팅게임은 모바일에서 많이하기 때문에 , 해상도를 맞춰준다.
- Game창에 Free Aspect(자유 비율 (카메라크기 = Game 뷰 크키))
-> 우리가 마음대로 조절이 가능하다.- +를 눌러 새로운 화면 뷰 생성이 가능하다.
- Type : Fixed Resolution(고정 해상도)
- Aspect Ratio로 설정하고 보통 스마트폰 크기인 9:16으로 생성
- 플레이어가 화면 밖으로 나가지 않도록 경계를 설정
Border라는 빈 오브젝트를 만들고 그 안에 Top, Bottom, Left, Right 4개의 오브젝트를 넣은 후 , Box Collider2D를 이용해 범위를 지정한다.- 각 경계에 Rigidbody2D를 넣어주고 움직일 필요가 없으니 Type을 Static으로 설정한다.
- 플레이어한테도 Box Collider2D와 Rigidbody2D를 생성해준다.
확인을 해보면 외부로 플레이어가 나가진 않지만 물리충돌에 의한 떨림현상이 일어난다.- 해결법 -
- Player의 Rigidbody Type을 Kinematic으로 설정해주고, 로직을 스크립트로 작성
- 4방향경계를 모두 isTrigger 설정 후 변수를 생성
- OnTriggerEnter2D로 플래그 세우기
- 플래그 변수를 사용해 경계이상을 넘지못하도록 설정public void OnTriggerEnter2D(Collider2D collision) { if(collision.gameObject.tag == "Border") { switch(collision.gameObject.name) { case "Top": isTouchTop = true; break; case "Bottom": isTouchBottom = true; break; case "Left": isTouchLeft = true; break; case "Right": isTouchRight = true; break; } } }
- OnTriggerExit2D로 플래그 지우기
private void OnTriggerExit2D(Collider2D collision) { if (collision.gameObject.tag == "Border") { switch (collision.gameObject.name) { case "Top": isTouchTop = false; break; case "Bottom": isTouchBottom = false; break; case "Left": isTouchLeft = false; break; case "Right": isTouchRight = false; break; } } }
- Update문에서 수정부
if ((isTouchRight && h == 1) || (isTouchLeft && h == -1)) h = 0; float v = Input.GetAxisRaw("Vertical"); if ((isTouchTop && v == 1) || (isTouchBottom && v == -1)) v = 0;
Rigidbody의 3가지 Type
1. Dynamic -> 물리현상을 받고 주변의 모든 물체와 상호작용이 가능하다.
2. Kinematic -> 물리현상을 받지않고 스크립트를 이용해 이동한다.
3. Static -> 움직이지 않는 물체
- int형 파라미터를 이용해 트랜잭션을 이동시킨다.
- 버튼을 누르거나 뗏을때 바로 동작할 수 있게 Has Exit Time을 끄고 Duration 제거
- SetInteger를 이용해 값 설정
if(Input.GetButtonUp("Horizontal") || Input.GetButtonDown("Horizontal")) { anim.SetInteger("Input", (int)h); }
Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public float speed;
public bool isTouchTop;
public bool isTouchBottom;
public bool isTouchLeft;
public bool isTouchRight;
Animator anim;
private void Awake()
{
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
float h = Input.GetAxisRaw("Horizontal");
if ((isTouchRight && h == 1) || (isTouchLeft && h == -1))
h = 0;
float v = Input.GetAxisRaw("Vertical");
if ((isTouchTop && v == 1) || (isTouchBottom && v == -1))
v = 0;
Vector3 curPos = transform.position;
Vector3 nextPos = new Vector3(h, v, 0) * speed * Time.deltaTime;
transform.position = curPos + nextPos;
// Animation
if(Input.GetButtonUp("Horizontal") || Input.GetButtonDown("Horizontal"))
{
anim.SetInteger("Input", (int)h);
}
}
public void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.tag == "Border")
{
switch(collision.gameObject.name)
{
case "Top":
isTouchTop = true;
break;
case "Bottom":
isTouchBottom = true;
break;
case "Left":
isTouchLeft = true;
break;
case "Right":
isTouchRight = true;
break;
}
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.tag == "Border")
{
switch (collision.gameObject.name)
{
case "Top":
isTouchTop = false;
break;
case "Bottom":
isTouchBottom = false;
break;
case "Left":
isTouchLeft = false;
break;
case "Right":
isTouchRight = false;
break;
}
}
}
}