HeroController
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Test
{
public class HeroController : MonoBehaviour
{
private Vector3 targetPosition;
private Coroutine moveRoutine;
private Animator anim;
public System.Action<MonsterController> onMoveComplete;
private MonsterController target;
private float moveSpeed = 2f;
public float radius = 1f;
// Start is called before the first frame update
void Start()
{
this.anim = GetComponent<Animator>();
}
//Method Overload
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 = StartCoroutine(CoMove());
}
public void Move(Vector3 targetPosition)
{
//타겟을 지움
this.target = null;
//이동할 목표지점을 저장
this.targetPosition = targetPosition;
//이동시작
if(this.moveRoutine != null)
{
//이미 코루틴이 실행중이다 -> 중지
this.StopCoroutine(this.moveRoutine);
}
this.moveRoutine = StartCoroutine(CoMove());
}
private IEnumerator CoMove()
{
while (true)
{
//로직
//방향을 바라봄
this.transform.LookAt(this.targetPosition);
//이동
this.anim.SetInteger("State", 1);
this.transform.Translate(Vector3.forward * this.moveSpeed * Time.deltaTime);
//목표지점과 나와의 거리를 잼
float distance = Vector3.Distance(this.transform.position, this.targetPosition);
//distance가 0이 될 수는 없다 가까워질 때 도착한 것으로 판단하자
//타겟이 있을 경우
if(this.target != null)
{
if (distance <= 1f + 1f)
{
//도착
break;
}
}
else
{
if (distance <= 0.1f)
{
//도착
break;
}
}
yield return null; //다음 프레임 시작
}
this.anim.SetInteger("State", 0);
this.onMoveComplete(this.target);
}
private void OnDrawGizmos()
{
Gizmos.DrawWireSphere(this.transform.position, this.radius);
}
public void Attack(MonsterController target)
{
this.anim.SetInteger("State", 2);
this.StartCoroutine(this.CoAttack());
}
private IEnumerator CoAttack()
{
//다음 함수 시작
//yield return null;
yield return new WaitForSeconds(0.1f); //0.1초 이후
//위 아래 같은거임
//float elaspedTime = 0;
//while (true)
//{
// elaspedTime += Time.deltaTime;
// if (elaspedTime > 0.1f)
// {
// break;
// }
// yield return null;
//}
Debug.Log("<color=red>Impact!!!!!</color");
//0.83 - 0.1
yield return new WaitForSeconds(0.73f);
Debug.Log("Attack애니메이션 종료");
this.anim.SetInteger("State", 0);
}
}
}
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;
[SerializeField]
private Image image;
private float maxDistance = 100f;
// Start is called before the first frame update
void Start()
{
this.heroController.onMoveComplete = ((target) => {
Debug.LogFormat("<color=cyan>이동을 완료했습니다. : {0}</color>", target);
//타겟이 있다면 공격 애니메이션 실행
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);
Debug.DrawRay(ray.origin, ray.direction * maxDistance, Color.red, 2f);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, maxDistance))
{
//충돌정보가 hit변수에 담김
Debug.LogFormat("hit.point: {0}", hit.point);
Debug.LogFormat("hit.collider: {0}", hit.collider.tag);
//클릭한 오브젝트가 몬스터라면
if(hit.collider.tag == "Monster")
{
//거리를 구한다.
float distance = Vector3.Distance(this.transform.position, hit.collider.gameObject.transform.position);
MonsterController monsterController = hit.collider.gameObject.GetComponent<MonsterController>();
//각 반지름 더한거와 비교
float sumRadius = this.heroController.radius + monsterController.radius;
Debug.LogFormat("=> {0}, {1}", distance, sumRadius);
//사거리 안에 들어옴
if(distance <= sumRadius)
{
//공격
}
//사거리 안에 안들어옴
else
{
//이동
this.heroController.Move(monsterController);
//this.heroController.Move(hit.point);
}
}
else if (hit.collider.tag == "Ground")
{
this.heroController.Move(hit.point);
}
//this.heroGo.transform.position = hit.point;
//Hero게임오브젝트를 이동
//this.heroController.Move(hit.point);
}
}
}
}
MonsterController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonsterController : MonoBehaviour
{
public float radius = 1f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
private void OnDrawGizmos()
{
Gizmos.DrawWireSphere(this.transform.position, this.radius);
}
}
'유니티 기초' 카테고리의 다른 글
SimpleRPG (0) | 2023.08.09 |
---|---|
이펙트 (0) | 2023.08.08 |
몬스터 클릭해서 몬스터 있는 위치로 이동 (0) | 2023.08.08 |
코루틴 (0) | 2023.08.08 |
로비씬, 사과, 폭탄 - 추가사항 빼고 기본 [완성] (0) | 2023.08.07 |