게임클라이언트 프로그래밍/Unity
SpaceShooter
Game Client Lee Hwanguk
2023. 2. 10. 19:31
#1.플레이어 이동,공격(spcae를 누르면 레이져 프리팹 생성),레이져가 플레이어 위치에서 생성되어 날아가고 일정 위치에 도달하면 사라진다.
#2.적기 프리팹 생성(랜덤한 x축에 생성되어 아래방향으로 향하고 일정위치에서 제거된다), 랜덤한 확률로 Big,Midium,Small적기가 생성 (Small>Midium>Big순서로)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private float speed = 1f;
public GameObject laserPrefab;
//public GameObject enermyPrefab;
//private GameObject laserPrefab;
void Start()
{
//this.laser = GetComponent<GameObject>();
//this.enermyPrefab=GetComponent<GameObject>();
}
void Update()
{
//Instantiate(enermyPrefab);
//Input.GetAxis
var dirx=Input.GetAxisRaw("Horizontal"); //-1,0,1 //반환 타입 float
var diry=Input.GetAxisRaw("Vertical");
//Debug.LogFormat("{0}", dirx);
//이동
//방향*속도*시간
var dir=new Vector3(dirx,diry,0);
dir.Normalize();
this.transform.Translate(dir * speed * Time.deltaTime);
this.Attack();
}
private void Attack()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Debug.LogFormat("attack");
//레이져 생성
GameObject laserGo=Instantiate(laserPrefab);
laserGo.transform.position=this.transform.position;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LaserController : MonoBehaviour
{
// Start is called before the first frame update
private Animator anim;
void Start()
{
}
// Update is called once per frame
void Update()
{
float speed = 1.4f;
//var dir = new Vector3(0, 0.05f, 0);
//dir.Normalize();
this.transform.Translate(this.transform.up*speed*Time.deltaTime);
if (transform.position.y > 1.496f)
{
Destroy(gameObject);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnermyGenerator : MonoBehaviour
{
[SerializeField]
private GameObject []enermyPre;
/*private int[] dice= { 2, 4, 7 }; */ //랜덤한 확률로 적기 생성 (Small>Midium>Big)
private int span = 1;
private float delta;
void Update()
{
//enermy생성
this.delta += Time.deltaTime;
if(this.delta>span)
{
var random=Random.Range(0,enermyPre.Length);//랜덤한 enermy생성 0~enermy의 length
var randomEnermy=this.enermyPre[random];
var go=Instantiate(randomEnermy);
go.transform.position = new Vector3(Random.Range(-0.842f, 0.781f), 1.671f, 0);
this.delta = 0;
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enermy : MonoBehaviour
{
public enum eType
{
None = -1,
BIG,
MIDIUM,
SMALL
}
[SerializeField]
float speed; //적마다 스피드가 다름
void Start()
{
}
// Update is called once per frame
void Update()
{
this.transform.Translate(Vector3.down * this.speed * Time.deltaTime); //아래로*1f*시간
Debug.Log(this.transform.position);
//만약 -1.791에 도달하면 제거
if (this.transform.position.y< -1.791)
{
Destroy(this.gameObject);
}
}
}
#레이져의 재장전시간,충돌감지(레이져-적기/적기-플레이어) 그리고 이펙트 발생
if (Input.GetKeyDown(KeyCode.Space))
{
if (this.isReload)
{
Debug.LogFormat("attack");
this.Attack();
this.isReload=false;
}
else
{
Debug.Log("Reloading");
}
}
if (this.isReload == false)
{
this.delta += Time.deltaTime;
if (this.delta > this.reloadTime)
{
this.delta = 0;
this.isReload = true;
}
}
*재장전
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.tag=="Enermy") //적기와 충돌하면?
{
Destroy(this.gameObject); //플레이어 제거
//이펙트생성
this.exp = Instantiate(exp);
this.exp.transform.position = collision.transform.position;
//이펙트가 발생하지만 사라지지않는 버그 발견
//파괴된 플레이어는 일정 시간이 지나면 부활
}
}
*플레이어와 적기의 충돌감지, 충동헀다면 사라진다
rivate void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "Enermy")
{
Destroy(collision.gameObject); //맞은 적기 제거
Destroy(this.gameObject); //레이져 제거
Debug.Log("격추");
this.exp=Instantiate(this.exp);
this.exp.transform.position = this.transform.position;
}
}
*레이저가 적기와 충돌한다면? 적기가 사라진다
2/2
- 플레이어가 죽고 난후 일정시간 후에 다시 태어난다
- 이때 아래에서 위로 올라가야하며 약간 반투명 상태가 된다
- 일정시간동안 (반투명 상태 = 무적상태)이 지나면 일반 상태가 된다
- 배경 사운드 추가
-UI-score,time 표시
2/4 player의 무적상태 추가
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using UnityEngine;
using static UnityEditor.PlayerSettings;
public class PlayerController : MonoBehaviour
{
private float speed = 1f;
public GameObject laserPrefab;
private bool isReload=false; //재장전여부
private float reloadTime = 0.7f;
private float delta;
private bool immotal = false;
private float immotalTime = 2f;
public GameObject exp;
private SpriteRenderer sr;
private bool isImmotalMoving=false;
void Start()
{
this.isReload=true; //게임 시작은 장전상태
this.sr = this.GetComponent<SpriteRenderer>();
}
void Update()
{
float dirx = 0;
float diry = 0;
if(!this.isImmotalMoving)
{
dirx = Input.GetAxisRaw("Horizontal"); //-1,0,1 //반환 타입 float
diry = Input.GetAxisRaw("Vertical");
}
var dir = new Vector3(dirx, diry, 0);
dir.Normalize();
this.transform.Translate(dir * speed * Time.deltaTime);
if (Input.GetKeyDown(KeyCode.Space)&&!isImmotalMoving)
{
if (this.isReload)
{
Debug.LogFormat("attack");
this.Attack();
this.isReload = false;
}
else
{
Debug.Log("Reloading");
}
}
if (this.isReload == false)
{
this.delta += Time.deltaTime;
if (this.delta > this.reloadTime)
{
this.delta = 0;
this.isReload = true;
}
}
}
private void Attack()
{
Debug.LogFormat("attack!");
//레이져 생성
GameObject laserGo = Instantiate(laserPrefab);
laserGo.transform.position = this.transform.position;
//this.isReload = false;
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (this.immotal) return;
if(collision.gameObject.tag=="Enermy") //적기와 충돌하면?
{
immotal = true;
Debug.Log("game over");
//Destroy(this.gameObject); //플레이어 제거
//이펙트생성
this.exp = Instantiate(exp);
this.exp.transform.position = collision.transform.position;
this.StartCoroutine(this.Immotal());
this.StartCoroutine(this.ImmotalMove());
this.transform.position = new Vector3(0, -1.744f, 0);
this.immotal = true;
}
}
private IEnumerator Immotal() //IEnumerable과 혼동 주의
{
Debug.Log("무적 true");
var color=this.sr.color;
color.a=0.5f;
this.sr.color= color;
//this.sr.color
this.delta = 0;
while(true)
{
//무적시간동안 color.a값이 바뀜
delta+= Time.deltaTime;
color.a = Mathf.Lerp(this.sr.color.a, 1, Time.deltaTime);
this.sr.color=color;
//this.transform.Translate(new Vector3(0, -1.707f,0)*speed/2*delta);
//delta값이 immotalTime(2f)보다 커지면 반복문종료
if(delta>this.immotalTime) break;
yield return null;
}
Debug.Log("무적상태 false");
this.immotal = false;
color.a = 1;
this.sr.color= color;
}
private IEnumerator ImmotalMove()
{
//무적상태
this.isImmotalMoving=true;
Debug.Log(this.immotal);
var tPos = new Vector3(0, -1.09f,0); //y -1.09
while(true)
{
this.transform.position = Vector3.Lerp(this.transform.position, tPos, Time.deltaTime * 2); //tPos에 도달
var dis = Vector2.Distance(tPos, this.transform.position); //tpos와 position까지의 거리
if (dis <= 0.1f)
break;
yield return null;
}
this.isImmotalMoving = false;
Debug.Log(this.isImmotalMoving);
}
}
#코루틴 호출에는 문제가 없으나 다시 무적이 아닌상태로 돌아가지 않는다
#어디서인가 bool타입을 true로 만들어주고 있지 않은 것 같다
#enermy가 격추되면 item을 생성, player가 item과 충돌하면 item제거
#boom추가, boom과 enermy가 충돌하면 enermy제거
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Item : MonoBehaviour
{
private Animator anim;
private void OnTriggerEnter2D(Collider2D collision)
{
//player와 충돌하면 destroy
if(collision.tag=="Player")
{
Destroy(this.gameObject);
Debug.Log("get item");
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bom : MonoBehaviour
{
private Animator anim;
private float delta;
void Update()
{
this.delta += Time.deltaTime;
if (this.delta > 1.5)
{
this.delta = 0;
Destroy(this.gameObject);
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.tag=="Enermy")
{
//boom 과 enermy가 충돌하면 enermy제거
Destroy(collision.gameObject);
}
}
}
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class Enermy : MonoBehaviour
{
public enum eType
{
None = -1,
BIG,
MIDIUM,
SMALL
}
[SerializeField]
float speed; //적마다 스피드가 다름
[SerializeField]
private GameObject item;
// Update is called once per frame
void Update()
{
this.transform.Translate(Vector3.down * this.speed * Time.deltaTime); //아래로*1f*시간
//Debug.Log(this.transform.position);
//만약 -1.791에 도달하면 제거
if (this.transform.position.y< -1.791)
{
Destroy(this.gameObject);
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "Laser")
{
//item생성
var items = Instantiate(item);
items.transform.position = this.transform.position;
Debug.Log("item creat");
}
}
}
#누가 누구를 알아야하는지가 중요하다...
*2/10
#Enemy와 충돌 후 무적상태 기능 추가
#배경화면 스크롤 기능 추가
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private float speed = 2f;
public GameObject laser;
private float reloadtime = 0.4f;
private bool isReloading = false;
private float delta;
public GameObject explosionPrefab;
private bool isReloaded = false;
private bool isImmotal = false;
private float immotalTime = 2f;
private SpriteRenderer sr;
private bool isImmotalMoving = false;
void Start()
{
this.isReloading = true;
this.sr = this.GetComponent<SpriteRenderer>();
}
void Update()
{
var dirx=Input.GetAxisRaw("Horizontal");
var diry=Input.GetAxisRaw("Vertical");
var dir=new Vector3(dirx, diry, 0);
this.transform.Translate(dir.normalized*speed*Time.deltaTime);
if (Input.GetKeyDown(KeyCode.Space)&&!isImmotalMoving)
{
if (this.isReloading)
{
this.Shoot();
this.isReloading = false;
}
}
this.delta += Time.deltaTime;
if (this.delta > this.reloadtime)
{
this.delta = 0;
this.isReloading = true;
//Debug.Log("reloaded");
}
}
private void Shoot()
{
//Debug.Log("Attack!");
var bullet=Instantiate(this.laser);
bullet.transform.position=this.transform.position;
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (this.isImmotal) return;
if(collision.tag=="Enemy")
{
Debug.Log("Die");
var exp=Instantiate(this.explosionPrefab);
exp.transform.position=this.transform.position;
this.StartCoroutine("Immotal");
this.StartCoroutine("ImmotalMove");
this.transform.position = new Vector3(0, -1.744f, 0);//부활위치
this.isImmotal = true;
}
}
private IEnumerator ImmotalMove()
{
this.isImmotalMoving = true;
var tpos = new Vector3(0, -1.09f, 0);
while (true)
{
this.transform.position = Vector3.Lerp(this.transform.position, tpos, Time.deltaTime * 2);
var dis = Vector2.Distance(tpos, this.transform.position);
if (dis <= 0.1f)
break;
yield return null;
}
this.isImmotalMoving = false;
}
private IEnumerator Immotal()
{
var color = this.sr.color;
color.a = 0.5f;
this.sr.color = color;
float delta = 0;
while (true)
{
delta += Time.deltaTime;
color.a = Mathf.Lerp(this.sr.color.a, 1, Time.deltaTime);
this.sr.color = color;
if (delta > this.immotalTime)
{
break;
}
yield return null;
}
color.a = 1;
this.sr.color = color;
this.isImmotal = false;
}
}