Transform

감사콩·2025년 10월 15일

유니티

목록 보기
3/29

서론

Transform의 정의와 특징, 주요 속성을 알아보고
그를 응용한 유니티에서의 위치 이동 구현에 대해 알아보겠다.
일단 배운 걸 활용하여 과제를 제작해보겠다.



과제

과제 먼저 하는 이유
1. 배운거 바로 안 써먹으면 휘발되기 때문에
2. 재밌어서


목표

목표를 달성한 뒤 파괴 매커니즘까지 작성해보도록 하겠다.
오브젝트 풀링은 복습 TIL 작성 후에 시간 나면 추가해보기

목표를 달성하기 위한 과정

  1. 복습겸 총알 프리팹 하나 추가로 제작(BBbullet)
  2. Bullet 컴포넌트를 생성하여 총알의 속도, 방향 구현 및 이동 함수 작성
  3. 총구(FirePoint)를 Player 청사진에 추가
  4. Weapon 컴포넌트를 추가하여 총알 발사 함수를 작성
  5. 총알 생성 발사 파괴까지

순서대로 가보자


1. BBbullet 제작

비비탄 완성
Material 에서 메탈릭을 적용하니 반들반들해졌다.

크기는 메인 카메라 조절하면서 줄일 예정

2. Bullet 컴포넌트 제작

총알의 속도, 진행방향을 선언하고 이동 함수를 구현

using System.Collections;
using System.Collections.Generic;
using Unity.Collections;
using UnityEngine;

// bullet의 기본속도와 방향을 선언하고, 총알의 이동을 구현

public class Bullet : MonoBehaviour
{
    [SerializeField] private float bulletSpeed = 30f;
    [SerializeField] Vector3 moveDirection = Vector3.forward;

    private void Update()
    {
        BulletMove();
    }

    private void BulletMove()
    {
        transform.position += bulletSpeed * Time.deltaTime * moveDirection;
    }
}

기본 속도 30f
기본 방향 foward로 설정.

3. 총구(FirePoint) 제작

Create Empty를 통해 Player 오브젝트 앞에 무형의 총구를 제작.
여기에 총알 발사 컴포넌트를 추가하겠다.


4. Weapon 컴포넌트 제작

reload를 선언하고 총알 발사 함수를 작성

using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;

//총알 장전 및 발사방향을 불러와 발사하는 메서드 출력
public class Weapon : MonoBehaviour
{
    [SerializeField] private GameObject bulletPrefab;
    [SerializeField] private Transform firePoint;
    [SerializeField] private float reload = 0.5f;
    private float nextFire = 0f;
    void Update()
    {
        nextFire = Time.deltaTime + reload;
        if (Input.GetKey(KeyCode.Space) && nextFire >= reload )
        {
            FireBullet();
        }
    }

    /// <summary>
    /// 총알 생성 및 방향 설정
    /// </summary>
    private void FireBullet()
    {
        // 총알 인스턴스 생성
        GameObject bulletInstance = Instantiate(bulletPrefab, firePoint.position, Quaternion.identity);
        //불릿 컴포넌트 가져오기
        Bullet bulletData = bulletInstance.GetComponent<Bullet>();
        if (bulletData != null)
        {
            bulletData.moveDirection = firePoint.forward;
        }
    }

}

발사체크

nextFire가 항상 리로드보다 크니까 생긴 문제
기왕 고치는 거 다른 함수도 활용해보려고 한다.

해결책

도와줘요 매뉴얼

제일 아래

Time.time은 플레이어가 시작한 이후 경과한 시간의 양을 가리키며 일반적으로 꾸준히 계속해서 증가합니다. Time.deltaTime은 지난 프레임 이후 경과한 시간의 양을 가리키므로 이상적으로는 꽤 일정하게 유지됩니다.

Time.time를 사용해보자

이런 식으로 하고 실행해보겠다.



EZ

기본 목표는 달성했으니
Player.cs에 역할 분담해주고 Bullet.cs에 Destroy 함수를 사용해보겠다

5. Destroy()

Bullet 스크립트에 추가

Start() 2초 뒤 알아서 제거되도록 설정




Transform

모든 게임 오브젝트가 가지고 있는 기본 컴포넌트
어제 배운 대로 위치(Vector), 회전(Quaternion), 크기(Vector)를 담당

Transform 함수

  1. 위치 이동 구현
// Position을 직접적으로 변경
Transform.position = new Vector3(x, y, z);

// Translate 함수를 이용한 축(x, y, z) 기준 위치이동
Transform.Translate(Direction * Speed);

// 선형 보간을 이용해 거리에 따라 빠르게 이동하며 천천히 감속
Transform.position = Vector3.Lerp(StartPosition, EndPosition, Interpolation)

// 목표지점을 향해 일정한 속도로 이동
Transform.position = Vector3.MoveTowards(transform.position, Target.Position, Speed);
  1. 회전 구현(3축 기준)
// rotation에 값을 직접 지정해 회전
Transform.rotation = Quaternion.Euler(x, y, z);

// Rotate 함수를 이용한 회전
Transform.Rotate(Vector3.up, Speed);

// RotateAround를 이용한 중심축 기준으로 회전
Transform.RotateAround(Target.position, Vector3.up, Speed);

// LookAt을 이용한 대상을 향해 회전시키기
Transform.LookAt(Target.position);
  1. 크기값 구현
// Scale 조절
Transform.localScale = new Vector3(x, y, z);

// lossyScale은 부모 오브젝트의 스케일에 상관 없이 자신 고유의 Scale 수치를 반환
Transform.lossyScale

Quaternion

유니티엔진 내부적으로 4개의 실수로 구성된 복소수로 오브젝트의 회전을 연산함.

오일러 각을 기반으로 회전에 대한 연산을 다루지 않는 이유는?
1. 두개의 축이 겹쳐져 하나의 축이 기능을 상실하는 짐벌락 현상을 방지

  1. 오일러 각보다 연산 성능적으로 우수

Vector

크기와 방향을 모두 가지는 물리적/수학적 개념
Vector3(2, 1, 1)

기본 제공 속성

적재적소에 맞게 활용해보자

정규화(normalized)

방향을 계산한 뒤 크기를 고정하는 것(대각선 이동 등)
온보딩 때 배웠던 내용 리비전

Hierarchy

부모-자식 관계
부모 Transform 기준으로 자식의 이동/회전/스케일이 적용됨.



위치 이동 구현

위치 이동을 구현하기 위해 필요한 입출력을 알아보겠다.

각자 다른 환경에서 동일한 위치 이동이 구현되어야 한다.
그를 위해 필요한 요소부터 알아보겠다.

Frame

게임의 움직임 중 한 장의 이미지를 표현.
Frame Per Second = 초당 프레임 수
PC마다 성능이 다르므로 초당 표현할 수 있는 프레임 수가 다른 건 당연함.

즉 정해진 시간 내의 Update() 호출 수도 적으니
각 환경에 따라 다른 결과값이 도출될 수 있음

그를 위해 필요한 것이 DeltaTime


Delta Time

1 프레임의 갱신에 소요된 시간
( = 1 / FPS)

이걸 활용하여 어떤 PC에서든 동일한 이동속도를 표현 가능
이동속도 x Delta Time

이외에도 시간 카운트 등 다양한 곳에 사용
Time.deltaTime 유니티에서 지원해 주므로 활용



Input Class

방금까지 출력 방식을 알아봤다면 이번엔 입력 방식에 대해 알아보겠다.
흔히 사용되는 함수부터 알아보자

1. GetKey

단일 키 입력에 대한 여부를 반환받기 위한 함수

Input.GetKey()      // 키 입력이 진행되는 동안 true를 반환 
Input.GetKeyDown()  // 키 입력이 시작되는 순간 1회 true를 반환
Input.GetKeyUp()    // 키 입력이 종료되는 순간 1회 false를 반환

2. GetAxis

유니티에서 제공하는 Input Manager에 대응하는 코드
유니티 좌표상의 X(Horizontal), Z(Vertical)축에 해당하는 입력 데이터
미입력 시 0
방향 = -1.0 ~ 1.0 사이의 float값 반환

3. GetAxisRaw

GetAxis와 마찬가지로 Input Manager에 대응하고
유니티 좌표상의 X, Z축에 해당하는 입력 데이터를 -1, 0, 1로 반환
키보드 입력에 대한 이동 구현에 적합

마무리

Transform에 대한 개념을 알아보고
그를 통한 위치 이동 구현을 과제 및 복습을 통해 응용해보았다.

기본으로 제공되는 속성은 하나씩 사용해가며 익숙해져야겠다.

profile
안녕하시와요

0개의 댓글