유니티-오브젝트 물리엔진

아따맘마·2020년 12월 23일
0

Unity

목록 보기
5/5

이제는 오브젝트에 물리엔진을 줌으로써 현실세계에서처럼 움직이게 해보려고 한다.

일단은 기본 오브젝트 셋팅은 다음과 같이 만들었다.
plane으로 바닥을 깔고 그 위에 구 7개, 바닥 구석에 Cube 한개.
여기서 Cube를 보면 투명하게 되어있다.

이를 설정하기 위해 오브젝트 설정창에서 Rendering ModeTransparent로 설정하고 아래 색깔 설정 창을 열어서 RGB 아래에 A칸을 왼쪽으로 설정하면 투명하게 설정 가능하다.

오브젝트 설정

이번에는 각각의 오브젝트에 물리엔진을 적용하기 위한 기초설정을 한다.

Add Component에서 Rigidbody를 검색하여 추가하고 Sphere ColliderRigidbody만 확인하면 된다.
공에 탄성을 주고싶으면

physic Material에서 마찰계수나 Bounce를 설정할 수 있다.

C# 코딩

User Ball

User가 직접 움직이는 공에 대한 코드를 짜보려고 한다.

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

public class MyBall : MonoBehaviour
{
    Rigidbody rigid;
    
    void Start()
    {
        rigid = GetComponent<Rigidbody>();
        //rigid.velocity = Vector3.right; // new Vector3(2, 4, 3);
        
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        if (Input.GetButtonDown("Jump"))
        {
            rigid.AddForce(Vector3.up * 5, ForceMode.Impulse);
            Debug.Log(rigid.velocity);
        }
        Vector3 vec = new Vector3(Input.GetAxis("Horizontal"), 
            0, 
            Input.GetAxis("Vertical"));
        rigid.AddForce(vec, ForceMode.Impulse);

        rigid.AddTorque(Vector3.up);
    }
    
        void OnTriggerStay(Collider other)
    {
        // 물리적인 충돌이 아닌 콜라이더 충돌로 발생하는 이벤트
        if (other.name == "Cube")
        {
            rigid.AddForce(Vector3.up * 2, ForceMode.Impulse);
        }
    }
}

Rigidbody

Rigidbody rigid;

Rigidbody 클래스를 통해 변수 하나를 설정한다. 이 변수로 오브젝트에 속도를 주거나 힘을 가하는 등 여러 물리엔진을 넣어줄 수 있다.

Velocity

    void Start()
    {
        rigid = GetComponent<Rigidbody>();
        rigid.velocity = Vector3.right; // new Vector3(2, 4, 3);
        
    }

rigid 변수에 GetComponent<>();로 기본적인 설정.<>안에 Rigidbody를 넣어준다.
오브젝트에 속도를 주어 움직이게 한다. velocity를 가할 때는 벡터를 통해 설정을 해줘야 한다. 지금은 3D환경이기 때문에 Vector3를 사용.
velocity를 Update()안에 넣어주면 1초에 계속 속도를 가하게 된다.

Force

Force에 관한 함수를 Update()안에 넣어주면 오류가 발생 가능성이 있다. 그래서 FixedUpdate()안에서 코드를 짜주어야 한다.

    void FixedUpdate()
    {
        if (Input.GetButtonDown("Jump"))
        {
            rigid.AddForce(Vector3.up * 5, ForceMode.Impulse);
            Debug.Log(rigid.velocity);
        }
        Vector3 vec = new Vector3(Input.GetAxis("Horizontal"), 
            0, 
            Input.GetAxis("Vertical"));
        rigid.AddForce(vec, ForceMode.Impulse);

        rigid.AddTorque(Vector3.up);
    }

Input키 "Jump"를 누르면 AddForce를 통해 위로 힘을 가하게 한다. ForceMode는 여러개가 있는데 여기서는 Impulse로 설정했다.
Vecter3 변수 vec로 방향키를 입력받으면 AddForce로 해당 방향키에 맞는 벡터 방향으로 힘을 주도록 코드를 짰다.
AddTorque는 오브젝트에 회전력을 가한다.

Trigger

    void OnTriggerStay(Collider other)
    {
        // 물리적인 충돌이 아닌 콜라이더 충돌로 발생하는 이벤트
        if (other.name == "Cube")
        {
            rigid.AddForce(Vector3.up * 2, ForceMode.Impulse);
        }
    }

위의 오브젝트 중 Cube에는 Rigidbody를 설정 안했다. 대신 공이 저 Cube 안으로 들어가면 위로 상승하는 Trigger을 주려고 한다. 그 오버워치의 맵들 중 중간에 위치한 위로 바람이 불어서 슈퍼 점프(?)하는 것처럼 말이다.
이러한 트리거는 OnTrigger(Start, Stay, Exit)에서 코딩을 해야한다.
공이 만나는 오브젝트 name == 'Cube'일 때 오브젝트에 위로 힘을 가하는 AddForce 코딩을 했다.

Other Ball

물리엔진 효과

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

public class OtherBall : MonoBehaviour
{
    MeshRenderer mesh;
    Material mat;

    void Start()
    {
        mesh = GetComponent<MeshRenderer>();
        mat = mesh.material;
    }

    void OnCollisionEnter(Collision collision)
    {
        //물리적 충돌이 시작할때 호출되는 함수
        if (collision.gameObject.name == "Sphere")
            mat.color = new Color(0, 0, 0); //color : 기본색상 클래스, color32 : 255색상 클래스

    }

    private void OnCollisionStay(Collision collision)
    {
        //충돌을하는 중 호출되는 함수
    }

    private void OnCollisionExit(Collision collision)
    {
        //물리적 충돌이 끝났을 때 호출되는 함수
        if (collision.gameObject.name == "Sphere")
            mat.color = new Color(1, 1, 1);
    }
}

User가 움직이는 공 외에 나머지 6개의 공에 대한 이벤트를 주려고 한다. User Ball이 나머지 공에 부딪히는 순간은 공이 검정색으로 변하고 다시 떨어지면 흰색으로 변하는 효과이다.

    MeshRenderer mesh;
    Material mat;

    void Start()
    {
        mesh = GetComponent<MeshRenderer>();
        mat = mesh.material;
    }

Rigidbody와 비슷하게 여기서는 MeshRenderer 변수를 설정. 그리고 위와 같은 기본 설정을 한다.

oid OnCollisionEnter(Collision collision)
    {
        //물리적 충돌이 시작할때 호출되는 함수
        if (collision.gameObject.name == "Sphere")
            mat.color = new Color(0, 0, 0); //color : 기본색상 클래스, color32 : 255색상 클래스

    }

    private void OnCollisionStay(Collision collision)
    {
        //충돌을하는 중 호출되는 함수
    }

    private void OnCollisionExit(Collision collision)
    {
        //물리적 충돌이 끝났을 때 호출되는 함수
        if (collision.gameObject.name == "Sphere")
            mat.color = new Color(1, 1, 1);
    }

이벤트 실행 부분도 Rigidbody와 비슷하다.
OnCollisionEnter로 충돌이 시작할때 물질의 재질이 검정색으로 변하고, OnCollisionExit로 충돌이 끝날 때 색깔을 흰색으로 변하게 된다.

profile
늦게 출발했지만 꾸준히 달려서 도착지점에 무사히 도달하자

0개의 댓글