일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 2022년
- 수학
- 다이나믹 프로그래밍
- c++
- 백준
- 6월
- 4월
- 2025년
- 기초
- 게임 엔진 공부
- 5월
- 개인 프로젝트
- 자료 구조
- 코딩 기초 트레이닝
- 프로그래머스
- 개인 프로젝트 - 런앤건
- 2월
- 2023년
- C/C++
- 2024년
- 유니티
- 코딩 테스트
- 1월
- 유니티 심화과정
- 입문
- 3월
- 단계별로 풀어보기
- todolist
- 골드메탈
- 7월
- Today
- Total
기록 보관소
[Unity/유니티] 기초-뱀서라이크: 회전하는 근접무기 구현[07] 본문
개요
유니티 독학을 위해 아래 링크의 골드메탈님의 영상들을 보고 직접 따라 해보면서 진행 상황을 쓰고 배웠던 점을 요약한다.
https://youtube.com/playlist?list=PLO-mt5Iu5TeYI4dbYwWP8JqZMC9iuUIW2
📚유니티 기초 강좌
유니티 게임 개발을 배우고 싶은 분들을 위한 기초 강좌
www.youtube.com
뱀서라이크: 회전하는 근접무기 구현[07]
1. 프리펩 만들기
//Bullet Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour {
public float damage; //피해량 변수
public int per; //관통 변수
//변수 초기화 함수
public void Init(float damage, int per) {
this.damage = damage;
this.per = per;
}
}
2. 충돌 로직 작성
// Enemy Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour {
public RuntimeAnimatorController[] animCon;
public float health;
public float maxHealth;
public float speed;
public Rigidbody2D target; //쫓아갈 타겟(플레이어)
bool isLive;
Animator anim;
Rigidbody2D rigid;
SpriteRenderer spriter;
void Awake() {
anim = GetComponent<Animator>();
rigid = GetComponent<Rigidbody2D>();
spriter = GetComponent<SpriteRenderer>();
}
void FixedUpdate() {
if (!isLive)
return;
Vector2 dirVec = target.position - rigid.position; // 방향 = 위치 차이의 정규화(Normalized). 위치 차이 = 타겟 위치 - 나의 위치.
Vector2 nextVec = dirVec.normalized * speed * Time.fixedDeltaTime;
rigid.MovePosition(rigid.position + nextVec); //플레이어의 키 입력값을 더한 이동 = 몬스터의 방향 값을 더한 이동
rigid.velocity = Vector2.zero; //물리 속도가 이동에 영향을 주지 않도록 속도 제거
}
void LateUpdate() {
if (!isLive)
return;
spriter.flipX = target.position.x < rigid.position.x;
}
void OnEnable() {
target = GameManager.instance.player.GetComponent<Rigidbody2D>(); //플레이어 할당
isLive = true;
health = maxHealth;
}
//데이터를 가져오기 위한 초기화 함수
public void Init(SpawnData data) {
anim.runtimeAnimatorController = animCon[data.spriteType];
speed = data.speed;
maxHealth = data.health;
health = data.health;
}
void OnTriggerEnter2D(Collider2D collision) {
if (!collision.CompareTag("Bullet"))
return;
health -= collision.GetComponent<Bullet>().damage; //총알 데미지만큼 Enemy 체력 감소
if(health > 0) {
// .. Live, Hit Action
}
else {
// .. Die
Dead();
}
}
void Dead() {
gameObject.SetActive(false);
}
}
3. 근접 무기 배치
//Weapon Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon : MonoBehaviour {
public int id;
public int prefabId;
public float damage;
public int count;
public float speed;
void Start() {
Init();
}
void Update() {
}
public void Init() {
switch (id) {
case 0:
speed = -150;
Batch();
break;
default:
break;
}
}
void Batch() { //생성된 무기를 배치하는 함수
for (int index = 0; index < count; index++) {
Transform bullet = GameManager.instance.pool.Get(prefabId).transform;
bullet.parent = transform;
bullet.GetComponent<Bullet>().Init(damage, -1); //-1 is Infinity Per. 무한 관통.
}
}
}
//Weapon Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon : MonoBehaviour {
public int id;
public int prefabId;
public float damage;
public int count;
public float speed;
void Start() {
Init();
}
void Update() {
switch (id) {
case 0:
transform.Rotate(Vector3.back * speed * Time.deltaTime);
break;
default:
break;
}
}
public void Init() {
switch (id) {
case 0:
speed = -150;
Batch();
break;
default:
break;
}
}
void Batch() { //생성된 무기를 배치하는 함수
for (int index = 0; index < count; index++) {
Transform bullet = GameManager.instance.pool.Get(prefabId).transform;
bullet.parent = transform;
bullet.GetComponent<Bullet>().Init(damage, -1); //-1 is Infinity Per. 무한 관통.
}
}
}
- 근접 무기가 빙글빙글 돌 수 있게 Update()를 수정
- 이후 두 번째 테스트 플레이를 한다.
4. 근접 무기 배치
- 근접 무기 개수가 늘어날 때마다 순서대로 360을 나눈 값을 Z축에 적용한다.
- 무기의 위치는 회전한 상태에서 자신의 위쪽으로 이동한다.
//Weapon Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon : MonoBehaviour {
public int id;
public int prefabId;
public float damage;
public int count;
public float speed;
void Start() {
Init();
}
void Update() {
switch (id) {
case 0:
transform.Rotate(Vector3.back * speed * Time.deltaTime);
break;
default:
break;
}
}
public void Init() {
switch (id) {
case 0:
speed = -150;
Batch();
break;
default:
break;
}
}
void Batch() { //생성된 무기를 배치하는 함수
for (int index = 0; index < count; index++) {
Transform bullet = GameManager.instance.pool.Get(prefabId).transform;
bullet.parent = transform;
Vector3 rotVec = Vector3.forward * 360 * index / count; //개수에 따라 360도 나누기
bullet.Rotate(rotVec);
bullet.Translate(bullet.up * 1.5f, Space.World); //무기 위쪽으로 이동
bullet.GetComponent<Bullet>().Init(damage, -1); //-1 is Infinity Per. 무한 관통.
}
}
}
5. 레벨에 따른 배치
//Weapon Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon : MonoBehaviour {
public int id;
public int prefabId;
public float damage;
public int count;
public float speed;
void Start() {
Init();
}
void Update() {
switch (id) {
case 0:
transform.Rotate(Vector3.back * speed * Time.deltaTime);
break;
default:
break;
}
//Test Code
if(Input.GetButtonDown("Jump")) {
LevelUp(20, 5);
}
}
public void LevelUp(float damage, int count) {
this.damage = damage;
this.count += count;
if (id == 0)
Batch();
}
public void Init() {
switch (id) {
case 0:
speed = -150;
Batch();
break;
default:
break;
}
}
void Batch() { //생성된 무기를 배치하는 함수
for (int index = 0; index < count; index++) {
Transform bullet;
if (index < transform.childCount) {
bullet = transform.GetChild(index); //기존 오브젝트가 있으면 먼저 활용
}
else {
bullet = GameManager.instance.pool.Get(prefabId).transform; //모자라면 풀링에서 가져옴
bullet.parent = transform;
}
bullet.localPosition = Vector3.zero; //무기 위치 초기화
bullet.localRotation = Quaternion.identity; //무기 회전값 초기화
Vector3 rotVec = Vector3.forward * 360 * index / count; //개수에 따라 360도 나누기
bullet.Rotate(rotVec);
bullet.Translate(bullet.up * 1.5f, Space.World); //무기 위쪽으로 이동
bullet.GetComponent<Bullet>().Init(damage, -1); //-1 is Infinity Per. 무한 관통.
}
}
}
- 테스트를 위해 스페이스바(점프키)를 누르면 레벨 업을 해서 데미지와 무기 개수를 늘어나게 했다.
- Batch 함수를 수정해서 레벨 업시 무기가 늘어나서 위치가 엉키거나, 엉뚱한 위치에 생성되는 경우를 방지한다.
'유니티 프로젝트 > 뱀서라이크' 카테고리의 다른 글
[Unity/유니티] 기초-뱀서라이크: 타격감 있는 몬스터 처치 만들기[09] (0) | 2023.07.10 |
---|---|
[Unity/유니티] 기초-뱀서라이크: 자동 원거리 공격 구현[08] (0) | 2023.06.04 |
[Unity/유니티] 기초-뱀서라이크: 소환 레벨 적용하기[06+] (0) | 2023.05.29 |
[Unity/유니티] 기초-뱀서라이크: 오브젝트 풀링으로 소환하기[06] (0) | 2023.05.28 |
[Unity/유니티] 기초-뱀서라이크: 몬스터 만들기[05] (0) | 2023.05.22 |