[멋쟁이사자처럼 부트캠프 TIL] 멋쟁이사자처럼 유니티게임스쿨 7일차

굥지·2024년 10월 10일
0

Slope Limit : 올라갈수 있는 경사로의 한계

Step Offset : 올라갈 수 있는 계단의 단차 등을 설정할 수 있다

중력

public class PlayerController : MonoBehaviour
{
    public float WalkSpeed = 7;
    public float mouseSens = 1;
    public Transform cameraTransform; 

    public float gravity = 10;
    public float terminalSpeed = 20; //떨어지는 물체가 최대 속도를 유지하게

    float horizontalAngle;
    float verticalAngle;
    float verticalSpeed; //낙하 속력

    InputAction moveAction;
    InputAction lookAction;

    CharacterController characterController;
    
    ...생략
    void Update(){
        //중력
        verticalSpeed -=  gravity * Time.deltaTime; 
        //gravity값에 타임을 곱해 verticalSpeed를 뺴주면 점점 더 빠르게 아래로 떨어짐
        
        if(verticalSpeed < -terminalSpeed) 
        //verticalSpeed가 최대 낙하속도(terminalSpeed)를 넘어가면 **-**최대 낙하속도로 고정
        {
            verticalSpeed = -terminalSpeed;
        }
        Vector3 verticalMove = new Vector3(0, verticalSpeed, 0); //떨어지는 Vector 생성 
        verticalMove *= Time.deltaTime; //Vector에 deltaTime 적용

        CollisionFlags flag = characterController.Move(verticalMove); //캐릭터에게 중력속도 적용
        
        if ((flag & (CollisionFlags.Below | CollisionFlags.Above)) !=0) 
        //flag중에 Bellow 비트가 없으면 / 떨어지는 상태가 아니면(바닥에 땅을 디딛고 있냐)
        {
            verticalSpeed = 0; //하강속도를 0으로 초기화
        }
     }

땅에 붙어있는지 0.5초 뒤에 인지하도록

public class PlayerController : MonoBehaviour
{
    public float WalkSpeed = 7;
    public float mouseSens = 1;
    public Transform cameraTransform;

    public float gravity = 10;
    public float terminalSpeed = 20; //떨어지는 물체가 최대 속도를 유지하게

    float horizontalAngle;
    float verticalAngle;
    float verticalSpeed; //낙하 속력
    bool isGrounded;
    float groundedTimer;

    InputAction moveAction;
    InputAction lookAction;

    CharacterController characterController;

    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked; //게임화면 내 커서 잠금       
        Cursor.visible = false; //커서 숨기기

        InputActionAsset inputActions = GetComponent<PlayerInput>().actions;
        moveAction = inputActions.FindAction("Move"); //Move에 해당하는 입력값 가져오기
        lookAction = inputActions.FindAction("Look");

        characterController = GetComponent<CharacterController>();

        horizontalAngle = transform.localEulerAngles.y; //바라보는 각도에 얼마나 돌아야하는지 세팅
        verticalAngle = 0;
        verticalSpeed = 0;
        isGrounded = true;
        groundedTimer = 0;
    }
    
   void Update()
   {  
        Vector3 verticalMove = new Vector3(0, verticalSpeed, 0); //떨어지는 Vector 생성 
        verticalMove *= Time.deltaTime; //Vector에 deltaTime 적용

        CollisionFlags flag = characterController.Move(verticalMove); //캐릭터에게 중력속도 적용
        
        if ((flag & CollisionFlags.Below) !=0)
         //flag중에 Bellow 비트가 없으면 / 떨어지는 상태가 아니면(바닥에 땅을 디딛고 있냐)
        {
            verticalSpeed = 0; //하강속도를 0으로 초기화
        }
        if(!characterController.isGrounded) //characterController가 땅에 안 붙어있다고함
        { 
            if(isGrounded) //안 붙어있다면
            {
                groundedTimer += Time.deltaTime; //timer를 움직이게하고
                if(groundedTimer > 0.3f) //0.5초뒤에
                {
                    isGrounded = false; //false로
                }
            }
        }
        else //땅에 붙어있다면
        { 
            isGrounded = true; //true
            groundedTimer = 0;
        }
   }

점프

뉴인풋시스템에 있는 Jump를 사용하기 위해 OnJump()함수 사용

void OnJump()
{
    if(isGrounded)
    {
        verticalSpeed = jumpSpeed;
        isGrounded = false; //무한점프 방지
    }
}

총만들기

총 에셋 가져오기

애니메이션 생성

재장전 애니메이션은 Mag와 Mag_Full을 사용

애니메이션 연결

저 이름으로 할거면 스크립트도 저 이름으로 해야댐

발사할땐 Has Exit TIme없이(바로 애니메이션이 실행될 수 있도록)

Trigger 설정


Idle로 돌아올땐(애니메이션이 다 끝나고) Has Exit TIme 체크

인풋 이름 바꿔서

InputAction fireAction;

    void Start()
    {
        
        fireAction = inputActions.FindAction("Fire");
    }
    void Updat()
    {
    
        if (fireAction.WasPressedThisFrame())
        {

            weapon.FireWeapon();
        }
    }

이렇게 갖다 쓸 수 있다.

public class Weapon : MonoBehaviour
{
    }
    public void FireWeapon()
    {
        Debug.Log("Fire");
    }
    public void ReloadWeapon()
    {

    }
}

Player Input 컴포넌트를 보면 아래 저 함수들을 사용할 수 있다고 보여줌

public class PlayerController : MonoBehaviour
{
   void Update()
		{
        if (fireAction.WasPressedThisFrame())
        {
            weapon.FireWeapon();
        }
        if (reloadAction.WasPressedThisFrame()) //이번 프레임에 눌렸는가
        {
            weapon.ReloadWeapon();
        }
    } 
 }
public class Weapon : MonoBehaviour
{
    Animator animator;
    void Start()
    {
        animator = GetComponent<Animator>();
    }
    public void FireWeapon()
    {
        if (animator.GetCurrentAnimatorStateInfo(0).IsName("Idle"))
        {
            animator.SetTrigger("Fire");
        }
    }
    public void ReloadWeapon()
    {
        if (animator.GetCurrentAnimatorStateInfo(0).IsName("Idle"))
        {
            animator.SetTrigger("Reload");
        }
    }
}

인풋시스템 수동 추가

없는건 이렇게 만들 수 있음

조준선



이렇게 추가 된 모습

총구 위치 추가

빈 오브젝트를 총구 앞으로 설정

Effect - Line 추가

TrailPrefab으로 이름을 바꿔주고 프리팹으로 만들어줌

0,0,0으로 설정

using UnityEngine;

public class Weapon : MonoBehaviour
{
    public GameObject trailPrefab;
    public Transform firingPosition;

    Animator animator;
    void Start()
    {
        animator = GetComponent<Animator>();
    }

    void Update()
    {

    }
    public void FireWeapon()
    {
        if (animator.GetCurrentAnimatorStateInfo(0).IsName("Idle"))
        {
            animator.SetTrigger("Fire");
            RayCastFire();
        }
    }
    public void ReloadWeapon()
    {
        if (animator.GetCurrentAnimatorStateInfo(0).IsName("Idle"))
        {
            animator.SetTrigger("Reload");
        }
    }

    void RayCastFire()
    {
        Camera cam = Camera.main;

        RaycastHit hit;
        Ray r = cam.ViewportPointToRay(Vector3.one / 2); //카메라 정 중앙으로 발사

        Vector3 hitPosition = r.origin + r.direction * 200; //아무곳에도 부딪히지 않았다면 카메라 방향에서 200정도 떨어져있는 곳

        if(Physics.Raycast(r, out hit, 1000)) //어딘가에 빛이 부딪혔으면 true
        { //레이 r의 정보를 가지고 1000의 최대거리 만큼 레이를 쏜다. out : 변수를 넣었을때 변수가 변할 수 있다는 것(out을 안 쓰면 오류남)
            hitPosition = hit.point; //빛이 부딪힌 부분이 총알의 종착점
        }

        GameObject go = Instantiate(trailPrefab);
        Vector3[] pos = new Vector3[] { firingPosition.position, hitPosition };
        go.GetComponent<LineRenderer>().SetPositions(pos);
    }
}

Physics.Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance) :
시작점(Origin)과 방향(Direction)으로 최대거리(maxDistance)만큼 레이를 쏘는 함수입니다. 최대거리 안에서 충돌이 되면 true를 반환하고 RaycastHit로 충돌정보를 넘겨줍니다.

Physics.Raycast(r, out hit, 1000) :
레이 r의 정보를 가지고 1000의 최대거리 만큼 레이를 쏜다. out : 변수를 넣었을때 변수가 변할 수 있다는 것(out을 안 쓰면 오류남)

쏘면 이렇게 됨

1개의 댓글

comment-user-thumbnail
2024년 10월 12일

수박 겉 핥듯이 보고 갑니다

답글 달기

관련 채용 정보