Prefabs
- 재활용을 위해 에셋으로 저장된 게임오브젝트
- Scene 오브젝트를 에셋 안으로 드래그하여 생성한다.
- 총알을 프리펩으로 생성하고 충돌이벤트를 위해 Collider와 Rigidbody를 넣어준다.
- Rigidbody는 AddForce로 총알의 발사를 구현할 것이기 때문에 Dynamic 타입에 Gravity Scale은 0으로 설정
프리펩은 위와 같이 파란색으로 표시됨.
- 게임에 이미 지나간 총알이 계속쌓이면 메모리낭비가 일어나므로, 경계를 만들어 총알이 경계를 지나면 삭제하도록 한다.
- 따라하기 1에서 한 플레이어경계를 복사해 크기를 설정하고 태그를 BorderBullet으로 설정 한 후 , Bullet.cs를 만들고 OnTriggerEnter2D 함수를 이용해 제거한다.
- 게임오브젝트의 제거는 Destroy()를 사용한다.
private void OnTriggerEnter2D(Collider2D collision) { if(collision.gameObject.tag == "BorderBullet") { Destroy(gameObject); } }
- Input.GetButton을 이용해 발사체를 생성한다.
- Instantiate()를 사용해 생성 -> Instantiate() : 매개변수 오브젝트를 생성하는 함수
- Instantiate로 생성하고 AddForce로 발사를 구현
GameObject Bullet = Instantiate(BulletA, transform.position, transform.rotation); // 프리펩이름, 위치, 회전 Rigidbody2D rigid = Bullet.GetComponent<Rigidbody2D>(); rigid.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
- 총알의 충돌을 막기 위해 isTrigger를 켜준다.
- 마우스 좌클릭을 누를 때 무한대로 총알이 발사하기 때문에 딜레이를 설정할 변수를 만들어준다.
- curShotDelay에 Time.deltTime을 더해주면서 maxShotDelay보다 작을 경우 총알이 나가지 않게함.
curShotDelay += Time.deltaTime;
- 마우스 좌클릭을 누르지 않거나, 딜레이 시간이 안지났으면 return
if (!Input.GetButton("Fire1")) // Fire1은 마우스좌클릭 return; if (curShotDelay < maxShotDelay) return;
- 발사체의 파워에 따라 총알이 다르게 나가도록 설정
- switch문으로 로직을 만들어주고, power의 단계에 따라 2개가 나가던지, 3개가 나가던지 설정
switch(power) { case 1: // Power 1 GameObject Bullet = Instantiate(BulletA, transform.position, transform.rotation); Rigidbody2D rigid = Bullet.GetComponent<Rigidbody2D>(); rigid.AddForce(Vector2.up * 10, ForceMode2D.Impulse); break; case 2: // Power 2 GameObject BulletR = Instantiate(BulletA, transform.position + Vector3.right*0.1f, transform.rotation); GameObject BulletL = Instantiate(BulletA, transform.position + Vector3.left*0.1f, transform.rotation); Rigidbody2D rigidR = BulletR.GetComponent<Rigidbody2D>(); Rigidbody2D rigidL = BulletL.GetComponent<Rigidbody2D>(); rigidR.AddForce(Vector2.up * 10, ForceMode2D.Impulse); rigidL.AddForce(Vector2.up * 10, ForceMode2D.Impulse); break; case 3: // Power 3 GameObject BulletRR = Instantiate(BulletA, transform.position + Vector3.right*0.35f, transform.rotation); GameObject BulletCC = Instantiate(BulletB, transform.position, transform.rotation); GameObject BulletLL = Instantiate(BulletA, transform.position + Vector3.left*0.35f, transform.rotation); Rigidbody2D rigidRR = BulletRR.GetComponent<Rigidbody2D>(); Rigidbody2D rigidCC = BulletCC.GetComponent<Rigidbody2D>(); Rigidbody2D rigidLL = BulletLL.GetComponent<Rigidbody2D>(); rigidRR.AddForce(Vector2.up * 10, ForceMode2D.Impulse); rigidCC.AddForce(Vector2.up * 10, ForceMode2D.Impulse); rigidLL.AddForce(Vector2.up * 10, ForceMode2D.Impulse); break; }
Bullet.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.tag == "BorderBullet")
{
Destroy(gameObject);
}
}
}
Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public bool isTouchTop;
public bool isTouchBottom;
public bool isTouchLeft;
public bool isTouchRight;
public float speed;
public float power;
public float curShotDelay;
public float maxShotDelay;
public GameObject BulletA;
public GameObject BulletB;
Animator anim;
private void Awake()
{
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
Move();
Fire();
Reload();
}
void Reload()
{
curShotDelay += Time.deltaTime;
}
void Fire()
{
if (!Input.GetButton("Fire1")) // Fire1은 마우스좌클릭
return;
if (curShotDelay < maxShotDelay)
return;
switch(power)
{
case 1:
// Power 1
GameObject Bullet = Instantiate(BulletA, transform.position, transform.rotation);
Rigidbody2D rigid = Bullet.GetComponent<Rigidbody2D>();
rigid.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
break;
case 2:
// Power 2
GameObject BulletR = Instantiate(BulletA, transform.position + Vector3.right*0.1f, transform.rotation);
GameObject BulletL = Instantiate(BulletA, transform.position + Vector3.left*0.1f, transform.rotation);
Rigidbody2D rigidR = BulletR.GetComponent<Rigidbody2D>();
Rigidbody2D rigidL = BulletL.GetComponent<Rigidbody2D>();
rigidR.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
rigidL.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
break;
case 3:
// Power 3
GameObject BulletRR = Instantiate(BulletA, transform.position + Vector3.right*0.35f, transform.rotation);
GameObject BulletCC = Instantiate(BulletB, transform.position, transform.rotation);
GameObject BulletLL = Instantiate(BulletA, transform.position + Vector3.left*0.35f, transform.rotation);
Rigidbody2D rigidRR = BulletRR.GetComponent<Rigidbody2D>();
Rigidbody2D rigidCC = BulletCC.GetComponent<Rigidbody2D>();
Rigidbody2D rigidLL = BulletLL.GetComponent<Rigidbody2D>();
rigidRR.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
rigidCC.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
rigidLL.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
break;
}
curShotDelay = 0;
}
void Move()
{
float h = Input.GetAxisRaw("Horizontal");
if ((isTouchRight && h == 1) || (isTouchLeft && h == -1))
h = 0;
float v = Input.GetAxisRaw("Vertical");
if ((isTouchTop && v == 1) || (isTouchBottom && v == -1))
v = 0;
Vector3 curPos = transform.position;
Vector3 nextPos = new Vector3(h, v, 0) * speed * Time.deltaTime;
transform.position = curPos + nextPos;
// Animation
if (Input.GetButtonUp("Horizontal") || Input.GetButtonDown("Horizontal"))
{
anim.SetInteger("Input", (int)h);
}
}
public void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.tag == "Border")
{
switch(collision.gameObject.name)
{
case "Top":
isTouchTop = true;
break;
case "Bottom":
isTouchBottom = true;
break;
case "Left":
isTouchLeft = true;
break;
case "Right":
isTouchRight = true;
break;
}
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.tag == "Border")
{
switch (collision.gameObject.name)
{
case "Top":
isTouchTop = false;
break;
case "Bottom":
isTouchBottom = false;
break;
case "Left":
isTouchLeft = false;
break;
case "Right":
isTouchRight = false;
break;
}
}
}
}