2023. 12. 7. 22:10ㆍ스파르타코딩클럽 게임개발
프로젝트가 끝났다.
발표도 마무리 되었고 코드 피드백은 받지 않았지만 기분 좋았다.
https://youtu.be/Iq0WOOD30RE?si=WkC-ZUF7DKxhQXfO
나는 여기서 스토리 몬스터, 몬스터 스프라이트를 맡았는데
더욱 많은 기능을 만들고 싶었지만 아쉽게도 유니티에 관련한 지식이 부족하여 더이상 기능을 추가 하지 못했다.
강의를 좀더 자세히 들었다면 더욱 기능을 추가할 수 있었겠지만 참 아쉽다.
스토리 신도 이미와 대사를 추가하고 좀 더 박진감있게 만들고 싶었지만 그러지 못했다.
하고싶은것이 많았기에 더욱 아쉬웠다.
우리 팀원들도 정말 열심히 했다..
내가 부족해서 몬스터 구현에 시간을 많이 잡아먹었다.;
조금더 공부하자
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Monster : MonoBehaviour
{
public float speed;
public float health;
public float maxHealth;
public float Damege;
public bool IsBoss;
bool isLive;
public RuntimeAnimatorController\[\] animCon;
public Rigidbody2D target;
public AudioClip HitAudio;
Rigidbody2D rigid;
Collider2D coll;
Animator anim;
SpriteRenderer spriter;
WaitForFixedUpdate wait;
AudioSource ApplyDamage;
// \[우진영\] 드랍 아이템 연결을 위해 추가
public int exp;
public int money;
GameObject expPrefab;
GameObject moneyPrefab;
private void Awake()
{
ApplyDamage = GetComponent<AudioSource>();
rigid = GetComponent<Rigidbody2D>();
spriter = GetComponent<SpriteRenderer>();
anim = GetComponent<Animator>();
wait = new WaitForFixedUpdate();
coll = GetComponent<Collider2D>();
expPrefab = Resources.Load<GameObject>("Item/Droppable/Droppable Exp");
moneyPrefab = Resources.Load<GameObject>("Item/Droppable/Droppable Money");
}
void FixedUpdate()
{
if (IsBoss)
{
transform.localScale = new Vector3(10, 10, 1);
transform.localRotation = Quaternion.identity;
}
if (!isLive || anim.GetCurrentAnimatorStateInfo(0).IsName("Hit")) return;
Vector2 dirVec = target.position - rigid.position;
Vector2 nextVec = dirVec.normalized \* speed \* Time.fixedDeltaTime;
rigid.MovePosition(rigid.position + nextVec);
rigid.velocity = Vector2.zero;
}
private void LateUpdate()
{
if (GameManager.Instance.player.isDead) return;
if (!isLive) return;
spriter.flipX = target.position.x < rigid.position.x;
}
private void OnEnable()
{
target = GameManager.Instance.player.GetComponent<Rigidbody2D>();
isLive = true;
coll.enabled = true;
rigid.simulated = true;
spriter.sortingOrder = 2;
anim.SetBool("Dead", false);
health = maxHealth;
}
public void Init(SpawnData data)
{
anim.runtimeAnimatorController = animCon\[data.spriteType\];
speed = data.speed;
maxHealth = data.health;
health = data.health;
Damege = data.Damege;
IsBoss = data.IsBoss;
exp = data.exp;
money = data.money;
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (!collision.CompareTag("Weapon") || !isLive) return;
if (collision.GetComponent<Weapon>() != null)
health -= collision.GetComponent<Weapon>().Damage;
if (health > 0)
{
StartCoroutine(KnockBack());
ApplyDamage.clip = HitAudio;
ApplyDamage.Play();
anim.SetTrigger("Hit");
}
else
{
isLive = false;
coll.enabled = false;
rigid.simulated = false;
spriter.sortingOrder = 1;
anim.SetBool("Dead", true);
}
}
IEnumerator KnockBack()
{
yield return wait; // 다음 하나의 물리 프레임까지 기다림
Vector3 playerPos = GameManager.Instance.player.transform.position;
Vector3 dirVec = transform.position - playerPos;
rigid.AddForce(dirVec.normalized \* 3, ForceMode2D.Impulse);
}
void Attack()
{
anim.SetTrigger("Attack");
}
void Dead()
{
gameObject.SetActive(false);
var expObj = Instantiate(expPrefab, transform.position, Quaternion.identity).GetComponent<Droppable\_EXP>();
var moneyObj = Instantiate(moneyPrefab, transform.position, Quaternion.identity).GetComponent<Droppable\_Money>();
expObj.value = exp;
moneyObj.value = money;
if (IsBoss) GameManager.Instance.GameOver(true);
transform.localScale = new Vector3(1, 1, 1);
transform.localRotation = Quaternion.identity;
spriter.color = Color.white;
}
}
나의 몬스터 스크립트다.
여기에는 의도치 않는 코드가 있는데 바로 이부분인데
transform.localScale = new Vector3(1, 1, 1);
transform.localRotation = Quaternion.identity;
spriter.color = Color.white;
원래 dead가 아닌 OnEnable에서 실행되었어야 하는 코드다.
하지만 애니매이션이 거의 끝나는 상황에 저 OnEnable이 실행되어서 애니매이션 마지막의 장면에 있는
스케일과 컬러 등 속성들이 그대로 옮겨지면서 새로 생겨나게 된다.
그러면 죽으면서 쓰러진 몬스터가 그 모습 그대로 다시 생성되서 누운채로 몬스터가 나타나는 것.
이 문제를 해결하기 위해 튜터님과 상담을 하였는데
코드로서 문제 해결은 하지 말고 run 애니매니션을 시작할때 스케일과 컬러 그리고 로테이션을 기본상태로 조정하면
간편하게 해결 할 수 있다고 헀다.
다른 방법도 있는데 애니매이션을 강제로 코드로서 변환시켜 실행시킬수 있다고 한다.
그 방법을 사용하면 런으로 실행되면서 dead가 끝나기 때문에 다시 생성될때는 원래 상태 그대로 생성되는것
하지만 그 방법을 사용하면 코드와 애니매이터 두가지에서 애니매이션을 조정하게 되기 때문에
한눈에 보기 어렵다고 한다.
그렇기 때문에 코드로만 사용하던가 애니매이터로만 사용해서 애니매이션을 조정하는 것이 중요하다.
'스파르타코딩클럽 게임개발' 카테고리의 다른 글
오늘은 스파르타 코딩 클럽 unity 게임 개발 과정 31일차(코드카타와 레이어 비트연산 ) (0) | 2023.12.11 |
---|---|
오늘은 스파르타 코딩 클럽 unity 게임 개발 과정 30일차(ScriptableObject 메뉴 만들기 신박한 [Range] ) (1) | 2023.12.08 |
오늘은 스파르타 코딩 클럽 unity 게임 개발 과정 28일차(버그 수정) (1) | 2023.12.07 |
오늘은 스파르타 코딩 클럽 unity 게임 개발 과정 27일차(팀 프로젝트) (1) | 2023.12.05 |
저번주 금요일은 스파르타 코딩 클럽 unity 게임 개발 과정 25일차(팀 프로젝트) (1) | 2023.12.04 |