[24.02.23]Unity - Rigidbody

손지·2024년 2월 26일
0

Unity

목록 보기
15/44

Rigidbody

스테이지, 카메라 프리팹을 가져오고 스피어를 만들어서 리지드바디를 넣습니다.
그리고 실행해서 낙하하는지 봅니다.


인스펙터창
Mass : 질량 ( scale 1,1,1 이 기준임) 이외엔 정교함이 떨어짐
Drag : 저항 (공기) 이외에 바람, 물 등을 구현할때 필요함
Angular Drag : 회전 저항 : 말 그대로 회전할때 받는 저항
Automatic Center of Mass : 저항의 기준
Automatic Tensor (관성)
Use Gravity : 중력 사용여부
is Kinematic(역기구학) : 외부에서 들어오는 물리의 힘을 받을지 말지 설정하는기능
On : 안밀림 / Off : 밀림 /// (갱비스트, 휴먼폴폴렛 : 액티브 래그돌 방식)

Interpolate(보간) : 게임의 프레임 속도가 물리 업데이트 속도보다 훨씬 높을 때 물리 개체의 움직임을 부드럽게 만드는 데 유용합니다. 예를 들어 레이싱 게임에서 보간을 사용하여 게임이 높은 프레임 속도로 실행되는 경우에도 자동차의 움직임이 더 부드럽게 보이도록 할 수 있습니다.
출처
Collision Detection : https://dev
eloper.mozilla.org/en-US/docs/Games/Techniques/3D_collision_detection
Constraints : 고정 : 위치값이나 회전값을 고정할때 사용하는 기능이다.
자료 : https://sdolnote.tistory.com/entry/KineticKinematic


Physic Material : Collider의 Material에 넣어서 씀
Friction : 마찰력
Dynamic Friction : 움직일때의 마찰력
Static Friction : 정적일때의 마찰력
Bounciness : 물체의 탄성
Friction Combine : 마찰력이 있는 물체들끼리 충돌처리
Bounce Combine : 탄성이 있는 물체들끼리 충돌처리

빈 오브젝트를 만들고 이름을 P_FPS_Character로 만들어줍니다

이런식으로 캐릭터처럼 배치를 잘 해준 다음에 스크립트를 만들어서 각각 부위에 넣어줍니다.

FPSArm.cs

private void Start()
{
    rotX = transform.localRotation.eulerAngles.x; // 시작할 때 현재 로컬 회전 각도를 가져옵니다.
}

// 팔을 회전시키는 함수
// _my: 마우스 Y 축 입력 값
// _sensitivity: 회전 감도(기본값은 5)
public void ArmRotate(float _my, float _sensitivity = 5f)
{
    rotX -= _my * _sensitivity; // 입력된 Y 축 값에 감도를 곱하여 회전 각도를 업데이트합니다.
    rotX = Mathf.Clamp(rotX, -45f, 60f); // 회전 각도를 제한합니다. 최소 -45도, 최대 60도로 설정합니다.

    // 제한된 회전 각도를 적용하여 팔을 회전시킵니다.
    transform.localRotation = Quaternion.Euler(rotX, 0f, 0f);
}

FPSBall.cs

private void Awake()
{
    rb = GetComponent<Rigidbody>(); // Rigidbody 컴포넌트를 가져옵니다.
    col = GetComponent<Collider>(); // Collider 컴포넌트를 가져옵니다.
}

private void Start()
{
    rb.useGravity = false; // 시작할 때 중력을 사용하지 않도록 설정합니다.
    rb.isKinematic = true; // 시작할 때 운동학적 상태를 true로 설정하여 외부 힘이 적용되지 않도록 합니다.
    col.enabled = false; // 시작할 때 Collider를 비활성화합니다.
}

// 공의 위치를 설정하는 함수
public void SetPosition(Vector3 _pos)
{
    transform.position = _pos; // 입력된 위치로 공의 위치를 설정합니다.
}

// 공을 부모 오브젝트에 붙이는 함수
public void AttachParent(Transform _parentTr)
{
    transform.SetParent(_parentTr); // 입력된 부모 Transform으로 공을 설정합니다.
}

// 공의 부모 오브젝트에서 분리하는 함수
public void DetachPerant()
{
    transform.SetParent(null); // 부모를 null로 설정하여 공을 분리합니다.
}

// 공의 크기를 힘에 따라 설정하는 함수
public void SetSizeWithPower(float _power)
{
    _power = Mathf.Clamp(_power, 0.1f, 1f); // 입력된 힘을 최소 0.1, 최대 1로 제한합니다.
    transform.localScale = Vector3.one * _power; // 입력된 힘에 따라 공의 크기를 조정합니다.
}

// 공을 발사하는 함수
public void Shoot(Vector3 _dir, float _power)
{
    rb.useGravity = true; // 중력을 사용하도록 설정합니다.
    rb.isKinematic = false; // 운동학적 상태를 false로 설정하여 외부 힘이 적용되도록 합니다.
    col.enabled = true; // Collider를 활성화합니다.
    rb.AddForce(_dir * _power * 10f, ForceMode.Impulse); // 입력된 방향과 힘을 기반으로 공을 발사합니다.

    Destroy(gameObject, 5f); // 5초 후에 공을 파괴합니다.
}

FPSCharacter.cs

private float senstivity = 5f; // 마우스 감도
private float moveSpeed = 10f; // 이동 속도
private float rotY = 0f; // 캐릭터의 Y 축 회전 각도

private void Awake()
{
    rb = GetComponent<Rigidbody>(); // Rigidbody 컴포넌트를 가져옵니다.
    head = GetComponentInChildren<FPSHead>(); // 자식 오브젝트에서 FPSHead 컴포넌트를 가져옵니다.
    arm = GetComponentInChildren<FPSArm>(); // 자식 오브젝트에서 FPSArm 컴포넌트를 가져옵니다.
    gun = GetComponentInChildren<FPSGun>(); // 자식 오브젝트에서 FPSGun 컴포넌트를 가져옵니다.

    rotY = transform.rotation.y; // 시작할 때 캐릭터의 Y 축 회전 각도를 초기화합니다.

    Cursor.lockState = CursorLockMode.Locked; // 커서 고정 설정
    Cursor.visible = false; // 커서를 보이지 않도록 설정
}

private void Update()
{
    // 키보드 입력 처리
    float h = Input.GetAxis("Horizontal"); // 좌우 이동 입력
    float v = Input.GetAxis("Vertical"); // 전후 이동 입력
    MovingProcess(h, v);

    // 마우스 입력 처리
    float mx = Input.GetAxis("Mouse X"); // 마우스 X 축 입력
    float my = Input.GetAxis("Mouse Y"); // 마우스 Y 축 입력
    head.HeadRotate(mx, my, senstivity); // 머리 회전 처리
    arm.ArmRotate(my, senstivity); // 팔 회전 처리
    Turn(mx); // 캐릭터 회전 처리

    // 마우스 클릭 입력 처리
    if (Input.GetMouseButton(0)) // 마우스 좌클릭이 눌렸는지 확인
    {
        gun.HoldTrigger(); // 총을 일반 발사 상태로 전환
    }
    if (Input.GetMouseButtonUp(0)) // 마우스 좌클릭이 해제되었는지 확인
    {
        gun.Fire(); // 총 발사
    }
}

// 캐릭터 이동 처리 함수
private void MovingProcess(float _h, float _v)
{
    Vector3 forward = transform.forward * _v; // 전진 방향 벡터 계산
    Vector3 right = transform.right * _h; // 우측 이동 방향 벡터 계산
    Vector3 dir = forward + right; // 이동 방향 벡터 계산
    dir.Normalize(); // 이동 방향 벡터를 정규화합니다.
    rb.velocity = dir * moveSpeed; // Rigidbody의 속도를 이동 방향에 맞게 설정합니다.
}

// 캐릭터 회전 처리 함수
private void Turn(float _mx)
{
    rotY += _mx * senstivity; // Y 축 회전 각도를 마우스 X 축 입력과 감도를 곱하여 업데이트합니다.
    transform.rotation = Quaternion.Euler(0f, rotY, 0f); // 회전 각도를 적용하여 캐릭터를 회전시킵니다.
}

FPSSpawnPoint.cs

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

public class FPSSpawnPoint : MonoBehaviour
{
    public Vector3 GetPosition()
    {
        return transform.position;
    }
}

FPSGun.cs

private void Awake()
{
    spawnPoint = GetComponentInChildren<FPSSpawnPoint>(); // 자식 오브젝트에서 FPSSpawnPoint 컴포넌트를 가져옵니다.
}

// 공을 생성하고 발사 위치와 부모를 설정하는 함수
private void SpawnBall()
{
    GameObject go = Instantiate(projectilePrefab) as GameObject; // 프로젝타일 프리팹을 복제하여 공을 생성합니다.

    ball = go.GetComponent<FPSBall>(); // 공의 FPSBall 컴포넌트를 가져옵니다.
    ball.SetPosition(spawnPoint.GetPosition()); // 발사 위치를 설정합니다.
    ball.AttachParent(transform); // 총의 위치를 부모로 설정합니다.
}

// 발사 트리거를 누르고 있는 동안 호출되는 함수
public void HoldTrigger()
{
    if (ball == null) // 발사된 공이 없을 때
    {
        SpawnBall(); // 공을 생성합니다.
    }
    shootPower += Time.deltaTime; // 발사 파워를 시간에 따라 증가시킵니다.
    shootPower = Mathf.Clamp(shootPower, 0.1f, 5f); // 발사 파워를 최소 0.1, 최대 5로 제한합니다.
    ball.SetSizeWithPower(shootPower); // 발사된 공의 크기를 발사 파워에 따라 조정합니다.
}

// 발사 트리거를 놓았을 때 호출되는 함수
public void Fire()
{
    ball.DetachPerant(); // 공의 부모를 제거하여 캐릭터와 독립시킵니다.
    ball.Shoot(transform.forward, shootPower); // 공을 발사합니다. 방향은 총의 정면 방향으로 설정되며, 발사 파워를 적용합니다.

    ball = null; // 발사된 공을 null로 초기화합니다.
    shootPower = 0f; // 발사 파워를 초기화합니다.
}

FPSHead.cs

private void Start()
{
    rot = transform.localRotation.eulerAngles; // 시작할 때 현재 로컬 회전 각도를 가져옵니다.
}

// 마우스 X 및 Y 입력에 따라 머리를 회전시키는 함수
// _mx: 마우스 X 축 입력 값
// _my: 마우스 Y 축 입력 값
// _senstivity: 회전 감도(기본값은 5)
public void HeadRotate(float _mx, float _my, float _senstivity = 5f)
{
    // 머리의 회전 각도를 입력된 마우스 Y 축 값에 감도를 곱하여 업데이트합니다.
    rot.x -= _my * _senstivity;
    rot.x = Mathf.Clamp(rot.x, -45f, 45f); // 회전 각도를 최소 -45도, 최대 45도로 제한합니다.

    // 새로운 회전 각도를 적용하여 머리를 회전시킵니다.
    transform.localRotation = Quaternion.Euler(rot);
}
profile
게임 개발자가 될사람

0개의 댓글