일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- 모작
- 드래곤 플라이트 모작
- VR
- Oculus
- 길건너 친구들
- meta xr
- 유니티 UI
- 오큘러스
- CGV
- 가상현실
- 앱 배포
- 멀티플레이
- 오브젝트 풀링
- 포트폴리오
- 유니티
- 팀 프로젝트
- Photon Fusion
- 팀프로젝트
- 개발일지
- 개발
- 유니티 Json 데이터 연동
- 유니티 GUI
- XR
- ChatGPT
- input system
- OVR
- 연습
- HAPTIC
- meta
- 드래곤 플라이트
Archives
- Today
- Total
EasyCastleUNITY
간단 RPG 2 본문
구현이 된 부분
영웅이 이동하여 몬스터를 공격하는 애니메이션을 실행하는 부분까지
구현이 안 된 부분
몬스터가 피격시 몬스터가 피격되는 애니메이션을 실행하는 부분
Test_PlayerControlSceneMain -> 전체적인 실행을 하는 클래스
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Test;
public class Test_PlayerControlSceneMain : MonoBehaviour
{
[SerializeField]
private HeroController heroController;
// Start is called before the first frame update
void Start()
{
this.heroController.onMoveComplete = (target) =>{
Debug.Log("<color=cyan>이동을 완료 했습니다.</color>");
//타겟이 있다면 공격 애니메이션 실행
if(target != null){
this.heroController.Attack(target);
}
};
}
// Update is called once per frame
void Update()
{
//화면을 클릭하면 클릭한 위치로 Hero가 이동
if (Input.GetMouseButtonDown(0))
{
//Ray를 만든다
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
float maxDistance = 1000f;
//화면에 출력
Debug.DrawRay(ray.origin, ray.direction * maxDistance, Color.red, 2f);
//충돌검사
RaycastHit hit;
if (Physics.Raycast(ray, out hit, maxDistance))
{
//클릭한 오브젝트가 몬스터라면
if(hit.collider.tag == "Monster")
{
//거리를 구한다
float distance =Vector3.Distance(this.heroController.gameObject.transform.position,
hit.collider.gameObject.transform.position);
MonsterController monsterController =
hit.collider.gameObject.GetComponent<MonsterController>();
//각 반지름 더한거와 비교
float sumRadius = this.heroController.radius + monsterController.radius;
Debug.LogFormat("<color=green>distance:{0}, sumRadius:{1}</color>",
distance, sumRadius);
//사거리 안에 들어옴
if(distance <= sumRadius)
{
//공격
}
else
{
//이동
this.heroController.Move(monsterController);
}
}
else if(hit.collider.tag =="Ground")
{
//충돌정보가 hit 변수에 담김
Debug.Log(hit.point); //월드 상의 충돌 지점 위치
//Hero Gameobject 이동
this.heroController.Move(hit.point);
}
}
}
}
}
HeroController -> 영웅을 조종하는 클래스
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Test
{
public class HeroController : MonoBehaviour
{
private Vector3 targetPosition; //타겟이 되는 위치
private Coroutine moveRoutine; //전에 실행하던 코루틴을 저장하는 변수
private Animator anim; //Hero의 Animator
public System.Action<MonsterController> onMoveComplete;
[SerializeField]
public float radius=1.0f; //Hero 사거리
private MonsterController target; //target이 된 몬스터의 MonsterController 컴포넌트
// Start is called before the first frame update
void Start()
{
this.anim = this.GetComponent<Animator>();
}
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 필수
{
//방향을 바라봄
this.transform.LookAt(targetPosition);
//이미 바라봤으니깐 정면으로 이동 (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);
//대리자 호출
this.onMoveComplete(this.target);
}
private void OnDrawGizmos()
{
GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, 1, 40);
}
public void Attack(MonsterController target)
{
this.anim.SetInteger("State", 2);
//코루틴 함수 호출
this.StartCoroutine(this.CoAttack());
}
private IEnumerator CoAttack()
{
//Attack 애니메이션의 0.1초에서 Impact가 발생
yield return new WaitForSeconds(0.1f); // 0.1초 이후
//밑에 주석문과 같은 효과
//float elapsedTime = 0;
//while (true) {
// elapsedTime += Time.deltaTime;
// if (elapsedTime > 0.1f) {
// break;
// }
// yield return null;
//}
Debug.Log("<color=red>Impact!!!!!!!!!!</color>");
//0.83 - 0.1 => 0.83은 Hero의 Attack 애니메이션의 길이
yield return new WaitForSeconds(0.73f);
Debug.Log("Attack 애니메이션 종료");
this.anim.SetInteger("State", 0); //기본동작으로 전환
}
}
}
MonsterController -> 몬스터에대한 정보 및 기능을 하는 클래스
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonsterController : MonoBehaviour
{
public float radius = 1;
private Animator anim;
public int hp;
// Start is called before the first frame update
void Start()
{
this.anim = this.GetComponent<Animator>();
this.hp = 3;
}
// Update is called once per frame
void Update()
{
if (this.hp <= 0)
{
this.hp = 0;
this.anim.SetInteger("MonsterState", 1); //사망
}
else
{
this.anim.SetInteger("MonsterState", 0); //대기
}
}
//이벤트 함수
private void OnDrawGizmos()
{
GizmosExtensions.DrawWireArc(this.transform.position, this.transform.forward, 360, 1, 40);
}
public void SetHp(int hp)
{
this.hp = hp;
}
public int GetHp()
{
return this.hp;
}
public Animator GetAnim()
{
return this.anim;
}
}
몬스터 피격 애니메이션
아직 여기서 영웅이 공격을 할 때 정확히 피격애니메이션이 나오도록 해야한다.
'유니티 기초' 카테고리의 다른 글
코드 베이스로 버튼 실행 (0) | 2023.08.09 |
---|---|
간단 RPG 2-1 (몬스터 피격 애니메이션) (0) | 2023.08.08 |
간단 RPG (0) | 2023.08.08 |
유니티 코루틴 (0) | 2023.08.08 |
바구니로 떨어지는 사과 받기 (여러가지 요소 추가) (0) | 2023.08.07 |