잘 모르겠어서 다시한번 알아본 3가지들
1. Mathf.Atan2(float y, floay x); , Mathf.Rad2Deg
Quaternion을 사용해야할 때, 즉 회전이 필요할 때 사용한다.
유니티에서 제공하고 있는 아크탄젠트 함수는 반환값이 라디안값이라서 Mathf.Atan2를 해준 후에 Mathf.Rad2Deg를 곱해주면 우리가 알고있는 몇'도'로 라디안값에서 변하게 된다.
2. Quaternion.AngleAxis(float angle, Vector3 axis);
Mathf.Atan2와 MathfRad2Deg로 구한 '도'를 이용해서 z축으로 축을 회전시켜준다.
지금까지 HeroShooter를 하면서 Main을 만들지 않고 했었는데 만들어온 함수들을 보니.. PlayerController에만 놔둘 수는 없을 것 같았고, 지금은 괜찮지만 나중에 가서 10스테이지 100스테이지를 간다는 가정하에 코드가 얼마나 개판이 될지 상상이 안가서 Main에다가 따로 만들어주기로 결심을 하였다.
하이라키와 프로젝트는 이렇게 구성되어있다.
TutorialSceneMain
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class TutorialSceneMain : MonoBehaviour
{
//플레이어
[SerializeField]
private PlayerController playerController;
//조이스틱
[SerializeField]
private CJoystick joystick;
//포탈
[SerializeField]
private GameObject portalGo;
//왼쪽 문
[SerializeField]
private DoorController leftDoorController;
//오른쪽 문
[SerializeField]
private DoorController rightDoorController;
//페이드아웃
[SerializeField]
private Image dim;
//NPC 텍스트
[SerializeField]
private Text text;
// Start is called before the first frame update
void Start()
{
//포탈에 닿았을 때
this.playerController.reachPortal = () => {
//포탈 삭제하고
Destroy(this.portalGo.gameObject);
//문 열기
this.leftDoorController.OpenDoor();
this.rightDoorController.OpenDoor();
};
//문에 닿았을 때
this.playerController.reachDoor = () => {
//씬 전환하기
this.FadeOutAndSceneManager();
};
}
// Update is called once per frame
void Update()
{
//수평, 수직 좌표 구하고 moveDir에 넣기
float h = this.joystick.Horizontal;
float v = this.joystick.Vertical;
Vector3 moveDir = new Vector3(h, 0, v);
//moveDir이 Vector3.zero일 경우
if(moveDir == Vector3.zero)
{
//정지 애니메이션 실행
this.playerController.PlayAnimation(EnumState.ePlayerState.Idle);
}
else // (0,0,0)이 아닐 경우
{
this.playerController.Move(moveDir);
}
}
private void FadeOutAndSceneManager()
{
//페이드아웃 이미지 액티브 활성화
this.dim.gameObject.SetActive(true);
//코루틴 활성화
this.StartCoroutine(this.CoFadeOutAndSceneManager());
}
private IEnumerator CoFadeOutAndSceneManager()
{
//dim 컬러 가져오기
Color color = this.dim.color;
while (true)
{
//color.a --> 0.01f씩 더해주기
color.a += 0.01f;
//color.a가 1보다 높으면 break
if(color.a >= 1)
{
//while문 나오기
break;
}
//정지
yield return null;
}
//while문 나온 후 씬 전환
SceneManager.LoadScene("Stage1Scene");
}
}
PlayerController
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour
{
//캐릭터 움직임 속도
[SerializeField]
private float moveSpeed = 5f;
//애니메이션
private Animator anim;
//포탈태그했을 때
public Action reachPortal;
//문에 닿았을 때
public Action reachDoor;
void Start()
{
this.anim = this.GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
//Ray로 한번 발견이나 해보자
Ray ray = new Ray(this.transform.position, this.transform.forward);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, 1000f))
{
DrawArrow.ForDebug(this.transform.position, hit.collider.transform.position, 2f, Color.red, ArrowType.Solid);
if (hit.collider.tag == "Monster")
{
Debug.Log("몬스터");
}
}
}
public void Move(Vector3 moveDir)
{
//달리는 애니메이션 실행
this.PlayAnimation(EnumState.ePlayerState.RunF);
//Mathf.Atan2와 Mathf.Rad2Deg를 이용해서 회전시키기
float angle = Mathf.Atan2(moveDir.x, moveDir.z) * Mathf.Rad2Deg;
//AngleAxis를 이용하기
Quaternion q = Quaternion.AngleAxis(angle, Vector3.up);
//캐릭터에 회전 적용
this.transform.rotation = q;
//캐릭터 움직이기
this.transform.Translate(Vector3.forward * this.moveSpeed * Time.deltaTime);
}
public void PlayAnimation(EnumState.ePlayerState state)
{
this.anim.SetInteger("State", (int)state);
}
private void OnCollisionEnter(Collision collision)
{
if (collision.collider.tag == "Door")
{
//대리자 사용해서 씬 전환하기
this.reachDoor();
}
else if (collision.collider.tag == "Portal")
{
//대리자 사용해서 문 열고, 포탈 제거하기
this.reachPortal();
}
}
}
EnumState
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnumState
{
public enum ePlayerState
{
Idle, RunF
}
}
동영상은 똑같으므로 찍지않았다.
TutorialMain으로 옮겨오면서 다시 한번 공부하게되어 도움이 된 것 같다.
'유니티 심화 > 복습' 카테고리의 다른 글
[복습] SpaceShooter2D - Player, Bullet -> Main으로 옮기기, 오브젝트 풀링 기반 만들기 (0) | 2023.08.28 |
---|---|
[복습 & 추가] HeroShooter - 몬스터 Indicator.. 잘모르는 것들 (0) | 2023.08.25 |
[복습] Quaternion , OverlapSphere (0) | 2023.08.22 |
[복습] SpaceShooter - 마우스로 캐릭터 이동 (0) | 2023.08.18 |
[복습] SpaceShooter - 줌인, 줌아웃, 캐릭터 이동 (0) | 2023.08.18 |