![article thumbnail image](https://blog.kakaocdn.net/dn/7oxtE/btqHMwDQUsy/SG5CFp3OYQVMvxTLqmZ6K0/img.png)
반응형
Position
Update()는 한 프레임당 실행된다. 60 프레임이라고 했을 경우, 1/60초마다 Update() 함수가 호출되는 셈이다. 따라서 해당 코드를 실행하면 플레이어가 비정상적으로 빠르게 움직인다.
void Update()
{
if(Input.GetKey(KeyCode.W))
{
transform.position += new Vector3(0.0f, 0.0f, 1.0f);
}
if(Input.GetKey(KeyCode.S))
{
transform.position -= new Vector3(0.0f, 0.0f, 1.0f);
}
if (Input.GetKey(KeyCode.A))
{
transform.position -= new Vector3(1.0f, 0.0f, 0.0f);
}
if (Input.GetKey(KeyCode.D))
{
transform.position += new Vector3(1.0f, 0.0f, 0.0f);
}
}
따라서 Time.deltaTIme, 현재 시간과 비례한 수치를 곱하게끔 수정한다.
void Update()
{
if(Input.GetKey(KeyCode.W))
{
transform.position += new Vector3(0.0f, 0.0f, 1.0f) * Time.deltaTime * _speed;
}
if(Input.GetKey(KeyCode.S))
{
transform.position -= new Vector3(0.0f, 0.0f, 1.0f) * Time.deltaTime * _speed;
}
if (Input.GetKey(KeyCode.A))
{
transform.position -= new Vector3(1.0f, 0.0f, 0.0f) * Time.deltaTime * _speed;
}
if (Input.GetKey(KeyCode.D))
{
transform.position += new Vector3(1.0f, 0.0f, 0.0f) * Time.deltaTime * _speed;
}
}
[SerializeField]: private 변수여도 Unity Inspector에서 접근 가능하게끔 선언한다.
public class PlayerController : MonoBehaviour
{
[SerializeField]
float _speed = 10.0f;
//...
}
Vector3.forward / Vector3.back / Vector3.left / Vector3.right
X 키를 누르면 월드 좌표 <-> 로컬 좌표 토글이 가능하다.
앞으로 이동한다는 개념은 플레이어 기준, 즉 로컬 좌표로 이동해야 한다.
void Update()
{
//TransformDirection: Local -> World
//InverseTransformDirection: World -> Local
if(Input.GetKey(KeyCode.W))
{
transform.position += transform.TransformDirection(Vector3.forward * Time.deltaTime * _speed);
}
if(Input.GetKey(KeyCode.S))
{
transform.position += transform.TransformDirection(Vector3.back * Time.deltaTime * _speed);
}
if (Input.GetKey(KeyCode.A))
{
transform.position += transform.TransformDirection(Vector3.left * Time.deltaTime * _speed);
}
if (Input.GetKey(KeyCode.D))
{
transform.position += transform.TransformDirection(Vector3.right * Time.deltaTime * _speed);
}
}
이 방식이 귀찮다면 transform.Translate() 함수를 이용하자.
void Update()
{
if(Input.GetKey(KeyCode.W))
{
transform.Translate(Vector3.forward * Time.deltaTime * _speed);
}
if(Input.GetKey(KeyCode.S))
{
transform.Translate(Vector3.back * Time.deltaTime * _speed);
}
if (Input.GetKey(KeyCode.A))
{
transform.Translate(Vector3.left * Time.deltaTime * _speed);
}
if (Input.GetKey(KeyCode.D))
{
transform.Translate(Vector3.right * Time.deltaTime * _speed);
}
}
Vector3
1. 위치 벡터: (x, y, z)를 좌표로 인식한다.
2. 방향 벡터
Vector3(0, 0, 1) => forward, 어떠한 방향을 나타내고 있다.
내가 상대방에게 가기 위한 좌표를 구하려면 상대방의 위치 좌표에서 내 좌표를 뺀다.
1) 거리(크기) magnitude와 2) 실제 방향 normalized을 나타내는 특징이 있다.
단위 벡터는 크기가 1짜리인, normalized인 벡터이다. 방향에 대한 정보만 가지고 있다.
struct MyVector
{
public float x;
public float y;
public float z;
// +
// + +
// +----------+
public float magnitude { get { return Mathf.Sqrt(x * x + y * y + z * z); } }
public MyVector normalized { get { return new MyVector(x / magnitude, y / magnitude, z / magnitude); } }
public MyVector(float x, float y, float z) { this.x = x; this.y = y; this.z = z; }
public static MyVector operator +(MyVector a, MyVector b)
{
return new MyVector(a.x + b.x, a.y + b.y, a.z + b.z);
}
public static MyVector operator -(MyVector a, MyVector b)
{
return new MyVector(a.x - b.x, a.y - b.y, a.z - b.z);
}
public static MyVector operator *(MyVector a, float d)
{
return new MyVector(a.x * d, a.y * d, a.z * d);
}
}
public class PlayerController : MonoBehaviour
{
[SerializeField]
float _speed = 10.0f;
void Start()
{
MyVector to = new MyVector(10.0f, 0.0f, 0.0f);
MyVector from = new MyVector(5.0f, 0.0f, 0.0f);
MyVector dir = to - from; // (5.0f, 0.0f, 0.0f)
dir = dir.normalized; // (1.0f, 0.0f, 0.0f)
MyVector newPos = from + dir * _speed;
// 방향 벡터
// 1. 거리(크기)
// 2. 실제 방향
}
// ...
}
반응형