728x90
✏️이 글은 나도 코딩님의 유니티 무료 강의 5시간 게임 개발 속성 강의를 듣고 내용을 정리한 것입니다. 유니티를 처음 공부하시는 분들이 보기에 좋은 강의라서 추천드려요!
✏️실습을 하면서 기록한 것이라서 내용이 들쭉날쭉할 수 있습니다
출처 🔽
https://www.youtube.com/watch?v=rJE6bhVUNhk&t=9529s
👉적 만들기
더보기





장애물 아이템 크기 28 픽셸로 설정
- Enemy는 바깥쪽에서 밑으로 쭉 떨어지는 동작을 정의하면 된다.
- 또한 떨어진 오브젝트는 화면상에서 제거해줘야한다
✏️코드 작성
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
[SerializeField]
private float moveSpeed =10f;
private float minY=-7;
// Update is called once per frame
void Update()
{
transform.position += Vector3.down * moveSpeed * Time.deltaTime;
if(transform.position.y<minY){
Destroy(gameObject);
}// 화면상에 사라졌을 때 오브젝트 제거
}
}
💠중간 점검 및 설정

- Box Colider 2d를 추가해준 다음 영역을 설정해준다.
- 태그도 새롭게 Enemy를 추가해준다
- Rigidbody 2d를 추가해준다 (충돌 처리를 위해서 )
💠Box Collider 설정

- Is Trigger 가 체크되지 않으면 물리법칙이 적용되기 때문에 장애물과 플레이어가 서로를 밀어낸다
- Is Trigger가 체크되어 있으면 물리법칙이 적용되지 않기 때문에 밀어내지 않게 된다.

- Prefabs에서 여러가지 장애물을 설정한다
- 각 장애물마다 충돌 범위를 설정해준다 (Edit Collider를 통해서 충돌 범위 조절)
👉랜덤으로 적 만들기
더보기
💠랜덤으로 적 만들기
- 화면상에 랜덤으로 적이 나오게 설정
- 장애물 7개 중에서 5개를 랜덤으로 설정하는 스크립트 작성
✏️코드 작성
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
[SerializeField]
private GameObject[] enemies;
private float[] arrPosX = {-2.2f,-1.1f,0f,1,1f,2.2f};
// Start is called before the first frame update
void Start()
{
foreach( float posX in arrPosX){ // 배열의 값을 꺼내서 posX에 저장
int index = Random.Range(0,enemies.Length);
SpawEnemy(posX,index);
}
}
void SpawEnemy(float posX, int index){
Vector3 spawnPos = new Vector3(posX, transform.position.y,transform.position.z);
Instantiate(enemies[index], spawnPos, Quaternion.identity);
}
}
👉적 무한 생성하기
더보기
💠 적 무한 생성 하기
- 적을 무한으로 생성하기 위해서 스폰 코드를 작성해준다
✏️코드 작성
EnemySpawner.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
[SerializeField]
private GameObject[] enemies;
private float[] arrPosX = {-2.2f, -1.1f, 0f , 1.1f, 2.2f};
[SerializeField]
private float spawnInterval = 1.5f;
void Start()
{
StartEnemyRoutine();
}
void StartEnemyRoutine(){
StartCoroutine("EnemyRoutine");
}
IEnumerator EnemyRoutine(){
yield return new WaitForSeconds(3f);// 3초간 대기 후에 밑에 코드 실행
int enemyIndex= 0;
int spawnCount=0;
while(true){
for (int i = 0; i < 5; i++) {
SpawEnemy(arrPosX[i], enemyIndex); // 선택된 위치에 장애물 생성
}
spawnCount +=1;
if(spawnCount %10==0){
enemyIndex +=1;
}
yield return new WaitForSeconds(spawnInterval);// 1.5초 기다렸다가 반복
}//무한 반복
}
void SpawEnemy(float posX, int index){
Vector3 spawnPos = new Vector3(posX, transform.position.y,transform.position.z);
if(Random.Range(0,5)==0){
index +=1;
}// 0~4사이 숫자 (20%확률)
if(index>=enemies.Length){
index = enemies.Length-1;
}
Instantiate(enemies[index], spawnPos, Quaternion.identity);
}
}
Enemy.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
[SerializeField]
private float moveSpeed =10f;
private float minY=-7;
// Update is called once per frame
public void SetMoveSpeed(float moveSpeed){
this.moveSpeed = moveSpeed; // this는 현재 객체
}
void Update()
{
transform.position += Vector3.down * moveSpeed * Time.deltaTime;
if(transform.position.y<minY){
Destroy(gameObject);
}// 화면상에 사라졌을 때 오브젝트 제거
}
}
👉충돌처리
더보기
💠 충돌 처리
- 물체 충돌 처리를 하기 위해서 코드를 수정해준다
✏️코드 작성
Enemy.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
[SerializeField]
private float moveSpeed =10f;
private float minY=-7f;
[SerializeField]
private float hp = 1f;
// Update is called once per frame
public void SetMoveSpeed(float moveSpeed){
this.moveSpeed = moveSpeed; // this는 현재 객체
}
void Update()
{
transform.position += Vector3.down * moveSpeed * Time.deltaTime;
if(transform.position.y<minY){
Destroy(gameObject);
}// 화면상에 사라졌을 때 오브젝트 제거
}
private void OnTriggerEnter2D(Collider2D other) {
if(other.gameObject.tag == "Weapon"){
Weapon weapon = other.gameObject.GetComponent<Weapon>(); //충돌한 대상이 weapon일 때만 충돌한 대상의 gameObject로 부터 weapon을 가져옴
hp -= weapon.damage;
if(hp<=0){
Destroy(gameObject);
}
Destroy(other.gameObject);
}
}
}
player.cs
using System.Collections;
using System.Collections.Generic;
using Unity.Collections;
using UnityEngine;
public class Player : MonoBehaviour
{ [SerializeField] //유니티 상에서 값을 넣어줄 수 있게함
private float moveSpeed;
[SerializeField]
private GameObject weapon;
[SerializeField]
private Transform shootTransform; //플레이어 머리 위에서 발사되는 예측값
[SerializeField]
private float shootInterval = 0.05f; //미사일을 쏘는 간격
private float lastShotTime =0f;
void Update() {
Vector3 mousePos =Camera.main.ScreenToWorldPoint(Input.mousePosition);
float toX = Mathf.Clamp(mousePos.x,-2.35f,2.35f);
transform.position = new Vector3(toX,transform.position.y,transform.position.z);
Shoot();
}
void Shoot(){
if(Time.time-lastShotTime>shootInterval){
Instantiate(weapon,shootTransform.position,Quaternion.identity); //게임 오브젝트를 만드는 메소드
lastShotTime =Time.time;//현재 시간으로 업데이트
} //Time.time 게임이 시작된 이후로 현재까지 흐른 시간
}
private void OnTriggerEnter2D(Collider2D other) {
if(other.gameObject.tag == "Enemy"){
Debug.Log("GAME OVER");
Destroy(gameObject);
}
}
}
👉코인 만들기
더보기


- Coin 오브젝트 애니메이션으로 만든 후 Prefabs에 등록하기 (isTrigger 설정도 해주기)
✏️코드 작성
Coin.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Coin : MonoBehaviour
{
private float minY=-7f;
// Start is called before the first frame update
void Start()
{
Jump();
}
void Jump(){
Rigidbody2D rigidBody=GetComponent<Rigidbody2D>();
float randomJumpForce = Random.Range(4f, 8f);
Vector2 jumpVelocity = Vector2.up * randomJumpForce;
jumpVelocity.x = Random.Range(-2f,2f);
rigidBody.AddForce(jumpVelocity,ForceMode2D.Impulse);
}
// Update is called once per frame
void Update()
{
if(transform.position.y<minY){
Destroy(gameObject);
}// 화면상에 사라졌을 때 오브젝트 제거
}
}
private void OnTriggerEnter2D(Collider2D other) {
if(other.gameObject.tag == "Enemy"){
Debug.Log("GAME OVER");
Destroy(gameObject);
}else if (other.gameObject.tag=="Coin"){
Debug.Log("Coin+1");
Destroy(other.gameObject);
}
}
👉점수 출력
더보기





- 점수는 먹고 있는 코인 개수로 설정
- 점수 패널을 새롭게 추가해준다

- ScorePanel에 이미지와 텍스트를 지정해준다

- Wrapping 설정은 Disabled로 설정

- GameManger 오브젝트 생성 후 스크립트 작성
- Text 부분에 Text(TMP)를 집어 넣는다
✏️코드 작성
GameManger.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class GameManager : MonoBehaviour
{
public static GameManager instance = null;
[SerializeField]
private TextMeshProUGUI text;
private int coin = 0;
void Awake(){
if(instance == null){
instance = this;
}
}
public void IncreaseCoin(){
coin +=1;
text.SetText(coin.ToString());
}
}
👉무기 업그레이드
더보기


- weapon을 배열로 수정한다음 player에 추가해준다
✏️코드 작성
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class GameManager : MonoBehaviour
{
public static GameManager instance = null;
[SerializeField]
private TextMeshProUGUI text;
private int coin = 0;
void Awake(){
if(instance == null){
instance = this;
}
}
public void IncreaseCoin(){
coin +=1;
text.SetText(coin.ToString());
if(coin % 30 ==0){//30의 배수
Player player = FindObjectOfType<Player>(); //플레이어를 찾으면 반환
if(player !=null){
player.Upgrade();
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using Unity.Collections;
using UnityEngine;
public class Player : MonoBehaviour
{ [SerializeField] //유니티 상에서 값을 넣어줄 수 있게함
private float moveSpeed;
[SerializeField]
private GameObject[] weapons;
private int weaponIndex =0;
[SerializeField]
private Transform shootTransform; //플레이어 머리 위에서 발사되는 예측값
[SerializeField]
private float shootInterval = 0.05f; //미사일을 쏘는 간격
private float lastShotTime =0f;
void Update() {
Vector3 mousePos =Camera.main.ScreenToWorldPoint(Input.mousePosition);
float toX = Mathf.Clamp(mousePos.x,-2.35f,2.35f);
transform.position = new Vector3(toX,transform.position.y,transform.position.z);
Shoot();
}
void Shoot(){
if(Time.time-lastShotTime>shootInterval){
Instantiate(weapons[weaponIndex],shootTransform.position,Quaternion.identity); //게임 오브젝트를 만드는 메소드
lastShotTime =Time.time;//현재 시간으로 업데이트
} //Time.time 게임이 시작된 이후로 현재까지 흐른 시간
}
private void OnTriggerEnter2D(Collider2D other) {
if(other.gameObject.tag == "Enemy"){
Debug.Log("GAME OVER");
Destroy(gameObject);
}else if (other.gameObject.tag=="Coin"){
GameManager.instance.IncreaseCoin();
Destroy(other.gameObject);
}
}
public void Upgrade(){
weaponIndex +=1;
if(weaponIndex >= weapons.Length){
weaponIndex = weapons.Length-1;
}
}
}
👉보스 만들기
더보기
- 보스를 설정한 다음에 충돌처리와 스폰 처리를 해준다
✏️코드 작성
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
[SerializeField]
private GameObject[] enemies;
private float[] arrPosX = {-2.2f, -1.1f, 0f , 1.1f, 2.2f};
[SerializeField]
private float spawnInterval = 1.5f;
[SerializeField]
private GameObject boss;
void Start()
{
StartEnemyRoutine();
}
void StartEnemyRoutine(){
StartCoroutine("EnemyRoutine");
}
IEnumerator EnemyRoutine(){
yield return new WaitForSeconds(3f);// 3초간 대기 후에 밑에 코드 실행
float moveSpeed = 5f; //이동속도 5
int enemyIndex= 0;
int spawnCount=0;
while(true){
for (int i = 0; i < 5; i++) {
SpawnEnemy(arrPosX[i], enemyIndex, moveSpeed); // 선택된 위치에 장애물 생성
}
spawnCount +=1;
if(spawnCount %10==0){
enemyIndex +=1;
moveSpeed +=2;
}
if(enemyIndex >= enemies.Length){
SpawnBoss();
enemyIndex=0;
moveSpeed =5f;
}//보스 등장 후 초기화
yield return new WaitForSeconds(spawnInterval);// 1.5초 기다렸다가 반복
}//무한 반복
}
void SpawnEnemy(float posX, int index, float moveSpeed){
Vector3 spawnPos = new Vector3(posX, transform.position.y,transform.position.z);
if(Random.Range(0,5)==0){
index +=1;
}// 0~4사이 숫자 (20%확률)
if(index>=enemies.Length){
index = enemies.Length-1;
}
GameObject enemyObject = Instantiate(enemies[index], spawnPos, Quaternion.identity);
Enemy enemy = enemyObject.GetComponent<Enemy>();
enemy.SetMoveSpeed(moveSpeed);
}
void SpawnBoss(){
Instantiate(boss, transform.position, Quaternion.identity );
}
}
private void OnTriggerEnter2D(Collider2D other) {
if(other.gameObject.tag == "Enemy"|| other.gameObject.tag =="Boss"){
Debug.Log("GAME OVER");
Destroy(gameObject);
}else if (other.gameObject.tag=="Coin"){
GameManager.instance.IncreaseCoin();
Destroy(other.gameObject);
}
}
👉게임 오버 처리
더보기

💠게임 오버 처리
- hp가 0 이하일 때, 보스를 잡을 때, 플레이어가 게임 오브젝트에 충돌했을 때 게임 오버가 되게 처리
public void SetGameOver(){
EnemySpawner enemySpawner = FindObjectOfType<EnemySpawner>();
if(enemySpawner!= null){
enemySpawner.StopEnemyRoutine();
}
}
private void OnTriggerEnter2D(Collider2D other) {
if(other.gameObject.tag == "Enemy"|| other.gameObject.tag =="Boss"){
GameManager.instance.SetGameOver();
Destroy(gameObject);
}else if (other.gameObject.tag=="Coin"){
GameManager.instance.IncreaseCoin();
Destroy(other.gameObject);
}
}
private void OnTriggerEnter2D(Collider2D other) {
if(other.gameObject.tag == "Weapon"){
Weapon weapon = other.gameObject.GetComponent<Weapon>(); //충돌한 대상이 weapon일 때만 충돌한 대상의 gameObject로 부터 weapon을 가져옴
hp -= weapon.damage;
if(hp<=0){
if(gameObject.tag == "Boss"){
GameManager.instance.SetGameOver();
}
Destroy(gameObject);
Instantiate(coin, transform.position, Quaternion.identity);
}
Destroy(other.gameObject);
}//충돌처리

👉결과 화면 및 실행
728x90
'🎮 취미 > Unity' 카테고리의 다른 글
유니티 스터디 - 탑뷰 액션 게임 업그레이드 하기🆙 (2) | 2024.11.22 |
---|---|
유니티 스터디 - 게임 개발 속성 강의 (1) (1) | 2024.11.08 |
유니티 쯔꾸르 게임 만들기 4 (인프런) (0) | 2023.07.01 |
유니티 쯔꾸르 게임 만들기 3 (인프런) (0) | 2023.07.01 |
유니티 쯔꾸르 게임 만들기 2 (인프런) (0) | 2023.07.01 |