1.현재 구현
- 플레이어 이동(조이스틱 or 키보드 둘 중 하나로 가능)
- 플레이어 공격(몬스터가 살아있는 상태에서 조이스틱을 놓을 경우(or 키보드를 건드리지 않을 경우) 플레이어는 몬스터를 공격)
- 플레이어 Idle(몬스터가 죽은 상태에서는 이동하지 않는 한 기본 상태)
- 몬스터는 아직 한 마리 구현
->generator를 구현하였으나 아직 게임을 관리해줄 game main을 못 만든 상태,,
- 몬스터 hp가 다 닳으면 소멸되도록 구현
2.구현 코드
(1) Player
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public enum eControlType
{
Keyboard, Joystick
}
public enum eState
{
Idle, Run, Shoot
}
[SerializeField]
private float moveSpeed=2f;
[SerializeField]
private VariableJoystick joystick;
private Transform tr;
[SerializeField]
private eControlType control;
private Monster monster;
[SerializeField]
private BulletGenerator bulletGenerator;
private Animator anim;
private bool isShoot = true;
private eState state;
private Coroutine shootCoroutine;
// Start is called before the first frame update
void Start()
{
tr = this.gameObject.transform;
this.anim=this.GetComponent<Animator>();
GameObject go = GameObject.FindGameObjectWithTag("Monster");
Debug.Log(go);
monster = go.GetComponent<Monster>();
monster.onDie = () =>
{
isShoot = false;
};
}
// Update is called once per frame
void Update()
{
float h, v;
if(control == eControlType.Keyboard)
{
h = Input.GetAxisRaw("Horizontal");
v = Input.GetAxisRaw("Vertical");
}
else
{
h = this.joystick.Direction.x;
v = this.joystick.Direction.y;
}
Vector3 dir = Vector3.forward * v + Vector3.right * h;
Debug.LogFormat("dir: {0}", dir);
if (dir != Vector3.zero)
{
float angle = Mathf.Atan2(dir.x, dir.z) * Mathf.Rad2Deg;
this.tr.localRotation = Quaternion.AngleAxis(angle, Vector3.up);
this.tr.Translate(dir.normalized * this.moveSpeed * Time.deltaTime, Space.World);
PlayAnimation(eState.Run);
}
else
{
if (isShoot)
this.Shoot();
else
PlayAnimation(eState.Idle);
}
}
private void Shoot()
{
Debug.LogFormat("monster: {0}", monster.transform.position);
this.tr.LookAt(monster.transform.position);
Debug.LogFormat("<color=yellow>rotation: {0}</color>", tr.rotation);
PlayAnimation(eState.Shoot);
if(shootCoroutine==null)
this.shootCoroutine = StartCoroutine(CoShoot());
}
private IEnumerator CoShoot()
{
anim.Play("Shoot", -1, 0f);
yield return new WaitForSeconds(0.015f);
bulletGenerator.Generate();
yield return new WaitForSeconds(0.485f);
this.shootCoroutine = null;
}
private void PlayAnimation(eState state)
{
this.state = state;
anim.SetInteger("State", (int)this.state);
}
}
(2) BulletGenerator
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletGenerator : MonoBehaviour
{
[SerializeField]
private Transform trans;
[SerializeField]
private GameObject bulletPrefab;
public void Generate()
{
GameObject go = Instantiate(bulletPrefab, trans);
go.transform.Translate(Vector3.forward*0.2f);
go.transform.parent = null;
}
}
(3) Bullet
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
private int damage = 1;
[SerializeField]
private float moveSpeed = 5f;
void Update()
{
this.transform.Translate(Vector3.forward*moveSpeed*Time.deltaTime);
if (this.transform.position.x >= 4 || this.transform.position.x <= -4 || this.transform.position.y >= 17 || this.transform.position.y <= -3)
Destroy(this.gameObject);
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Monster"))
{
Monster monster = other.GetComponent<Monster>();
monster.HitDamage(this.damage);
Destroy(this.gameObject);
}
}
}
(4) MonsterGenerator
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonsterGenerator : MonoBehaviour
{
[SerializeField]
private GameObject monsterPrefab;
// Start is called before the first frame update
void Start()
{
GameObject go = Instantiate(monsterPrefab);
}
// Update is called once per frame
void Update()
{
}
}
(5) Monster
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Monster : MonoBehaviour
{
private Transform tr;
private int hp;
public System.Action onDie;
// Start is called before the first frame update
void Start()
{
this.tr = this.gameObject.transform;
this.tr.position = new Vector3(2, 0, 8);
this.hp = 5;
}
// Update is called once per frame
/*void Update()
{
}*/
public void HitDamage(int damage)
{
this.hp -= damage;
if (this.hp <= 0)
this.Die();
}
void Die()
{
Destroy(this.gameObject);
this.onDie();
}
}
3. 결과
녹화를 프로그램 돌리기 전에 시작하지 못해서 나타난 움짤 모양(start 부분이 살짝 엉망,,)
지금 보니 콜라이더 모양도 다시 잡아야 될 것 같,,,
+추가로 구현해야되는 부분
- 몬스터 여러 마리 생성
- Game Main으로 게임 관리
->몬스터 리스트, 플레이어 프리팹 두고 game main에서 돌리기
- 몬스터 애니메이션 구현
- 그 밖 : 몬스터 플레이어 공격, 몬스터 아이템 드롭, 아이템에 따른 플레이어 성능 추가, 종스크롤 등등,,,
+구현하면서 포기한(?) 부분
플레이어도 프리팹으로 두고 등장시키고 싶었는데 조이스틱을 플레이어 스크립트 속성값에 넣으려니 Type mismatch가 떠버렸다. 검색을 해보니 Asset으로 저장해야 된다고 하는데 방법을 보다가 머리 터져서 pass (나중에 찬찬히 보기로,,,)
'K-digital traning > 유니티 심화' 카테고리의 다른 글
[주말과제]UGUI+데이터 연동(1) (0) | 2023.09.10 |
---|---|
HeroShooter에 new Input System 적용 (0) | 2023.09.03 |
[주말과제] HeroShooter stage1까지 (0) | 2023.08.28 |
OverlapSphere 연습 (0) | 2023.08.21 |
캐릭터 이동 후 normal(법선벡터)로 회전 (0) | 2023.08.21 |