μ„œμšΈμ—¬μžλŒ€ν•™κ΅ SWU/2023 여름방학 SW사관학ꡐ Programing GURU

[6] μŠˆνŒ… κ²Œμž„ μ œμž‘ (2)

waterproof 2023. 7. 6. 02:26

 

[6].1 μ΄μ•Œ λ°œμ‚¬ μ œμž‘
[6].2 적 이동 & 좩돌
[6].3 적 μžλ™ 생성
[6].4 적 인곡지λŠ₯

 


[6].1 μ΄μ•Œ λ°œμ‚¬ μ œμž‘


πŸ”Ά PlayerFire 슀크립트 생성 및 ν• λ‹Ή

  • Project 창에 PlayerFire λΌλŠ” μ΄λ¦„μœΌλ‘œ C# 슀크립트λ₯Ό ν•˜λ‚˜ λ§Œλ“ λ‹€.
  • Player 객체에 λ“œλž˜κ·Έ μ•€ λ“œλ‘­μœΌλ‘œ λΆ™μ—¬ μ€€λ‹€.

Player 객체에 PlayerFire 슀크립트 ν• λ‹Ή

 

 

 

πŸ”Ά μ΄μ•Œ λ°œμ‚¬ 둜직

  • 총의 λ°©μ•„μ‡ λ₯Ό λ‹ΉκΈ°λ©΄ μ΄μ•Œ 곡μž₯에 μ „ν™”λ₯Ό ν•˜μ—¬ μƒμ‚°λœ μ΄μ•Œμ„ λ°›μ•„ λ°œμ‚¬ ν•˜λŠ” νλ¦„μœΌλ‘œ 이해 ν•  수 있으며 μ΄λŠ” μ΄μ•Œ νŒŒμ„ μ—΄μ–΄ λ©”λͺ¨λ¦¬μ— μ˜¬λ¦¬λŠ” 흐름과 κ°™λ‹€.
  • 이 흐름을 μ²˜λ¦¬ν•΄ μ£ΌλŠ” ν•¨μˆ˜κ°€ Instantiate ν•¨μˆ˜.

μ΄μ•Œμ„ λ°œμ‚¬ ν•  λ•Œμ˜ μΌμ–΄λ‚˜λŠ” 일의 흐름도

 

 

 

πŸ”Ά ν•„μš” 속성 μΆ”κ°€

  • μ΄μ•Œμ„ μƒμ„±ν•˜κΈ° μœ„ν•΄ μ΄μ•Œ 곡μž₯이 ν•„μš”ν•˜λ‹€.
  • λ§Œλ“€μ–΄μ§„ μ΄μ•Œμ„ λ°œμ‚¬ν•˜κΈ° μœ„ν•œ μœ„μΉ˜κ°€ ν•„μš”ν•˜λ©° μ΄λŠ” 총ꡬ둜 μ†μ„±μœΌλ‘œ λ“±λ‘ν•œλ‹€.

πŸ–₯️ PlayerFire.cs ν•„μš”μ†μ„± μ„€μ •

public class PlayerFire : MonoBehaviour
{
	//μ΄μ•Œ 생산할 곡μž₯
	public GameObject bulletFactory;
	//총ꡬ
	public GameObject firePosition;
}

 

 

 

πŸ”Ά Bullet ν”„λ¦¬νŒΉ μ œμž‘

  • Project 창에 폴더λ₯Ό ν•˜λ‚˜ λ§Œλ“€μ–΄ 이름을 Prefabs 으둜 λ³€κ²½
  • ν•˜μ΄μ–΄λΌν‚€μ˜ Bullet 객체λ₯Ό λ“œλž˜κ·Έ μ•€ λ“œλ‘­μœΌλ‘œ Project 창의 Prefabs 폴더에 λ„£μ–΄μ€€λ‹€.

Prefabs 폴더 생성
Bullet 을 Prefab 으둜 등둝

 

 

 

πŸ”Ά Bullet ν• λ‹Ή

  • μ”¬μ—μ„œ Bullet μ„ μ œκ±°ν•œλ‹€.
  • PlayerFire 의 Bullet Factory 속성에 Bullet ν”„λ¦¬νŒΉμ„ ν• λ‹Ή

Bullet Prefab 등둝 ν›„ 씬 μƒνƒœ
PlayerFire 의 Bullet Factory 속성에 Bullet ν”„λ¦¬νŒΉ ν• λ‹Ή

 

 

 

πŸ”Ά 총ꡬ μ œμž‘

  • Player κ°μ²΄λ₯Ό μ„ νƒν•˜κ³  λ§ˆμš°μŠ€ μš°ν΄λ¦­. 
  • Create Empty λ₯Ό μ„ νƒν•˜λ©΄ μžμ‹μœΌλ‘œ 빈 κ²Œμž„μ˜€λΈŒμ νŠΈκ°€ 등둝이 되며, 이름을 FirePosition 으둜 λ³€κ²½.

Player 으둜 FirePosition 객체 등둝

 

 

 

πŸ”Ά μ΄κ΅¬ μ†μ„± ν• λ‹Ή

  • FirePosition 객체λ₯Ό Player 의 PlayerFire μŠ€ν¬λ¦½νŠΈμ— ν• λ‹Ή

PlayerFire 의 FirePosition ν• λ‹Ή

 

 

 

πŸ”Ά μ‚¬μš©μžκ°€ λ°œμ‚¬ λ²„νŠΌμ„ λˆ„λ₯΄λ©΄

  • μ‚¬μš©μžκ°€ μ™Όμͺ½ λ§ˆμš°μŠ€λ²„νŠΌ 클릭을 ν•˜κ±°λ‚˜ μ™Όμͺ½ Ctrl λ²„νŠΌμ„ λˆŒλ €μ„λ•Œμ˜ μž…λ ₯μ²˜λ¦¬λŠ” “Fire1” μ— ν•΄λ‹Ήν•œλ‹€.
  • GetButtonDown ν•¨μˆ˜λ₯Ό 톡해 μž…λ ₯μ—¬λΆ€λ₯Ό ν™•μΈν•˜μ—¬ 처리λ₯Ό ν•  μˆ˜ μžˆλ‹€.

πŸ–₯️ PlayerFire.cs λ°œμ‚¬ μž…λ ₯처리

public class PlayerFire : MonoBehaviour
{
	. . . (μƒλž΅) . . .
	void Update()
	{
		//λͺ©ν‘œ: μ‚¬μš©μžκ°€ λ°œμ‚¬ λ²„νŠΌμ„ λˆ„λ₯΄λ©΄ μ΄μ•Œμ„ λ°œμ‚¬ν•˜κ³  μ‹Άλ‹€.
		//μˆœμ„œ : 1.μ‚¬μš©μžκ°€ λ°œμ‚¬ λ²„νŠΌμ„ λˆ„λ₯΄λ©΄
		// - λ§Œμ•½ μ‚¬μš©μžκ°€ λ°œμ‚¬ λ²„νŠΌμ„ λˆ„λ₯΄λ©΄
		if (Input.GetButtonDown("Fire1"))
		{
			//2.μ΄μ•Œ 곡μž₯μ—μ„œ μ΄μ•Œμ„ λ§Œλ“ λ‹€.
			//3.μ΄μ•Œμ„ λ°œμ‚¬ν•œλ‹€.
		}
	}
}

 

 

 

πŸ”Ά μ΄μ•Œ 곡μž₯μ—μ„œ μ΄μ•Œμ„ λ§Œλ“ λ‹€

  • Instantiate ν•¨μˆ˜μ˜ 인자둜 μ΄μ•Œκ³΅μž₯ bulletFactory λ₯Ό λ„£μ–΄ μ£Όλ©΄ μ΄μ•Œμ„ ν•˜λ‚˜ 생성 ν•΄μ€€λ‹€.

πŸ–₯️ PlayerFire.cs μ΄μ•Œ 생성

public class PlayerFire : MonoBehaviour
{
	. . . (μƒλž΅) . . .
	void Update()
	{
		//λͺ©ν‘œ: μ‚¬μš©μžκ°€ λ°œμ‚¬ λ²„νŠΌμ„ λˆ„λ₯΄λ©΄ μ΄μ•Œμ„ λ°œμ‚¬ν•˜κ³  μ‹Άλ‹€.
		//μˆœμ„œ : 1.μ‚¬μš©μžκ°€ λ°œμ‚¬ λ²„νŠΌμ„ λˆ„λ₯΄λ©΄
		// - λ§Œμ•½ μ‚¬μš©μžκ°€ λ°œμ‚¬ λ²„νŠΌμ„ λˆ„λ₯΄λ©΄
		if (Input.GetButtonDown("Fire1"))
		{
			//2.μ΄μ•Œ 곡μž₯μ—μ„œ μ΄μ•Œμ„ λ§Œλ“ λ‹€.
			GameObject bullet = Instantiate(bulletFactory);
            
			//3.μ΄μ•Œμ„ λ°œμ‚¬ν•œλ‹€.
		}
	}
}

 

 

 

 

πŸ”Ά μ΄μ•Œμ„ λ°œμ‚¬ν•œλ‹€

  • λ§Œλ“€μ–΄μ§„ bullet 객체에 μ†μ„±μœΌλ‘œ μ„ μ–Έν•œ firePosition 총ꡬ의 μœ„μΉ˜λ₯Ό ν• λ‹Ή

πŸ–₯️ PlayerFire.cs μ΄μ•Œ λ°œμ‚¬

public class PlayerFire : MonoBehaviour
{
	. . . (μƒλž΅) . . .
	void Update()
	{
		//λͺ©ν‘œ: μ‚¬μš©μžκ°€ λ°œμ‚¬ λ²„νŠΌμ„ λˆ„λ₯΄λ©΄ μ΄μ•Œμ„ λ°œμ‚¬ν•˜κ³  μ‹Άλ‹€.
        //μˆœμ„œ : 1.μ‚¬μš©μžκ°€ λ°œμ‚¬ λ²„νŠΌμ„ λˆ„λ₯΄λ©΄
		// - λ§Œμ•½ μ‚¬μš©μžκ°€ λ°œμ‚¬ λ²„νŠΌμ„ λˆ„λ₯΄λ©΄
		if (Input.GetButtonDown("Fire1"))
		{
			//2.μ΄μ•Œ 곡μž₯μ—μ„œ μ΄μ•Œμ„ λ§Œλ“ λ‹€.
			GameObject bullet = Instantiate(bulletFactory);
            
			//3.μ΄μ•Œμ„ λ°œμ‚¬ν•œλ‹€.(μ΄μ•Œμ„ μ΄κ΅¬μœ„μΉ˜λ‘œ κ°€μ Έλ‹€ 놓기)
			bullet.transform.position = firePosition.transform.position;
		}
	}
}

 

 

 

 


[6].2 적 이동 & 좩돌

πŸ”Ά Enemy 객체 생성

  • ν•˜μ΄μ–΄λΌν‚€μ—μ„œ + λ²„νŠΌμ„ 눌러 κ·Έλ¦Όκ³Ό 같이 3D Object 의 Cube λ₯Ό ν•˜λ‚˜ λ§Œλ“€κ³  이름을 Enemy둜 λ³€κ²½

Enemy κ²Œμž„μ˜€λΈŒμ νŠΈ 생성

 

 

 

πŸ”Ά Enemy μœ„μΉ˜ μ„€μ •

  • 적이 μƒμ„±λ˜λŠ” μœ„μΉ˜λŠ” ν™”λ©΄μ˜ μœ„μͺ½μ΄λ‹ˆ Enemy의 Transform μ˜ Position μ •λ³΄λ₯Ό λ³€κ²½

Enemy Transform κ°’ μ„€μ •

 

 

 

 

πŸ”Ά Enemy μŠ€ν¬λ¦½νŠΈ ν• λ‹Ή

  • Project μ°½μ—μ„œ Scripts 폴더에 Enemy λΌλŠ” μ΄λ¦„μ˜ 슀크립트λ₯Ό λ§Œλ“ λ‹€.
  • ν•˜μ΄μ–΄λΌν‚€μ˜ Enemy κ²Œμž„μ˜€λΈŒμ νŠΈμ— λ“œλž˜κ·Έ μ•€ λ“œλ‘­μœΌλ‘œ λΆ™μ—¬ μ€€λ‹€.

Enemy 슀크립트 ν• λ‹Ή

 

 

 

πŸ”Ά  μ΄λ™ μ½”λ“œ μž‘μ„±

  • 이동속도 μ†μ„±μ„ μ„ μ–Έ
  • λ°©ν–₯을 κ΅¬ν•˜κ³  μ΄λ™κ³΅μ‹μœΌλ‘œ μ½”λ“œλ₯Ό κ΅¬ν˜„ν•œλ‹€.

πŸ–₯️ Enemy.cs μ•„λž˜λ‘œ μ΄λ™μ‹œν‚€κΈ°

public class Enemy : MonoBehaviour
{
	//ν•„μš”μ†μ„± : 이동속도
	public float speed = 5;
    
    void Update()
	{
		// 1. λ°©ν–₯을 κ΅¬ν•œλ‹€.
		Vector3 dir = Vector3.down;
		// 2. μ΄λ™ν•˜κ³  μ‹Άλ‹€. 곡식 P = P0 + vt
		transform.position += dir * speed * Time.deltaTime;
	}
}

 

 

 

 

πŸ”Ά μΆ©λŒμ„ μœ„ν•œ 쑰건

  • λͺΈμ²΄μ— ν•΄λ‹Ήν•˜λŠ” μΆ©λŒμ²΄ Collder κ°€ ν•„μš”
  • 물리 역할을 λ‹΄λ‹Ήν•  Rigidbody κ°€ ν•„μš”

 

 

 

 

πŸ”Ά μΆ©λŒμ²΄

  • Enemy κ²Œμž„μ˜€λΈŒμ νŠΈμ— λΆ™μ–΄ μžˆλŠ” κΈ°λ³Έ μΆ©λŒμ²΄λŠ” BoxCollider 이닀.

Enemy의 좩돌체인 Box Collider

 

 

 

πŸ”Ά λ¬Όμ²΄λΌλ¦¬ μΆ©λŒν•˜κΈ°

  • Enemy κ²Œμž„μ˜€λΈŒμ νŠΈμ— Physics ν•­λͺ©μ˜ Rigidbodyλ₯Ό ν΄λ¦­ν•΄μ„œ μ»΄ν¬λ„ŒνŠΈλ₯Ό μΆ”κ°€
  • 쀑λ ₯을 μ‚¬μš©ν•˜μ§€ μ•Šκ²Œ ν•˜λ„λ‘ Use Gravity 속성을 κΊΌμ€€λ‹€.

Rigidbody μ»΄ν¬λ„ŒνŠΈ μΆ”κ°€ν•˜κΈ°
Rigidbody 의 Use Gravity μ²΄ν¬λ°•μŠ€ 끄기

 

 

 

πŸ”Ά μΆ©λŒν•œ λ¬Όμ²΄ νŒŒκ΄΄ν•˜κΈ°

  • 물체의 μΆ©λŒμ„ κ°μ§€ν•˜λŠ” ν•¨μˆ˜λŠ” OnCollisionEnter ν•¨μˆ˜μ΄λ©° μ΄κ³³μ—μ„œ λΆ€λ”ͺ힌 객체(other) λ₯Ό μ œκ±°ν•˜κ³  본인도 μ œκ±°ν•œλ‹€.

πŸ–₯️ Enemy.cs μΆ©λŒ μ²˜λ¦¬

public class Enemy : MonoBehaviour
{
	. . . (μƒλž΅) . . .

	// 좩돌 μ‹œμž‘
	private void OnCollisionEnter(Collision other)
	{
		// λ„ˆμ£½κ³ 
		Destroy(other.gameObject);
		// λ‚˜μ£½μž
		Destroy(gameObject);
	}
}

 

 

 

πŸ’‘μ—¬κΈ°μ„œ... μ‹€ν–‰ λ²„νŠΌμ„ λˆŒλŸ¬μ„œ μΆ©λŒμ‹œμΌ°λ”λ‹ˆ 씬과 ν•˜μ΄μ–΄λΌν‚€μ—μ„œ κ·ΈλŒ€λ‘œ 사라짐 ... 

 


[6].3 적 μžλ™ 생성

 

πŸ”Ά Enemy Prefab μ œμž‘ 및 제거

  • ν•˜μ΄μ–΄λΌν‚€(Hierarchy)창의 Enemy κ²Œμž„μ˜€λΈŒμ νŠΈλ₯Ό ν”„λ‘œμ νŠΈ(Project)창의 Prefabs폴더μͺ½μœΌλ‘œ λ“œλž˜κ·Έ μ•€ λ“œλ‘­ν•΄μ„œ ν”„λ¦¬νŒΉμœΌλ‘œ λ§Œλ“€μ–΄ μ€€λ‹€.
  • ν•˜μ΄μ–΄λΌν‚€μ˜ Enemy κ²Œμž„μ˜€λΈŒμ νŠΈλŠ” Delν‚€λ₯Ό λˆŒλŸ¬μ„œ μ‚­μ œ

Enemy κ²Œμž„μ˜€λΈŒμ νŠΈλ₯Ό Prefab 으둜 등둝
Enemy Prefab 등둝 ν›„ 씬 μƒνƒœ

 

 

 

πŸ”Ά μ—­ν•  μ •μ˜ λ° κ°μ²΄ μƒμ„±

  • μΌμ •μ‹œκ°„ λ§ˆλ‹€ μ μ„ λ§Œλ“€μ–΄ λ‚΄λ„둝 ν•˜λ©° EnemyManager의 μœ„μΉ˜μ—μ„œ μ μ΄ μƒμ„± λ˜λ„둝 ν•œλ‹€.
  • ν•˜μ΄μ–΄λΌν‚€μ—μ„œ [+] -> [Create Empty] 을 μ„ νƒν•˜μ—¬ 빈 κ²Œμž„μ˜€λΈŒμ νŠΈλ₯Ό ν•˜λ‚˜ λ§Œλ“€κ³  이름을 EnemyManager둜 λ³€κ²½

EnemyManager κ²Œμž„μ˜€λΈŒμ νŠΈ 생성

 

 

 

πŸ”Ά 기즈λͺ¨ μ„€μ •

  • Sceneμ—μ„œ μ λ‹Ήν•œ μœ„μΉ˜μ— 배치 ν›„ 잘 보이도둝 μ•„μ΄μ½˜ 기즈λͺ¨λ₯Ό μ„€μ •
  • μ•„μ΄μ½˜ 기즈λͺ¨ 섀정은 EnemyManager κ²Œμž„μ˜€λΈŒμ νŠΈλ₯Ό ν΄λ¦­ν•œ ν›„ Inspector창의 λ°”λ‘œ μ•„λž˜μͺ½μ— μžˆλŠ” νλΈŒ λͺ¨μ–‘μ˜ λ²„νŠΌμ„ λˆ„λ₯Έλ‹€

EnemyManager μœ„μΉ˜ λ³€κ²½ 및 μ•„μ΄μ½˜ 기즈λͺ¨ μ„€μ •

 

 

 

πŸ”Ά EnemyManager 슀크립트 생성 및 ν• λ‹Ή

  • Project μ°½μ—μ„œ Scripts 폴더에 EnemyManager λΌλŠ” μ΄λ¦„μ˜ 슀크립트λ₯Ό λ§Œλ“€μ–΄ μ€€λ‹€.
  • ν•˜μ΄μ–΄λΌν‚€μ˜ EnemyManager κ²Œμž„μ˜€λΈŒμ νŠΈμ— λ“œλž˜κ·Έ μ•€ λ“œλ‘­μœΌλ‘œ λΆ™μ—¬ μ€€λ‹€.

EnemyManager 슀크립트 ν• λ‹Ή

 

 

 

πŸ”Ά λͺ©ν‘œμ„€μ •

λͺ©ν‘œ μΌμ •μ‹œκ°„λ§ˆλ‹€ μ μ„ μƒμ„±ν•΄μ„œ λ‚΄ μœ„μΉ˜μ— κ°–λ‹€ λ†“κ³  μ‹Άλ‹€
ν•„μš”μ†μ„± μΌμ •μ‹œκ°„, ν˜„μž¬μ‹œκ°„, μ  κ³΅μž₯
μˆœμ„œ 1. μ‹œκ°„이 νλ₯΄λ‹€κ°€
2. λ§Œμ•½ ν˜„μž¬μ‹œκ°„μ΄ μΌμ •μ‹œκ°„이 λ˜λ©΄
3. μ  κ³΅μž₯μ—μ„œ μ μ„ μƒμ„±ν•΄μ„œ λ‚΄ μœ„μΉ˜μ— κ°–λ‹€ λ†“κ³  μ‹Άλ‹€.

 

 

 

πŸ”Ά ν•„μš” 속성 μ„ μ–Έ

  • “μΌμ •μ‹œκ°„λ§ˆλ‹€ 적을 μƒμ„±ν•΄μ„œ λ‚΄ μœ„μΉ˜μ— κ°–λ‹€ 놓고 μ‹Άλ‹€” λ₯Ό κ΅¬ν˜„ν•˜κΈ° μœ„ν•΄ ν•„μš”ν•œ μ •λ³΄λŠ” μΌμ •μ‹œκ°„, 생성할 적 곡μž₯, κ·Έλ¦¬κ³  κ²½κ³Όλœ μ‹œκ°„인 ν˜„μž¬ μ‹œκ°„μœΌλ‘œ λ³Ό μˆ˜ μžˆλ‹€.
  • Enemy ν”„λ¦¬νŒΉμ„ EnemyManager 의 Enemy Factory 속성에 ν• λ‹Ήν•˜μ—¬ μ€€λ‹€.

πŸ–₯️ EnemyManager.cs ν•„μš”μ†μ„± μ„ μ–Έ

public class EnemyManager : MonoBehaviour
{
	// ν˜„μž¬μ‹œκ°„
	float currentTime;
	// μΌμ •μ‹œκ°„
	public float createTime = 1;
	// 적 곡μž₯
	public GameObject enemyFactory;
}

EnemyManager 의 Enemy Factory 속성에 Enemy ν”„λ¦¬νŒΉ ν• λ‹Ή

 

 

 

πŸ”Ά μ‹œκ°„이 νλ₯΄λ‹€κ°€

  • μ‹œκ°„μ„ 계속 흐λ₯΄κ²Œ ν•˜κΈ°μœ„ν•΄ 라이프사이클 ν•¨μˆ˜ 쀑 Update ν•¨μˆ˜μ— λ‚΄μš©μ„ κ΅¬ν˜„ν•œλ‹€.
  • deltaTime 을 ν™œμš©ν•˜μ—¬ μ‹œκ°„μ„ λˆ„μ μ‹œμΌœ μ™„μ„±

πŸ–₯️ EnemyManager.cs μ‹œκ°„μ΄ 흐λ₯΄λ‹€κ°€

public class EnemyManager : MonoBehaviour
{
	. . . (μƒλž΅) . . .
	void Update()
	{
		// 1. μ‹œκ°„μ΄ 흐λ₯΄λ‹€κ°€
		currentTime += Time.deltaTime;
	}
}

 

 

 

 

πŸ”Ά λ§Œμ•½ ν˜„μž¬ μ‹œκ°„이 μΌμ •μ‹œκ°„이 λ˜λ©΄

  • κ²½κ³Ό μ‹œκ°„이 μƒμ„± μ‹œκ°„을 μ΄ˆκ³Όν•˜λ©΄ λ¬Έμž₯을 κ΅¬ν˜„ν•œλ‹€.
  • λ‹¨μˆœ C# μ΄λΌλŠ” μ–Έμ–΄λ‘œ λ²ˆμ—­ν•˜λŠ” ν˜•νƒœμž„μ„ 인지.

πŸ–₯️ EnemyManager.cs ν˜„μž¬μ‹œκ°„μ΄ μΌμ •μ‹œκ°„이 λ˜λ©΄

public class EnemyManager : MonoBehaviour
{
	. . . (μƒλž΅) . . .
	void Update()
	{
    
		// 1. μ‹œκ°„μ΄ 흐λ₯΄λ‹€κ°€
		currentTime += Time.deltaTime;
    
		// 2. λ§Œμ•½ ν˜„μž¬μ‹œκ°„μ΄ μΌμ •μ‹œκ°„μ΄ 되면
		if (currentTime > createTime)
		{
			// 3. 적 곡μž₯μ—μ„œ 적을 μƒμ„±ν•΄μ„œ
			// λ‚΄ μœ„μΉ˜μ— κ°–λ‹€ 놓고 μ‹Άλ‹€
		}
	}
}

 

 

 

 

πŸ”Ά 적 곡μž₯μ—μ„œ 적을 μƒμ„±ν•΄μ„œ λ‚΄ μœ„μΉ˜μ— κ°–λ‹€ 놓고 μ‹Άλ‹€.

  • 적 κ³΅μž₯μ—μ„œ μ μ„ λ§Œλ“€μ–΄μ„œ λ‚΄ μœ„μΉ˜μ— κ°–λ‹€ λ†“λŠ”λ‹€.

πŸ–₯️ EnemyManager.cs 적 μƒμ„±ν•˜κΈ°

public class EnemyManager : MonoBehaviour
{
	. . . (μƒλž΅) . . .
	void Update()
	{
		// 1. μ‹œκ°„μ΄ 흐λ₯΄λ‹€κ°€
		currentTime += Time.deltaTime;
		// 2. λ§Œμ•½ ν˜„μž¬μ‹œκ°„μ΄ μΌμ •μ‹œκ°„μ΄ 되면
		if (currentTime > createTime)
		{
		// 3. 적 곡μž₯μ—μ„œ 적을 μƒμ„±ν•΄μ„œ
		GameObject enemy = Instantiate(enemyFactory);
		// λ‚΄ μœ„μΉ˜μ— κ°–λ‹€ 놓고 μ‹Άλ‹€.
		enemy.transform.position = transform.position; 
		} 
	}
}

 

 

 

πŸ”Ά μ‹€ν–‰ λ° λ¬Έμ œ ν™•μΈ

  • 그런데 ν•˜μ΄μ–΄λΌν‚€λ₯Ό 보면 적이 μ—¬λŸ¬ 개 μƒμ„±λ˜μ–΄ μžˆλŠ” 것을 ν™•μΈν•  μˆ˜ μžˆλ‹€.
  • ν˜„μž¬μ‹œκ°„μ΄ μΌμ •μ‹œκ°„μ΄ 되고 λ‚œ ν›„ 계속 μΌμ •μ‹œκ°„ 보닀 크기 λ•Œλ¬Έμ— μ μ„ κ³„속 μƒμ„±
  • 이것을 ν•΄κ²°ν•˜κΈ° μœ„ν•΄ ν˜„μž¬μ‹œκ°„μ΄ μΌμ •μ‹œκ°„λ³΄λ‹€ 컀지면 ν˜„μž¬μ‹œκ°„μ„ 0으둜 μ΄ˆκΈ°ν™”ν•΄μ•Ό ν•œλ‹€.

Enemyκ°€ μ—¬λŸ¬ 개 μƒμ„±λ˜λŠ” ν˜„μƒ

 

 

 

  • κ²½κ³Ό μ‹œκ°„을 μ΄ˆκΈ°ν™” ν•˜μ—¬ λ¬Έμ œ ν•΄κ²°

πŸ–₯️ EnemyManager.cs ν˜„μž¬μ‹œκ°„μ„ 0으둜 μ΄ˆκΈ°ν™”

public class EnemyManager : MonoBehaviour
{
	. . . (μƒλž΅) . . .
	void Update()
	{
		// 1. μ‹œκ°„μ΄ 흐λ₯΄λ‹€κ°€
		currentTime += Time.deltaTime;
		// 2. λ§Œμ•½ ν˜„μž¬μ‹œκ°„μ΄ μΌμ •μ‹œκ°„μ΄ 되면
		if (currentTime > createTime)
		{
			// 3. 적 곡μž₯μ—μ„œ 적을 μƒμ„±ν•΄μ„œ
			GameObject enemy = Instantiate(enemyFactory);
			// λ‚΄ μœ„μΉ˜μ— κ°–λ‹€ 놓고 μ‹Άλ‹€.
			enemy.transform.position = transform.position;
			// ν˜„μž¬μ‹œκ°„μ„ 0으둜 μ΄ˆκΈ°ν™”
			currentTime = 0;
		} 
	}
}

 

 

 

πŸ”Ά EnemyManager 배치

  • EnemyManager κ²Œμž„μ˜€λΈŒμ νŠΈλ₯Ό ν΄λ¦­ν•˜κ³  ν‚€λ³΄λ“œμ˜ [Ctrl + D]ν‚€λ₯Ό λˆŒλŸ¬ λ³΅μ œ.
  • λ„€ 번 λ³΅μ œν•΄μ„œ λ‹€μ„― 개의 EnemyManagerλ₯Ό λ§Œλ“€κ³  κ°€λ‘œλ‘œ 2μœ λ‹›(λ―Έν„°) κ°„κ²©μœΌλ‘œ λ°°μΉ˜ν•΄μ€€λ‹€.

EnemyManager κ²Œμž„μ˜€λΈŒμ νŠΈλ₯Ό λ³΅μ œν•΄μ„œ 적절히 배치

 

 

 

πŸ”Ά λͺ©ν‘œ λ° ν•„μš” μ†μ„± μΆ”κ°€

  • λͺ©ν‘œ : 적이 생성될 λ•Œλ§ˆλ‹€ λ‹€μŒ 생성 μ‹œκ°„μ„ λžœλ€ν•˜κ²Œ ν•˜κ³  μ‹Άλ‹€.
  • ν•„μš”μ†μ„± : μ΅œμ†Œ, μ΅œλŒ€μ‹œκ°„

πŸ–₯️ EnemyManager.cs μ΅œμ†Œμ‹œκ°„, μ΅œλŒ€μ‹œκ°„ μΆ”κ°€

public class EnemyManager : MonoBehaviour
{
	// μ΅œμ†Œμ‹œκ°„
	float minTime = 1;
	// μ΅œλŒ€μ‹œκ°„
	float maxTime = 5;
	. . . (μƒλž΅) . . .
}

 

 

 

πŸ”Ά μƒμ„±μ‹œκ°„ 랜덀으둜 μ„€μ •

πŸ–₯️ EnemyManager.cs μƒμ„±μ‹œκ°„을 λžœλ€ν•˜κ²Œ μ μš©

public class EnemyManager : MonoBehaviour
{
	. . . (μƒλž΅) . . .
    
	void Start()
	{
		// νƒœμ–΄λ‚  λ•Œ 적 μƒμ„±μ‹œκ°„μ„ μ„€μ •ν•˜κ³ 
		createTime = UnityEngine.Random.Range(minTime, maxTime);
	}
	void Update()
	{
		// 1. μ‹œκ°„μ΄ 흐λ₯΄λ‹€κ°€
		currentTime += Time.deltaTime;
		// 2. λ§Œμ•½ ν˜„μž¬μ‹œκ°„μ΄ μΌμ •μ‹œκ°„μ΄ 되면
		if (currentTime > createTime)
		{
			. . . (μƒλž΅) . . .
			// 적을 μƒμ„±ν•œ ν›„ 적 μƒμ„±μ‹œκ°„μ„ λ‹€μ‹œ μ„€μ •ν•˜κ³  μ‹Άλ‹€.
			createTime = UnityEngine.Random.Range(minTime, maxTime);
		} 
	}
}

 

 

 


6.[4] 적 μΈκ³΅μ§€λŠ₯

 

πŸ”Ά ν™•λ₯ μ— μ˜ν•œ λΆ„κΈ°μ²˜λ¦¬

  • Random 클래슀λ₯Ό μ΄μš©ν•΄μ„œ 0~9쀑 λžœλ€ν•œ ν•˜λ‚˜μ˜ 수λ₯Ό κ°€μ Έμ™€μ„œ κ·Έ 값이 3보닀 μž‘μœΌλ©΄ ν”Œλ ˆμ΄μ–΄λ°©ν–₯, 그렇지 μ•ŠμœΌλ©΄ μ•„λž˜λ°©ν–₯이 λ˜λ„둝 μ‘°κ±΄μ„ λ§Œλ“ λ‹€.

πŸ–₯️ Enemy.cs ν™•λ₯ μ— μ˜ν•œ λΆ„κΈ°μ²˜λ¦¬

public class Enemy : MonoBehaviour
{
	. . . (μƒλž΅) . . .
	void Start()
	{
		// 0λΆ€ν„° 9(10-1) κΉŒμ§€ 값쀑에 ν•˜λ‚˜λ₯Ό 랜덀으둜 κ°€μ Έμ™€μ„œ
		int randValue = UnityEngine.Random.Range(0, 10);
		// λ§Œμ•½ 3보닀 μž‘μœΌλ©΄ ν”Œλ ˆμ΄μ–΄λ°©ν–₯
		if (randValue < 3)
		{
		}
		// 그렇지 μ•ŠμœΌλ©΄ μ•„λž˜λ°©ν–₯으둜 μ •ν•˜κ³  μ‹Άλ‹€.
		else
		{
		}
	}
	. . . (μƒλž΅) . . .
}

 

 

 

πŸ”Ά λ°©ν–₯ κ΅¬ν•˜κΈ°

  • λ¨Όμ € Target 인 Player λ₯Ό GameObject.Find ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ μ°ΎλŠ”λ‹€.
  • Vector 의 λΊ„μƒ˜μ„ ν™œμš©ν•˜μ—¬ μ›ν•˜λŠ” λ°©ν–₯을 μ°Ύμ•„λ‚Έλ‹€.
  • μ •κ·œν™”(Normalize) λ₯Ό μ μš©ν•˜μ—¬ Vector 의 크기λ₯Ό 1둜 λ§Œλ“€μ–΄ μ€€λ‹€.
  • νƒ€κ²Ÿ λ°©ν–₯이 아닐 κ²½μš°μ—λŠ” μ•„λž˜ λ°©ν–₯으둜 μ •ν•΄μ€€λ‹€.

πŸ–₯️ Enemy.cs λ°©ν–₯ κ΅¬ν•˜κΈ°

public class Enemy : MonoBehaviour
{
	. . . (μƒλž΅) . . .
	void Start()
	{
		Vector3 dir;
		// 0λΆ€ν„° 9(10-1) κΉŒμ§€ 값쀑에 ν•˜λ‚˜λ₯Ό 랜덀으둜 κ°€μ Έμ™€μ„œ
		int randValue = UnityEngine.Random.Range(0, 10);
		// λ§Œμ•½ 3보닀 μž‘μœΌλ©΄ ν”Œλ ˆμ΄μ–΄λ°©ν–₯
		if (randValue < 3)
		{
			// ν”Œλ ˆμ΄μ–΄λ₯Ό μ°Ύμ•„μ„œ target으둜 ν•˜κ³ μ‹Άλ‹€.
			GameObject target = GameObject.Find("Player");
			// λ°©ν–₯을 κ΅¬ν•˜κ³ μ‹Άλ‹€. target - me
			dir = target.transform.position - transform.position;
			// λ°©ν–₯의 크기λ₯Ό 1둜 ν•˜κ³  μ‹Άλ‹€.
			dir.Normalize();
		}
		// 그렇지 μ•ŠμœΌλ©΄ μ•„λž˜λ°©ν–₯으둜 μ •ν•˜κ³  μ‹Άλ‹€.
		else
		{
			dir = Vector3.down;
		}
	}
	. . . (μƒλž΅) . . .
}

 

 

  • μ§€μ—­λ³€μˆ˜ dir μ„ μ „μ—­ λ³€μˆ˜λ‘œ λ³€κ²½
  • μœ λ‹ˆν‹°μ—μ„œ μ‹€ν–‰ν•˜μ—¬ κ²°κ³Ό 확인

πŸ–₯️ Enemy.cs λ°©ν–₯ μ •ν•΄μ„œ κ·Έ λ°©ν–₯으둜 이동

public class Enemy : MonoBehaviour
{
	. . . (μƒλž΅) . . .

	// λ°©ν–₯을 μ „μ—­λ³€μˆ˜λ‘œ λ§Œλ“€μ–΄μ„œ Start와 Updateμ—μ„œ μ‚¬μš©
	Vector3 dir;
	
	void Start()
	{
		// Vector3 dir; -> μ‚­μ œ
		. . . (μƒλž΅) . . .
	}
	void Update()
	{
		// 1. λ°©ν–₯을 κ΅¬ν•œλ‹€.
		// Vector3 dir = Vector3.down; -> μ‚­μ œ
		// 2. μ΄λ™ν•˜κ³  μ‹Άλ‹€. 곡식 P = P0 + vt
		transform.position += dir * speed * Time.deltaTime;
	}
	. . . (μƒλž΅) . . .
}