티스토리 뷰

💻 Unity

Lerp()

Unity에서 보간(Interpolation) 을 수행하는 함수

두 값 사이의 중간 값을 계산하는 기능을 하며, 주로 위치 이동, 색상 변화, 회전 보간 등에 사용된다

Mathf.Lerp(a, b, t) 숫자 보간 Mathf.Lerp(0, 10, 0.5f) → 5
Vector3.Lerp(a, b, t) 위치 보간 캐릭터 이동
Color.Lerp(a, b, t) 색상 보간 UI 색상 변경

Quaternion

Unity에서 회전(Rotation) 을 표현하는 방식

오일러 각(Euler angles) 대신 Quaternion 을 사용하여 회전을 다룬다

Quaternion이 필요한 이유

  1. 깜빡임 문제(Gimbal Lock) 방지
    • 오일러 각(Euler Angles)을 사용할 경우, 특정 각도에서 회전 축이 겹치는 문제가 발생함
    • Quaternion은 이를 방지할 수 있음
  2. 부드러운 회전(Interpolations) 가능
    • Quaternion.Lerp() 및 Quaternion.Slerp()을 사용하여 부드러운 회전 변화 구현 가능
Quaternion.Euler(x, y, z) 오일러 각을 Quaternion으로 변환
Quaternion.identity 초기 회전값 (0,0,0)
Quaternion.LookRotation(Vector3 direction) 특정 방향을 바라보게 회전
Quaternion.Lerp(q1, q2, t) 선형 보간 (빠르게 회전)
Quaternion.Slerp(q1, q2, t) 구면 선형 보간 (부드러운 회전)

🕹️ 실습 (2D 횡스크롤)

Player

public float speed = 5;
public float jumpUp = 1;
public Vector3 direction;

Animator animator;
Rigidbody2D rigid2D;
SpriteRenderer sp;
public GameObject slash;

public bool isJump = false;

void Start()
{
    animator = GetComponent<Animator>();
    rigid2D = GetComponent<Rigidbody2D>();
    sp = GetComponent<SpriteRenderer>();
    direction = Vector2.zero;
}

void Update()
{
    FlipPlayer();
    Move();
    Jump();
    Attack();
}

private void FixedUpdate()
{
    CheckGround();
}

private void FlipPlayer()
{
    direction.x = Input.GetAxisRaw("Horizontal");

    if (direction.x < 0)
    {
        sp.flipX = true;
        animator.SetBool("isRun", true);
    }
    else if (direction.x > 0)
    {
        sp.flipX = false;
        animator.SetBool("isRun", true);
    }
    else
    {
        animator.SetBool("isRun", false);
    }
}

private void Move()
{
    transform.position += direction * speed * Time.deltaTime;        
}

private void Jump()
{
    if (Input.GetKeyDown(KeyCode.W) && !animator.GetBool("isJump"))
    {
        rigid2D.linearVelocity = Vector2.zero;
        rigid2D.AddForce(new Vector2(0, jumpUp), ForceMode2D.Impulse);
        animator.SetBool("isJump", true);
        //isJump = true;
    }
}

private void CheckGround()
{
    Debug.DrawRay(rigid2D.position, Vector3.down, new Color(0, 1, 0));

    RaycastHit2D rayHit = Physics2D.Raycast(
        rigid2D.position, Vector3.down, 1, LayerMask.GetMask("Ground"));

    if (rigid2D.linearVelocityY < 0 && rayHit.collider != null && rayHit.distance < 0.7f)
    {
        animator.SetBool("isJump", false);
    }
}

private void Attack()
{
    if (Input.GetMouseButton(0))
    {
        animator.SetTrigger("Attack");
    }
}

private void AttackSlash() // 애니메이터에서 Event로 호출해줌
{
    Instantiate(slash, transform.position, Quaternion.identity);
}

Slash

private GameObject player;

Vector2 MousePos;
Vector3 dir;

float angle;
Vector3 dirNo;

public Vector3 direction = Vector3.right;

void Start()
{
    player = GameObject.FindGameObjectWithTag("Player");
    Transform tr = player.GetComponent<Transform>();
    MousePos = Input.mousePosition;
    MousePos = Camera.main.ScreenToWorldPoint(MousePos);
    Vector3 pos = new Vector3(MousePos.x, MousePos.y, 0);
    dir = pos - tr.position;

    angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg; // 바라보는 각도 구하기
}

void Update()
{
    transform.rotation = Quaternion.Euler(0f, 0f, angle);
    transform.position = player.transform.position;
}

public void MyDestroy()
{
    Destroy(gameObject);
}

Shadow

private GameObject player;
public float speed = 10;

void Update()
{
    player = GameObject.FindGameObjectWithTag("Player");
    transform.position = Vector3.Lerp(transform.position, player.transform.position, speed * Time.deltaTime);
}

Stair

public GameObject player;

private void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.gameObject.CompareTag("Player"))
    {
        player.GetComponent<Rigidbody2D>().gravityScale = 0;
    }
}

private void OnCollisionExit2D(Collision2D collision)
{
    if (collision.gameObject.CompareTag("Player"))
    {
        player.GetComponent<Rigidbody2D>().gravityScale = 1;
    }
}

HitLazer

float speed = 80f;
Vector2 MousePos;
Transform tr;
Vector3 dir;

float angle;
Vector3 dirNo;

void Start()
{
    tr = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
    MousePos = Input.mousePosition;
    MousePos = Camera.main.ScreenToWorldPoint(MousePos);
    Vector3 pos = new Vector3(MousePos.x, MousePos.y, 0);
    dir = pos - tr.position;

    angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;

    dirNo = new Vector3(dir.x, dir.y, 0).normalized;

    Destroy(gameObject, 4f);
}

void Update()
{
    transform.rotation = Quaternion.Euler(0f, 0f, angle);

    transform.position += dirNo * speed * Time.deltaTime;
}

Cursor

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함