유니티 공부 .. Roll a ball 따라하며
unity 유니티 공부 2024. 10. 28. 14:45 |
roll a ball 이라는 튜토리얼을 함. urp 파이프라인 기준,
첫 씬을 만든 후
save as - Scene 폴더 만든 후 Minigame 이라고 이름 지어 저장 하면
이 지금 씬의 이름이 Minigame 이라고 지어짐
맨첨엔 암것도 없으니
하이어라키 메뉴 - 우클릭 - 3d object - 원하는 primitives 쉐잎을 생성
난 박스를 선택해서 바닥에 깔앗음
primitive 중 sphere 만든후 Player 라고 명명
이 강의에선 공이 주인공임
마테리알도 만들어보자. 드래그 해서 적용함.
surface inputs 의 base map 에서 색조절
player 에게 rigidbody 콤포넌트 추가
window - package manager - input system 깔기
키보드 입력 연관된 거라함
file- build profiles - x64 체크
visual script , unity 호환 설치
player 공에게 컴포넌트 player input 추
scripts 폴더추
player 에 콤포넌트 아래 new script
PlayerController
새 스크립트 만들었음 해당 폴더에 정리
+
코드에서
Void Start
처음에 딱 한번만 실행
초기화 작업때 사용
Void Update()
매 프레임(=틱, 1/60초) 마다 호출함
Update()는 불규칙하기 때문에 물리엔진에 부적합함
Void FixedUpdate()
고정된 시간 간격마다 호출.
물리연산(리지드바디)을 안정적이게 만듦
Void LateUpdate()
Update()가 호출된 후 마지막에 호출됨
주로 플레이어 따라다니는 카메라는 LateUpdate() 를 사용함
+
코드에서
using UnityEngine.InputSystem; 이라는 건
난 앞으로 UnityEngine.InputSystem
에서 있는 명령어들을 사용하겠다 라는 뜻이다
+
microsoft visual script 가 유니티랑 제대로 연결되었다면
코드 조금만 써도 자동완성기능 이 생김
→ 오른 화살표 키 를 누르면 자동으로 코드 완성해줌
+
괄호 영어로
소괄호 ( round bvracket
중괄호 { curly bracket
대괄호 [ square bracket
오타가 안 나게 항상 주의하자
오타가 없나 항상 체크하자
값을 직접 조절해야하는 것이면 public 으로 바깥공개
개발자가 굳이 값을 보지 않아도 되면 private
가속도 붙어서 움직이는(물리 법칙이 자연스러운) 공의 이동
을 구현한 코드는 아래와 같음
Z 축 점프는 뺀 거임
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour
{
public float speed = 3; //기본속도는 3으로 설정
private Rigidbody rb;
private float movementX;
private float movementY;
// Start is called once before the first execution
// of Update after the MonoBehaviour is created
void Start()
{
rb = GetComponent<Rigidbody>();
}
void OnMove(InputValue movementValue)
{
// function Body
Vector2 movementVector = movementValue.Get<Vector2>();
movementX = movementVector.x;
movementY = movementVector.y;
}
void FixedUpdate()
{
Vector3 movement = new Vector3(movementX, 0.0f, movementY);
rb.AddForce(movement * speed);
}
}
rotation x 45 로 하고 position y 10 정도 올린게 일반적인 카메라 뷰
플레이어 하이어라키 아래쪽으로 메인 카메라를 종속 시키면
아래와 같이
플레이어가 회전하면 카메라도 따라서 회전하는 문제가 있음
그래서 그냥 main camera 와 player 를 서로 child 안 시키기로 하고,
스크립트로 연결시키게 하기로 함
main camera 에 새 스크립트 CameraController 생성
스크립트를 스크립트 폴더로 옮겨 정리
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraController : MonoBehaviour
{
public GameObject player;
private Vector3 offset;
// Start는 첫 프레임 업데이트 이전에 호출됩니다.
void Start()
{
offset = transform.position - player.transform.position;
}
// Update는 프레임마다 한 번씩 호출됩니다.
void LateUpdate()
{
transform.position = player.transform.position + offset;
}
}
CameraController 스크립트를 위와 같이 씀
CameraController 의 Player 칸에 플레이어 드래그해서 지정
이러면 회전값은 반영 안되지만, 위치값은 플레이어를 따라다니는 카메라가 되버림
+
벽을 cube 로 만들고
empty 오브젝트 안에 west east north south 4개를 일일히 만듦. 일일히 손수 배치.
그 후 box collider , is trigger 체크안함 이 되어있나 확임
노란 큐브 생성 후 이름을 PickUp 생성
콜렉터블 오브젝트 만들거임
PickUp에게 Rotator 라는 새 스크립트를 만들고 적용시킴
using UnityEngine;
using System.Collections;
public class Rotator : MonoBehaviour
{
void Update()
{
// deltaTime 값을 곱하면 프레임이 아닌 초를 기준으로 회전함
transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
}
}
Translate 는 이동시킨다는 뜻
Rotate 는 회전시킨다는 뜻
Time.deltaTime은 부드러운 움직임을 위한 것
+
Prefabs 폴더를 만든후
노란 네모 PickUp을 드래그 해서 넣기
한번 프리팹 인스턴스가 되면
하이어라키 리스트 창에서 파란 네모 아이콘이 됨
인스턴스 옆 > 화살표를 클릭하면 해당 프리팹 수정 가능해짐
PickUp Parent 엠티오브젝트 생성후 transform reset
페어런트를 이렇게 PickUp을 아래에 속하게 하기
PlayerController cs 맨 아래에 저 줄을 추가한다
부딪치면, 대상을 사라지게하는 것임
prefabs 선택법
왼위 화살표 클릭 또는
아래 프로젝트 창 에서 클릭
add tag , + 버튼 클릭해 새 태그 추가
프리팹 선택으로 돌아가서.. tag 란에 내가 만든 ' PickUp ' 이라는 태그가 추가된걸 확인할 수 있음
아까 설정했던
private void OntriggerEnter Collider oher (부딪치는 물체를 사라지게 함)
에 PickUp tag 만 적용되게 하려면...
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("PickUp"))
{
other.gameObject.SetActive(false);
}
}
PalyerController cs 에서 위 코드를 설정하면
다른 오브젝트와 충돌이 발생시,
그 오브젝트의 태그가 PickUp 일시,
그 오브젝트를 비활성회 시키겠다
라는 뜻임
프리팹의 콜라이더 인스펙터에서 Is Trigger 를 활성화 시키자
그러면 노란 박스 프리팹 건드릴때마다 노란 박스 프리팹이 성공적으로 사라짐
노란박스 프리팹에 Rigidbody 추가.
Use gravity 끔
is kinematic 킴
+
공 수집 개수 체크하기
굳이 개발자가 일일히 설정하는 숫자가 아니라서 private 로 설정함
원리는 매 게임 시작할 때마다 0으로 시작함
노란박스 하나씩 수집할 때마다 1개씩 증가함
count 를 새로 지칭하고, count 가 처음엔 0 으로 시작하고, 충돌시마다 count 개수가 1씩 증가하도록 코드를 짬
하이어라키 메뉴 - 우클 - ui - text textmeshpro
import tmp essentials 클릭
그리고 x 버튼으로 그 자그만한 tmp 메 끄기
Text (TMP) 이름을 CountText 로 변경
화면 위 2D 뷰 토글
오른쪽 Text Input 안에 Count Text 라고 쓰기
저 빨간 네모칸을 누르면
anchor 기준을 변경 가능. 여기선 왼위를 기준으로 삼겠다
Player Controller sc 인스펙터
Count Text 에 Count Text 를 드래그
text mesh pro 하나 더 생성 후 이름변경 : WinText
vertex color 는 블랙으로 설정
Text input 칸엔 You Win! 라고 쓰기
PlayerController 스크립트 속
wintext를 알리는 유니티 고유 언어
public GameObject winTextObject;
라고 지정
wintext는 시작시 꺼짐상태임
void start 란에 winTextObject.SetActive(false); 를 넣음
void SetCountText 아래에
if 절을 추가함
if (count >= 8)
{
winTextObject.SetActive(true);
}
카운트 수가 8개가 되면 승리하도록 설정
(강의에서는 12개지만 난 8개로 설정)
win text object 에 win text 드래그
텍스트 표시까지 완료하면 아래와 같은 코드가 됨 :
using UnityEngine;
// Unity UI 및 Input System을 사용하는 데 필요한 네임스페이스를 포함합니다.
using UnityEngine.InputSystem;
using TMPro;
public class PlayerController : MonoBehaviour {
// 플레이어 속도 및 텍스트 UI 게임 오브젝트에 대한 public 변수를 만듭니다.
public float speed;
public TextMeshProUGUI countText;
public GameObject winTextObject;
private float movementX;
private float movementY;
private Rigidbody rb;
private int count;
// 게임을 시작할 때
void Start ()
{
// 리지드바디 컴포넌트를 private rb 변수에 할당합니다.
rb = GetComponent<Rigidbody>();
// count를 0으로 설정합니다.
count = 0;
SetCountText ();
// Win Text UI의 텍스트 프로퍼티를 빈 문자열로 설정하여 'You Win'(게임 오버 메시지)을 공백으로 만듭니다.
winTextObject.SetActive(false);
}
void FixedUpdate ()
{
// Vector3 변수를 만들고 X와 Z를 할당하여 위의 horizontal 및 vertical 플로트 변수를 구현합니다.
Vector3 movement = new Vector3 (movementX, 0.0f, movementY);
rb.AddForce (movement * speed);
}
void OnTriggerEnter(Collider other)
{
// 교차하는 게임 오브젝트에 'Pick Up' 태그가 할당되어 있는 경우
if (other.gameObject.CompareTag ("PickUp"))
{
other.gameObject.SetActive (false);
// 점수 변수 'count'에 1을 추가합니다.
count = count + 1;
// 'SetCountText()' 함수를 실행합니다(아래 참조).
SetCountText ();
}
}
void OnMove(InputValue value)
{
Vector2 v = value.Get<Vector2>();
movementX = v.x;
movementY = v.y;
}
void SetCountText()
{
countText.text = "Count: " + count.ToString();
if (count >= 12)
{
// 'winText'의 텍스트 값을 설정합니다.
winTextObject.SetActive(true);
}
}
}
노란 박스를 하나씩 먹으면 count 수가 하나씩 올라가다가..
8개 이상 이 되면
you win! 출력 됨
이제 게임이 왼성되었으면
녹화도 하고
build 하면 됨
빌드는 window, mac, ios 등 여러플랫폼으로 출판하는 걸 의미함
+
코파일럿 ai 응용하기
코드 복붙 후 , 원하는 프롬프트 넣으면 코드를 수정해줌
위 스샷처럼
카운트 수를 8 고정이 아니라,
인스펙터 창에서 내맘대로 수정 가능하게 만들 수 있음
코드 복붙후,
자연어 입력후,
코파일럿이 싸지른 거
스크립트 창에 복사 붙여넣기 하면 됨
문제는,
두리뭉실하게 말하지 말고
콕콕 찝어서 자세히 말을 해야함
그러려면 유니티 코딩관련 지식을 더 많이 알아야 함