유니티에서 객체를 이동시키거나 회전시키는 방법은 2가지가 있다.
1. 모든 객체에 있는 Transform컴포넌트의 position, rotation 속성을 지속해서 변경하는 것이다.
2. 내장된 물리엔진을 이용해 물리적인 힘(Force)또는 회전력(Torque)을 가해 변경시키는 것이다.
애니메이션으로도 이동및 회전을 할 수 있지만, 이건 Transform컴포넌트의 속성값을 연속적으로 기록한 것을 재생하는 것이기 때문에 Transform컴포넌트를 이용하는 방법이다.
하이라키의 Player Object을 선택한후 인스펙터뷰에서 Add Component에서 new Script를 선택하고 PlayerCtrl로 한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCtrl : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
transform.position += new Vector3(h, 0f, v);
}
}
h,v를 입력 받아 Vector3 구조체를 만들어 transform.position에 "+=" 연산해준다.
h,v의 범위는 WASD나 화살표키에 따라 -1f~1f의 범위를 갖기 때문에 Player는 전후좌우로 잘 움직인다.
주의할건 Vector3(h,v,0f)가 아니라 Vector(h,0f,v)라는 거다 유니티는 3차원 좌표시스템인데 y는 위아래를 뜻한다. 따라서 x는 좌우 z는 전후를 뜻한다.
Play해보면 무지하게 빠르지만 잘 움직인다. 왜냐하면 Update()함수는 컴퓨터마다 다르자만 1초에 대략 60번 정도는 호출되기 때문이다. 그리고 이렇게 자주 호출되기때문에 되도록이면 무거운 처리를 피해야한다.
다음과 같이 자주호출될 Transform의 참조를 tr에 저장해놓고 사용하면 좀 가벼워진다. 이걸 컴포넌트캐시라고 한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCtrl : MonoBehaviour
{
// Start is called before the first frame update
Transform tf;
void Start(){
tf = GetComponent<Transform>();
}
// Update is called once per frame
void Update(){
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
tf.position += new Vector3(h, 0f, v);
}
}
tf.position += new Vector3(h, 0f, v);를 처리해주는 Translate()라는 함수가 있다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCtrl : MonoBehaviour
{
// Start is called before the first frame update
Transform tf;
void Start(){
tf = GetComponent<Transform>();
}
// Update is called once per frame
void Update(){
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
tf.Translate(new Vector3(h, 0f, v));
}
}
현재 움직임이 너무 빠르다. 왜냐하면 매프레임 호출되기 때문이다. 따라서 움직임을 작게하면 되지만 그렇게 되면 컴퓨터의 성능에 따라 속도차이가 나게 된다. 따라서 매 프레임의 시간간격을 곱해주면 컴퓨터의 성능에 관계없이 움직임 속도가 일정하게 된다. 성능이 나쁜 컴퓨터는 시간간격이 크기 때문에 그만큼 많이 움직이기 때문이다.
d(거리) = v1*t1 = v2*t2 , 컴퓨터 성능에 속도는 비례하지만 프레임간시간간격은 반비례한다.
간단하게 빠른 컴퓨터는 조금 움직이게 해주는거다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCtrl : MonoBehaviour
{
// Start is called before the first frame update
Transform tf;
void Start(){
tf = GetComponent<Transform>();
}
// Update is called once per frame
void Update(){
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
tf.Translate(Time.deltaTime * new Vector3(h, 0f, v));
}
}
단위벡터를 이용해 이동 벡터를 만들수 있다.
Vector3 dir = Vector3.right*x + Vector3.forward*v;
단위벡터와 단위벡터의 합은 √2가 될수 있으므로 스칼라값을 1로 만들기 위해 단위벡터로 만들려면 dir.normalized를 사용해야한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCtrl : MonoBehaviour {
// Start is called before the first frame update
Transform tf;
private float speed;
void Start() {
tf = GetComponent<Transform>();
speed = 8f;
}
// Update is called once per frame
void Update() {
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector3 dir = Vector3.right* h + Vector3.forward* v;
tf.Translate(dir.normalized * speed * Time.deltaTime);
}
}
'유니티게임강좌 > 주인공 캐릭터 제작' 카테고리의 다른 글
Assembly (0) | 2023.02.25 |
---|---|
[Player제작] 접근제한자 (0) | 2023.02.25 |
[Player제작] InputManager (2) | 2023.02.25 |
[Player제작] 유니티 Class 종류 (0) | 2023.02.25 |
[Player제작] 스크립트 (0) | 2023.02.25 |