유니티 공부.. 골드메탈님 공 튜토 되돌아보기
unity 유니티 공부 2024. 11. 18. 17:22 |
public float jumpPower;
라고 스크립트 상단에 쓰면
인스펙터 창에서 언제든지 값을 조정 가능해짐
using UnityEngine;
public class PlayerBall : MonoBehaviour
{
public float jumpPower;
bool isJump;
Rigidbody rigid;
void Awake()
{
isJump = false;
rigid = GetComponent<Rigidbody>();
}
private void Update()
{
if(Input.GetButtonDown("Jump")
&& !isJump)
{
rigid.AddForce(
new Vector3(0, jumpPower, 0),
ForceMode.Impulse);
isJump = true;
}
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.name == "Floor")
isJump = false;
}
}
플레이어의 2단 점프 방지하기
무한 점프 방지하기
한번 점프시 점프를 불가능하게 만듦
(isJump 가 트루)
바닥(Ground) 오브젝트에 닿으면
점프가 다시 가능하게 만듦 (isJump 가 팔스)
+
바닥은 name 이 아니라 tag 로 하고 싶으면
if (collision.gameObject.tag == "Floor")
+
회전축은 크게 두가지임
self 자기 자신 중심 기준
world. 전체 월드 기준
self | world |
self 로 회전시켰는데 , 회전하는 티가 안 나서 world 로 바꿈
+
name == Item 설정했는데
if (other.name == "Item")
위 스샷처럼 복붙하면 이름이 달라져버려서 스크립트 작동 안되는 경우가 있음
그래서 name 보다는 tag 를 쓰는 거임
태그 하나 만든 후
오브젝트 인스펙터 창에서 태그 지정한 후
스크립트 창에서
if (other.tag == "Item")
이렇게 변경 한다
+
Copilot ai 챗봇에게 물어봐서 만든
추락 방지 오브젝트 만드는 법
저 아래에 넙적한 회색 네모에 닿으면
플레이어의 위치를 0 0 0 으로 이동시켜줌
using UnityEngine;
public class TeleportPlayer : MonoBehaviour
{
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
// 플레이어 위치를 (0, 0, 0)으로 순간이동
other.transform.position
= new Vector3(0, 0, 0);
Debug.Log("플레이어가 순간이동되었습니다!");
}
}
}
+
궁금증 하나 더 생김
나중에 rpg 게임 만들다보면 Tag 가 아주 많아질텐데 이건 문제가 안될까?
에 대한 챗봇 답변
많은 태그는 분류가 힘들어지는 문제, 퍼포먼스 저하가 있다
태그가 아니라 커스텀 데이터 스크립트를 이용해라
예시 :
public enum MonsterSize { Small, Medium, Large }
public class Monster : MonoBehaviour
{
public MonsterSize size;
}
+
주로 쓰는 태그는 다음과 같음
캐릭터 유형: Player, Enemy, Ally
상호작용 가능한 오브젝트: Item, Pickup, Door
게임 오브젝트 타입: Projectile, Obstacle
+
GameManager
= 형태가 없고 전반적인 걸 관리하는 것
+
스크립트 Find 함수는 CPU 소모가 크니까 쓸 때 주의 할 것
+
using UnityEngine;
using UnityEngine.SceneManagement;
public class PlayerBall : MonoBehaviour
{
AudioSource audio;
public float jumpPower;
public int itemCount;
public GameManagerLogic manager;
bool isJump;
Rigidbody rigid;
void OnTriggerEnter(Collider other)
{
if (other.tag == "Item")
{
itemCount++;
audio.Play();
other.gameObject.SetActive(false);
}
else if (other.tag == "finish")
{
if (itemCount == manager.totalItemCount)
{
// Game Clear
}
else {
//Restart
SceneManager.LoadScene("SampleScene");
}
아이템 카운트를 다 못 모으고 결승전 피니쉬 라인에 다다른다면
씬을 다시 불러와서 초기화 한다는 뜻
+
else if (other.tag == "finish")
{
if (itemCount >= manager.totalItemCount)
{
// to next stage
SceneManager.LoadScene("Example_2");
}
else {
//Restart scene
SceneManager.LoadScene("SampleScene");
}
}
요렇게 하면
아이템 일정 개수 이상 모으면 다음 스테이지로
못 모으면 처음부터 초기화 해서 다시 라는 뜻
+
SceneManager.LoadScene
은 잘만 사용하면
나중에 시간 마법. 처음으로 되돌리기 마법을 구현할 수 있을듯
+
쓰는 씬은 꼭
file - build profiles 에
add open scenes 를 넣어주자
안그럼 에러남
+
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class GameManagerLogic : MonoBehaviour
{
public int totalItemCount;
public int stage;
public Text stageCountText;
public Text playerCountText;
void Awake()
{
stageCountText.text = "/ " + totalItemCount;
}
public void GetItem(int count)
{
playerCountText.text = count.ToString();
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
SceneManager.LoadScene(stage);
}
}
↑ 게임 메니저 로직 스크립트
using UnityEngine;
using UnityEngine.SceneManagement;
public class PlayerBall : MonoBehaviour
{
AudioSource audio;
public float jumpPower;
public int itemCount;
public GameManagerLogic manager;
bool isJump;
Rigidbody rigid;
void Awake()
{
isJump = false;
rigid = GetComponent<Rigidbody>();
audio = GetComponent<AudioSource>();
}
private void Update()
{
if(Input.GetButtonDown("Jump")
&& !isJump)
{
rigid.AddForce(
new Vector3(0, jumpPower, 0),
ForceMode.Impulse);
isJump = true;
}
}
void FixedUpdate()
{
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
rigid.AddForce(
new Vector3(h, 0, v), // y axis is for jump
ForceMode.Impulse);
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Floor")
isJump = false;
}
void OnTriggerEnter(Collider other)
{
if (other.tag == "Item")
{
itemCount++;
audio.Play();
other.gameObject.SetActive(false);
manager.GetItem(itemCount);
}
else if (other.tag == "finish")
{
if (itemCount >= manager.totalItemCount)
{
// to next stage
SceneManager.LoadScene("Example_2");
}
else {
//Restart scene
SceneManager.LoadScene("SampleScene");
}
}
}
}
↑ 플레이어 스크립트
길어서 복잡하겠지만
플레이어의 void OnTriggerEnter(Collider other) { if (other.tag == "Item") { itemCount++; audio.Play(); other.gameObject.SetActive(false); manager.GetItem(itemCount); } |
게임메니저 로직의 public Text stageCountText; public Text playerCountText; void Awake() { stageCountText.text = "/ " + totalItemCount; } public void GetItem(int count) { playerCountText.text = count.ToString(); } |
위 두개가 연관 있다~
정도만 알아두자
ui 상에선 저렇게 표기
/ 0 로 표기 | 0 으로 표기 |
Player Item Text | Stage Item Text |
+
컴포넌트 창에서 텍스트 드래그 하려면
TMP_Text 로 되어야 함
TMP_Text 가 아니라 Text 로 하면 안댐
+
씬 0 에서 만든 ui canvas 는
그냥 단순 복붙해서
씬1, 씬2 ... 에서 사용함
+
다 만들면 이런 게임이 됨 :
아이템 다 먹으면
다음 스테이지로 갈 수 있음
스테이지 두번째부턴 미구현