유니티에서 오브젝트에 이동 구현 스크립트를 적용하려면 Transform 컴포넌트 설정이 필요하고,
점프 구현 스크립트를 적용하려면 Rigidbody 컴포넌트를 추가하여 설정해야 한다.
따라서 오브젝트에 이동과 점프 둘 다 구현을 하려면 Transform과 Rigidbody 컴포넌트 둘 다 필요하다.
(이동과 점프 구현 스크립트는 아래 참고)
이동 구현 스크립크 : https://greenchoco.tistory.com/223
점프 구현 스크립트 : https://greenchoco.tistory.com/227
위의 스크립트를 참고하여 이동과 점프 둘 다 구현된 스크립트는 아래와 같다.
- 플레이어는 캡슐 오브젝트로 이름은 player이다.
- player오브젝트에는 rigidbody컴포넌트를 추가하고 constraints - freeze rotation x, y, z를 체크했다. (그래야 안쓰러짐)
- plane 오브젝트를 추가한 뒤 Ground 라는 이름으로 tag를 해주었다.
- 장애물 오브젝트로 큐브 오브젝트를 추가해주었다.
using System.Collections;
using System.Collections.Generic;
using UnityEditor.Rendering;
using UnityEngine;
public class Player : MonoBehaviour
{
public float moveSpeed; // 이동구현 - 속도
public float jumpPower; // 점프구현 - 점프하는 힘
int jumpCount; // 점프구현 - 점프 횟수
Rigidbody rb; // 점프구현 - rigid에 이름짓기
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>(); // 점프구현 - 오브젝트의 rigid 가져와서 저장
}
void Update()
{
float h = Input.GetAxis("Horizontal"); // 이동구현 - 수평
float v = Input.GetAxis("Vertical"); // 이동구현 - 수직
Vector3 dir = new Vector3 (h, 0, v); // 이동구현 - 이동 정규화를 위한 dir 선언
dir.Normalize(); // 이동구현 - dir의 이동 정규화
transform.position += dir * moveSpeed * Time.deltaTime; // 이동구현 - 이동함수에 dir 적용
if(Input.GetKeyDown(KeyCode.Space) && jumpCount<2) // 점프구현 - 만약 스페이스파를 누르면 / 2번 미만일 때
{
rb.AddForce(Vector3.up * jumpPower, ForceMode.Impulse); // 점프구현 - 위로 순간적인 힘이 발생
jumpCount++; // 점프구현 - 점프시 1씩 추가한다.
}
}
private void OnCollisionEnter(Collision collision) // 점프구현 - 충돌 시작하면 호출
{
if (collision.gameObject.tag == "Ground") // 점프구현 - 충돌한 물체의 tag가 Ground 일 때
{
jumpCount = 0; // 점프구현 - 점프 횟수를 초기화한다.
}
}
}
이렇게 작성했을 때 플에이어 오브젝트는 안정적으로 움직인다.
하지만 방애물이 발생하였을 때 충돌처리방식에 따라 rigidbody 컴포넌트는 더이상 움직이지 못한다고 판단하지만, transform 는 이동 기능에 따라 position 값이 계속 변하려고 하게 된다.
그 결과 장애물이 발생했을 때 아래 플레이어가 흔들거리는 현상이 나타난다.
이를 해결하기 위해서는 MovePosition 이라는 함수를 이용하면 된다.
이는 물리 작용을 활용해 위치 정보를 계산하는 함수로, Vector3 값을 인수로 지정할 수 있다.
즉 위 스크립트에서
transform.position += dir * moveSpeed * Time.deltaTime; 이 부분을
rb.MovePosition(rb.position +(dir * moveSpeed * Time.deltaTime)); 으로 수정하면 된다.
그럼 플레이어는 흔들리지 않고 잘 움직인다.
참고로 설치한 장애물이 untagged 상태면 장애물에 올라간 플레이어는 점프할 수 없다.
위 스크립트에서 Ground 이름이 tag된 오브젝트랑 충돌할 때 발생한다고 적어두었기 때문이다.
따라서 장애물 위에서도 점프를 하기 위해서는 장애물 오브젝트 인스펙터에서 untagged를 Ground로 바꿔주면 된다
따라서 최종 결과물은 아래와 같다.
'유니티 C# > C#' 카테고리의 다른 글
C#기초 - 스페이스바 점프 구현하기 (Getkey, Addforce함수) (0) | 2024.04.30 |
---|---|
C#기초 - isTrigger에 따른 OnCollision함수와 OnTrigger함수 (0) | 2024.04.30 |
C#기초 - Addforce함수와 ForceMode 종류 (0) | 2024.04.30 |
C#기초 - 방향키로 이동하기 (Input Manager, GetAxis, Vector3) (0) | 2024.04.29 |
C#기초 - 이동 함수와 인수 종류 (키보드, 마우스, 모바일) (1) | 2024.04.26 |
댓글