본문 바로가기

카테고리 없음

캐릭터 애니메이션(이동)

Rigidbody의 컴포넌트

이렇게 체크해주면 안넘어진다.

 

 void Update()
    {
        if (Input.GetKey(KeyCode.Alpha1) == true)
            gameObject.transform.position = new Vector3(-2, 1, 2);

        if (Input.GetKey(KeyCode.Alpha2) == true)
            gameObject.transform.position = new Vector3(2, 1, 2);

        if (Input.GetKey(KeyCode.Alpha3) == true)
            gameObject.transform.position = new Vector3(2, 1, -2);

        if (Input.GetKey(KeyCode.Alpha4) == true)
            gameObject.transform.position = new Vector3(-2, 1, -2);
    }

transform position을 이용한 방법

    void Update()
    {
        if (Input.GetKey(KeyCode.Alpha1) == true)
            gameObject.transform.Translate(new Vector3(-1, 0, 0));

        if (Input.GetKey(KeyCode.Alpha2) == true)
            gameObject.transform.Translate(new Vector3(1, 0, 0));

        if (Input.GetKey(KeyCode.Alpha3) == true)
            gameObject.transform.Translate(new Vector3(0, 0, 1));

        if (Input.GetKey(KeyCode.Alpha4) == true)
            gameObject.transform.Translate(new Vector3(0, 0, -1));
    }

Translate를 이용한 방법

    Rigidbody rb;
    float power = 30f;

    private void Start()
    {
        rb = gameObject.GetComponent<Rigidbody>();
    }

    private void Update()
    {
        if(Input.GetKey(KeyCode.LeftArrow)==true)
            rb.AddForce(Vector3.left*power);
        if(Input.GetKey (KeyCode.RightArrow)==true)
            rb.AddForce(Vector3.right*power);
        if(Input.GetKey(KeyCode.UpArrow)==true)
            rb.AddForce(Vector3.up*power);
        if(Input.GetKey(KeyCode.DownArrow)==true)
            rb.AddForce(Vector3.down*power);
    }

AddForce 를 이용한 방법 (빙판길 처럼 움직인다.

 

 

Velocity를 이용하면 질량과 관성을 무시하고 속도를 내는것이 가능하다

 Rigidbody rb;
    float speed = 10f;

    private void Start()
    {
        rb = gameObject.GetComponent<Rigidbody>();
    }

    private void Update()
    {
        float xMove = Input.GetAxis("Horizontal");
        float zMove = Input.GetAxis("Vertical");

        Vector3 getVel = new Vector3 (xMove, 0, zMove)*speed;
        rb.velocity = getVel;
    }

 

Vector3.foward를 사용하면 값을 얻어오지 않아도 speed만 곱해주면 된다.

Rigidbody rb;
    float speed = 10f;

    private void Start()
    {
        rb = gameObject.GetComponent<Rigidbody>();
    }

    private void FixedUpdate()  //물리 연산을 하는 코드는 FixedUpdate에 넣어야 한다.
    {
        // 정면 방향으로 이동
        Vector3 movement = Vector3.forward*speed;
        rb.velocity = movement;        
    }

 

 

코루틴을 무한루프 처럼 사용하는 방법

using System.Collections;
using System.Collections.Generic;
using UnityEditorInternal;
using UnityEngine;

public class CoroutineExample : MonoBehaviour
{
    private Coroutine myCoroutine;
    private void Start()
    {
        //코루틴을 시작합니다.
        myCoroutine = StartCoroutine(MyCoroutine());
    }

    private IEnumerator MyCoroutine()
    { 
        while (true)
        {
            //반복적으로 실행할 작업을 수행합니다.
            Debug.Log("Coroutine is running!");

            //1초 대기합니다.
            yield return new WaitForSeconds(1f);
        }
    }

    private void Update()
    {
        //예시로 특정 조건이 충족되면 코루틴을 중지합니다.
        if(Input.GetKeyDown(KeyCode.Space))
        {
            StopCoroutine(myCoroutine);
        }
    }
}

 

업데이트에 따라 연산하게 되면 프레임에 따라 연산 되기 때문에 불필요하게 연산되는 경우가 생긴다.

외부에서 업데이트처럼 임의대로 연산할 수 있게 한다.

코루틴을 이용하면 Update()에 맡기지 않고 연산의 횟수를 내마음 대로 할 수가 있는 것이다.

 

아래는 위 코드를 참조해서 이동 코드를 코루틴으로 제어 한 코드이다.

using System.Collections;
using System.Collections.Generic;
using UnityEditorInternal;
using UnityEngine;

public class MovePosition : MonoBehaviour
{
    Rigidbody rb;
    float speed = 10f;
    private Coroutine myCoroutine;

    private void Start()
    {
        rb = gameObject.GetComponent<Rigidbody>();
        myCoroutine = StartCoroutine(MyCoroutine());
    }
    private IEnumerator MyCoroutine()
    {
        while (true)
        {
            float xMove = Input.GetAxis("Horizontal");
            float zMove = Input.GetAxis("Vertical");

            Vector3 getVel = new Vector3(xMove, 0, zMove) * speed;
            rb.velocity = getVel;

            yield return new WaitForSeconds(0.05f);
        }
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
            StopCoroutine(myCoroutine);
    }
}

 

 

Plane

Capsule

TargetPosition

 

Cube

 

 

MoveToward 사용, 처음부터 끝까지 일정한 속도로 목표지점으로 이동한다.

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

public class MoveToTarget : MonoBehaviour
{
    public GameObject targetPosition;
    public float Speed = 1f;

    void Update()
    {
        transform.position = Vector3.MoveTowards(transform.position, 
            targetPosition.transform.position, Speed);
    }
}

 

SmoothDamp 사용 목적지에 부드럽게 도착한다.

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

public class MoveToTarget : MonoBehaviour
{
    public GameObject targetPosition;
    Vector3 vel = Vector3.zero;
    private void Update()
    {
        transform.position = Vector3.SmoothDamp(gameObject.transform.position, 
        targetPosition.transform.position, ref vel, 1f);
    }

}

 

 

선형 보간을 이용한 목표지점 이동 SmoothDamp와 비슷하다.

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

public class MoveToTarget : MonoBehaviour
{
    public GameObject targetPosition;
    private void Update()
    {        
        {
            transform.position = Vector3.Lerp(gameObject.transform.position, 
            targetPosition.transform.position, 0.005f);
        }
    }

}

구형 보간, 위로 호를 그리면서 이동한다.

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

public class MoveToTarget : MonoBehaviour
{
    public GameObject targetPosition;
    private void Update()
    {
        transform.position = Vector3.Slerp(gameObject.transform.position,
        targetPosition.transform.position, 0.05f);
    }

}