일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- meta
- CGV
- 드래곤 플라이트 모작
- HAPTIC
- 유니티 UI
- 모작
- OVR
- meta xr
- 유니티 Json 데이터 연동
- XR
- 오큘러스
- 연습
- 오브젝트 풀링
- 팀프로젝트
- 멀티플레이
- Oculus
- 유니티 GUI
- 유니티
- 가상현실
- 팀 프로젝트
- Photon Fusion
- 앱 배포
- 개발
- 길건너 친구들
- 개발일지
- VR
- input system
- 드래곤 플라이트
- ChatGPT
- 포트폴리오
Archives
- Today
- Total
EasyCastleUNITY
간단 RPG Test3 (불완전한 장착) 본문
GameEnums
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Test3
{
public class GameEnums
{
public enum eMonsterType
{
Turtle, Slime
}
public enum eItemType
{
Shield, Sword, Potion
}
}
}
MonsterGenerator
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
namespace Test3
{
public class MonsterGenerator : MonoBehaviour
{
//[SerializeField] private GameObject turtlePrefab;
//[SerializeField] private GameObject slimePrefab;
[SerializeField]
private List<GameObject> prefabList; //동적배열 (사용전 반드시 인스턴스화)
// Start is called before the first frame update
void Start()
{
foreach(GameObject prefab in prefabList)
{
Debug.LogFormat("Monster prefab : {0}", prefab.name);
}
}
/// <summary>
/// 몬스터 생성
/// </summary>
/// <param name="monsterType">생성 하려고 하는 몬스터의 타입</param>
/// <param name="initPosition">생성된 몬스터의 초기 월드좌표</param>
public MonsterController Generate(GameEnums.eMonsterType monsterType, Vector3 initPosition)
{
Debug.LogFormat("monsterType :{0}", monsterType);
//몬스터 타입에 따라 어떤 프리팹으로 프리팹 복사본(인스턴스)를 생성할지 결정 해야 함
int index = (int)monsterType;
Debug.LogFormat("index: {0}", index);
GameObject prefab = this.prefabList[index];
Debug.LogFormat("Monsterprefab: {0}", this.prefabList[index].name);
//프리팹 인스턴스를 생성
GameObject go =Instantiate(prefab);
//MonsterController가 부착되어 있지 않다면
//if (go.GetComponent<MonsterController>() == null)
//{
// //동적으로 컴포넌트를 부착 할수 있음
// MonsterController controller = go.AddComponent<MonsterController>();
//}
//위치 설정
go.transform.position = initPosition;
return go.GetComponent<MonsterController>();
}
}
}
MonsterController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Test3
{
public class MonsterController : MonoBehaviour
{
[SerializeField]
private GameEnums.eItemType type;
private Animator anim;
public System.Action <GameEnums.eItemType>onDie;
private void Awake()
{
this.anim = GetComponent<Animator>();
}
public void Die()
{
StartCoroutine(this.CoDie());
}
private IEnumerator CoDie()
{
this.anim.SetInteger("MonsterState", 2);
yield return new WaitForSeconds(2.0f);
this.onDie(this.type);
}
}
}
ItemGenerator
using System.Collections;
using System.Collections.Generic;
using Test;
using UnityEngine;
namespace Test3
{
public class ItemGenerator : MonoBehaviour
{
[SerializeField]
private List<GameObject> prefabList; //동적배열 (사용전 반드시 인스턴스화)
// Start is called before the first frame update
void Start()
{
foreach(GameObject prefab in prefabList)
{
Debug.LogFormat("Item prefab :{0}",prefab.name);
}
}
/// <summary>
/// 아이템 생성
/// </summary>
/// <param name="itemType">생성하려고 하는 아이템의 타입</param>
/// <param name="initPosition">생성한 아이템의 초기 월드 좌표</param>
/// <returns></returns>
public ItemController Generate(GameEnums.eItemType itemType,Vector3 initPosition)
{
Debug.LogFormat("itemType :{0}", itemType);
int index = (int)itemType;
Debug.LogFormat("index: {0}", index);
GameObject prefab = this.prefabList[index];
Debug.LogFormat("Item prefab: {0}", this.prefabList[index].name);
//프리팹 인스턴스 생성
GameObject go =Instantiate(prefab);
go.transform.position = initPosition;
return go.GetComponent<ItemController>();
}
}
}
ItemController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Test3
{
public class ItemController : MonoBehaviour
{
[SerializeField]
private GameEnums.eItemType itemType;
public GameEnums.eItemType ItemType
{
get { return this.itemType; }
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
}
HeroGenerator
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HeroGenerator : MonoBehaviour
{
[SerializeField]
private GameObject heroPrefab;
// Start is called before the first frame update
void Start()
{
}
public GameObject Generate(Vector3 initPosition)
{
GameObject prefab = this.heroPrefab;
//프리팹 인스턴스를 생성
GameObject go = Instantiate(prefab);
//위치 설정
go.transform.position = initPosition;
return go;
}
}
HeroController
using System.Collections;
using System.Collections.Generic;
using Test;
using UnityEngine;
using static Test3.GameEnums;
namespace Test3
{
public class HeroController : MonoBehaviour
{
private Vector3 targetPosition; //타겟이 되는 위치
private Coroutine moveRoutine; //전에 실행하던 코루틴을 저장하는 변수
private Animator anim; //Hero의 Animator
[SerializeField]
ItemGenerator itemGenerator;
[SerializeField]
public float radius = 1.0f; //Hero 사거리
private MonsterController target; //target이 된 몬스터의 MonsterController 컴포넌트
private int index = 0;
private List<ItemController> getItems;
// Start is called before the first frame update
void Start()
{
this.getItems = new List<ItemController>();
this.anim = this.GetComponent<Animator>();
GameObject main = GameObject.Find("ItemGenerator");
this.itemGenerator = main.GetComponent<ItemGenerator>();
}
public void Move(MonsterController target)
{
this.target = target;
this.targetPosition = this.target.gameObject.transform.position;
this.anim.SetInteger("State", 1);
if (this.moveRoutine != null)
{
//이미 코루틴이 실행중이다 -> 중지
this.StopCoroutine(this.moveRoutine);
}
this.moveRoutine = this.StartCoroutine(this.CoMove());
}
public void Move(Vector3 targetPosition)
{
//타겟을 지움
this.target = null;
//이동할 목표 지점을 저장
this.targetPosition = targetPosition;
Debug.Log("Move");
//이동 애니메이션 실행
this.anim.SetInteger("State", 1);
if (this.moveRoutine != null)
{
//이미 코루틴이 실행중이다 -> 중지
this.StopCoroutine(this.moveRoutine);
}
this.moveRoutine = StartCoroutine(this.CoMove());
}
private IEnumerator CoMove()
{
while (true)
//무한 반복이 되어 유니티가 멈출 수도 있음
//그러므로 yield return 필수
{
Vector3 pos = new Vector3(targetPosition.x, 0, targetPosition.z);
//방향을 바라봄
this.transform.LookAt(pos);
//이미 바라봤으니깐 정면으로 이동 (relateTo: Self/지역좌표)
//방향 * 속도 * 시간
this.transform.Translate(Vector3.forward * 2f * Time.deltaTime);
//목표지점과 나 사이의 거리를 계산, 즉 1프레임 마다 거리를 계산
float distance = Vector3.Distance(this.transform.position, this.targetPosition);
//타겟이 있을 경우
if (this.target != null)
{
if (distance <= (1f + 1f))
{
break;
}
}
else
{
if (distance <= 0.1f)
{
//도착
break;
}
}
yield return null; //다음 프레임 시작
}
Debug.Log("<color=yellow>도착!</color>");
this.anim.SetInteger("State", 0);
}
private void OnDrawGizmos()
{
GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, 1, 40);
}
private void OnTriggerEnter(Collider other)
{
if(other.gameObject.tag == "Item")
{
this.GetItem(other);
}
}
private void GetItem(Collider other)
{
GameEnums.eItemType itemType = other.gameObject.GetComponent<ItemController>().ItemType;
this.getItems.Add(other.GetComponent<ItemController>());
Debug.LogFormat("<color=lime>{0}을 획득</color>" ,other.gameObject.name);
if (itemType == GameEnums.eItemType.Sword)
{
Transform rootChild = this.gameObject.transform.Find("root");
Transform pelvisChild = rootChild.Find("pelvis");
Transform weaponChild = pelvisChild.Find("Weapon");
Vector3 weaponPos = weaponChild.GetChild(0).gameObject.transform.position;
Destroy(weaponChild.GetChild(0).gameObject); //전에 장착하고 있던 검 삭제
other.gameObject.transform.position = weaponPos;
other.gameObject.transform.SetParent(weaponChild, false);
}
else if (itemType == GameEnums.eItemType.Shield)
{
Transform rootChild = this.gameObject.transform.Find("root");
Transform pelvisChild = rootChild.Find("pelvis");
Transform shieldChild = pelvisChild.Find("Shield");
Vector3 shieldPos = shieldChild.GetChild(0).gameObject.transform.position;
Destroy(shieldChild.GetChild(0).gameObject); //전에 장착하고 있던 방패 삭제
other.gameObject.transform.position = shieldPos;
other.gameObject.transform.SetParent(shieldChild, false);
}
//other.gameObject.transform.SetParent(this.transform);
Debug.LogFormat("getItemList: {0}", getItems[index].name);
index++;
}
// Update is called once per frame
}
}
Main
using System.Collections;
using System.Collections.Generic;
using Test;
using UnityEngine;
namespace Test3
{
//씬의 모든 객체들을 관리하는 클래스 (컴포넌트)
public class Test3_CreatePortalMain : MonoBehaviour
{
[SerializeField]
private MonsterGenerator monsterGenerator;
[SerializeField]
private ItemGenerator itemGenerator;
[SerializeField]
private HeroGenerator heroGenerator;
[SerializeField]
private GameObject portalPrefab;
[SerializeField]
private GameObject portalFxPrefab;
private bool PortalisNotCreate = true;
private bool HeroisNotCreate = true;
private List<MonsterController> monsterList;
private List<ItemController> itemList;
private GameObject heroGo;
public ItemGenerator ItemGene
{
get { return this.itemGenerator; }
}
RaycastHit hit;
// Start is called before the first frame update
void Start()
{
//컬렉션 사용전 반드시 초기화
this.monsterList = new List<MonsterController>();
this.itemList = new List<ItemController>();
//몬스터 동적 생성
MonsterController turtle = this.monsterGenerator.Generate(GameEnums.eMonsterType.Turtle
,new Vector3(-3,0,0));
turtle.onDie = (type) =>{
this.CreateDropItem(type);
Destroy(turtle.gameObject);
};
MonsterController slime = this.monsterGenerator.Generate(GameEnums.eMonsterType.Slime
, new Vector3(0, 0, 3));
slime.onDie = (type) => {
this.CreateDropItem(type);
Destroy(slime.gameObject);
};
//만들어진 객체들을 그룹화 관리
//동적 배열
this.monsterList.Add(turtle);
this.monsterList.Add(slime);
Debug.LogFormat("this.monsterList.Count:{0}",this.monsterList.Count);
//리스트의 요소 출력
foreach(MonsterController monster in this.monsterList)
{
Debug.LogFormat("monster:{0}", monster.name);
}
}
private void CreatePortal()
{
if (this.monsterList.Count <= 0 && this.PortalisNotCreate == true)
{
Debug.Log("<color=lime>포탈이 생성됩니다!</color>");
GameObject portalGo = Instantiate(portalPrefab);
int posX = Random.Range(-4, 5);
int posZ = Random.Range(-4, 5);
portalGo.transform.position = new Vector3(posX, 0, posZ);
GameObject portalFx = Instantiate(portalFxPrefab);
portalFx.transform.position = portalGo.transform.position;
this.PortalisNotCreate = false;
}
}
private void MonsterDestory()
{
MonsterController monster = hit.collider.gameObject.GetComponent<MonsterController>();
//몬스터 제거
this.monsterList.Remove(monster);
monster.Die();
//남은 수 확인
Debug.LogFormat("<color=yellow>몬스터 남은 수: {0}</color>",
this.monsterList.Count);
}
private void CreateDropItem(GameEnums.eItemType type)
{
//드롭 아이템 생성
Vector3 itemPos = new Vector3(hit.collider.gameObject.transform.position.x,
hit.collider.gameObject.transform.position.y,
hit.collider.gameObject.transform.position.z);
ItemController dropItem = this.itemGenerator.Generate(type, itemPos);
this.itemList.Add(dropItem);
Debug.LogFormat("<color=yellow>드롭 아이템 {0} 생성</color>", dropItem.name);
}
private void CreateHero()
{
int posX = Random.Range(-4, 5);
int posZ = Random.Range(-4, 5);
if(this.monsterList.Count <= 0 && this.HeroisNotCreate == true)
{
//히어로 동적 생성
this.heroGo = this.heroGenerator.Generate(new Vector3(posX, 0.0f, posZ));
this.HeroisNotCreate = false;
}
}
private IEnumerator CoCreate()
{
yield return new WaitForSeconds(2.0f);
this.CreateHero();
this.CreatePortal();
}
// Update is called once per frame
void Update()
{
//Test
//Ray연습 겹 클릭해서 선택 몬스터 제거
if(Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
float maxDistance = 1000f;
Debug.DrawRay(ray.origin, ray.direction * maxDistance, Color.red, 2f);
if(Physics.Raycast(ray, out hit , maxDistance))
{
Debug.LogFormat("<color=red>{0}</color>",hit.collider.tag);
if(hit.collider.tag == "Monster")
{
this.MonsterDestory();
}
if (hit.collider.tag == "Ground" && HeroisNotCreate == false)
{
Debug.Log(hit.point);
this.heroGo.GetComponent<HeroController>().Move(hit.point);
}
if(hit.collider.tag == "Item" && HeroisNotCreate == false)
{
Debug.Log(hit.point);
this.heroGo.GetComponent<HeroController>().Move(hit.point);
}
StartCoroutine(this.CoCreate());
}
}
}
}
}
0.시작되면 동적 생성으로 몬스터가 생성된다.
1.Ray를 통해 몬스터를 죽인다.
2. 2초후에 몬스터가 죽은 자리에 드롭아이템이 생성된다.
3. 모든 몬스터가 죽고 2초후에, 포탈과 영웅이 만들어진다.
4. Ray를 쏘면 영웅이 해당 좌표로 이동한다.
5.아이템을 찍고 이동하면, 현재 장착하고 있던 아이템이 삭제되고, 장착이 된다. (불완전)
'유니티 기초' 카테고리의 다른 글
간단 RPG (0) | 2023.08.11 |
---|---|
간단 RPG Test3 (완전한 장착) 2023/08/10 11:19pm 작성 (0) | 2023.08.10 |
간단 RPG Test 3-1 (0) | 2023.08.10 |
간단 RPG Game Main (몬스터가 전부 죽으면, 포탈 생성) (1) | 2023.08.09 |
간단 RPG 게임 메인(수정중) (0) | 2023.08.09 |