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을 안 쓰면 오류남)
쏘면 이렇게 됨
수박 겉 핥듯이 보고 갑니다