일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- HAPTIC
- 오브젝트 풀링
- 유니티 Json 데이터 연동
- 앱 배포
- 길건너 친구들
- meta xr
- 가상현실
- 팀 프로젝트
- OVR
- 유니티 GUI
- 멀티플레이
- CGV
- 포트폴리오
- Photon Fusion
- input system
- 개발
- Oculus
- 드래곤 플라이트 모작
- XR
- 모작
- 유니티 UI
- 팀프로젝트
- 연습
- VR
- 유니티
- ChatGPT
- 드래곤 플라이트
- meta
- 개발일지
- 오큘러스
- Today
- Total
EasyCastleUNITY
3D SpaceShooter Player Control & FollowCam 본문
1. WASD를 통해 플레이어 이동
2. 마우스를 왼쪽 클릭하고 드래그하면 화면이 돌아간다
3. 마우스 휠을 스크롤하면 화면을 줌인 줌아웃 한다.
4. 키보드 1번과 2번은 화면의 각도를 변경한다. (위 아래로 움직임)
PlayerControl: 플레이어 움직임
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
public enum eControlType
{
KeyBoard,JoyStick
}
public enum eAnimState
{
Idle, RunB, RunF, RunL, RunR
}
private Transform transform;
[SerializeField]
private FollowCam cam;
private float dampingCoefficient = 0.96f;
public float moveSpeed = 10.0f;
public float turnSpeed = 0.0f;
[SerializeField]
private VariableJoystick joystick;
[SerializeField]
private eControlType controlType;
private Animation anim;
private Vector3 startPos; // down 했을 때 위치
private Vector3 endPos; //up 했을 때 위치
// Start is called before the first frame update
void Start()
{
this.transform = GetComponent<Transform>();
this.anim = GetComponent<Animation>();
this.startPos = new Vector3(0, 0, 0);
this.endPos = new Vector3(0, 0, 0);
//this.anim.clip= this.anim.GetClip(eAnimState.Idle.ToString());
//this.anim.Play();
}
// Update is called once per frame
void Update()
{
float h = 0;
float v = 0;
//키보드
if(this.controlType == eControlType.KeyBoard)
{
//GetAxis -> 키보드 입력에 대해서 정보를 제공
h = Input.GetAxisRaw("Horizontal"); // -1 ,0, 1
v = Input.GetAxisRaw("Vertical"); // -1 ,0, 1
}
//조이스틱
else if(this.controlType == eControlType.JoyStick)
{
h = this.joystick.Direction.x;
v = this.joystick.Direction.y;
}
//Debug.Log(this.joystick.Direction); // x,y
Vector3 dir = new Vector3(h, 0, v);
float angle =Mathf.Atan2(dir.x,dir.z) * Mathf.Rad2Deg; //라디안으로 나온 값, 각도로 변경
//회전
if(Input.GetMouseButtonDown(0))
{
this.startPos = Input.mousePosition;
}
else if (Input.GetMouseButton(0)) //드래그 하는 동안 회전
{
this.endPos = Input.mousePosition;
float swipeLength = this.endPos.x - this.startPos.x;
this.turnSpeed = swipeLength / 500f;
this.cam.isTurn = true;
}
else this.cam.isTurn = false;
//회전
//this.tr.localRotation = Quaternion.AngleAxis(angle, Vector3.up);
this.transform.Rotate(Vector3.up * this.turnSpeed);
this.turnSpeed *= this.dampingCoefficient;
if (dir != Vector3.zero ) //키보드 누르고 있을때
{
//이동
this.transform.Translate(dir * this.moveSpeed * Time.deltaTime);
this.cam.isMove = true;
}
else this.cam.isMove = false;
this.PlayAnimation(dir);
}
//애니메이션
private void PlayAnimation(Vector3 dir)
{
if (dir.x > 0)
{
//right
this.anim.CrossFade(eAnimState.RunR.ToString(), 0.25f);
}
else if (dir.x < 0)
{
//left
this.anim.CrossFade(eAnimState.RunL.ToString(), 0.25f);
}
else if(dir.z > 0)
{
//forward
this.anim.CrossFade(eAnimState.RunF.ToString(), 0.25f);
}
else if(dir.z < 0)
{
//back
this.anim.CrossFade(eAnimState.RunB.ToString(), 0.25f);
}
else
{
//Idle
this.anim.CrossFade(eAnimState.Idle.ToString(), 0.25f);
}
}
}
FollowCam: 카메라가 플레이어 쫓아감, 줌인 줌아웃 ,오프셋
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FollowCam : MonoBehaviour
{
//타겟은 플레이어
[SerializeField]
private Transform playerTrans;
[SerializeField]
private float distance = 10f;
private float height=3f;
[SerializeField]
private float scrollSpeed = 100f;
[SerializeField]
private Transform zoomInPoint;
[SerializeField]
private Transform zoomOutPoint;
[SerializeField]
[Range(0f, 1f)]
private float lerpValue =0.5f;
private Vector3 tpos;
[SerializeField]
private Vector3 offSet;
public bool isMove = false;
public bool isTurn = false;
private bool isScroll = false;
private bool isInit = true;
// Start is called before the first frame update
void Start()
{
this.offSet = Vector3.Lerp(Vector3.zero, new Vector3(0, 1.88f, 0), 1.0f);
//this.SetPosition();
this.isInit = true;
}
// Update메서드 이후의 실행
void LateUpdate()
{
this.SetOffset();
this.SetPosition();
this.CameraWheelMove();
}
//위치 세팅
private void SetPosition()
{
Vector3 x = this.playerTrans.position + this.playerTrans.forward * -1 * this.distance;
this.tpos = x + Vector3.up * height;
this.transform.position = this.tpos;
height = this.transform.position.y;
this.transform.LookAt(this.playerTrans.position + this.offSet);
this.zoomInPoint.transform.position =
this.transform.position + this.transform.forward * 2f;
this.zoomOutPoint.transform.position =
this.transform.position + this.transform.forward * -5f;
this.isInit = false;
}
//마우스 휠을 스크롤하면 마우스를 줌인 줌아웃
private void CameraWheelMove()
{
float scroll = Input.GetAxis("Mouse ScrollWheel");
//Debug.LogFormat("scroll:{0}",scroll); // 가까워지면 0.1, 멀어지면 -0.1
if (scroll > 0)
{
this.lerpValue -= 0.05f;
if(this.lerpValue <= 0) this.lerpValue = 0;
}
else if (scroll < 0)
{
this.lerpValue += 0.05f;
if(this.lerpValue >=1) this.lerpValue = 1;
}
this.tpos = Vector3.Lerp(this.zoomInPoint.position, this.zoomOutPoint.position,
this.lerpValue);
this.transform.position = this.tpos;
this.isInit = false;
}
//카메라 오프셋
//1번 누르면 플레이어 머리를 포커스
//2번 누르면 플레이어 발을 포커스
private void SetOffset()
{
if (Input.GetKey(KeyCode.Alpha1))
{
//offset위로
this.offSet.y += 0.03f;
if (this.offSet.y > 1.88f) this.offSet.y = 1.88f;
}
else if (Input.GetKey(KeyCode.Alpha2))
{
//offset 아래로
this.offSet.y -= 0.03f;
if (this.offSet.y < 0) this.offSet.y = 0.0f;
}
}
}
https://www.youtube.com/watch?v=LBc79tGaAwc 시연영상
어려웠던 점
1. 스크롤을 통해서 카메라 줌인 줌아웃 하는 기능을 구현하는 게 힘들었다.
처음에는 그냥 Translate를 사용하면 끝나는 기능인 줄 알았으나, 도중에 사용된 LookAt 함수 때문에
Vector3.forward를 활용하면, 카메라의 각도가 계속 바뀌는 일이 생겼다.
이 점을 해결한 것이 오늘 배운 Vector3.Lerp 였다.
이 Lerp를 활용하여 줌인 줌아웃을 구현해보니 어떤 식으로 벡터를 활용해야 될지 감이 잡혔다.
1-1. 인스펙터의 슬라이드 구현
이런식으로 범위를 정해서 슬라이드를 생성해준다. 여기서는 lerpValue를 응용하기위해 0~1까지로 구성하였다.
그런데 이런식으로 제한을 걸어도 실제 변수 lerpValue의 값은 제한이 안된다는 것을 알았다.
이런식으로 인스펙터 상에서 슬라이드의 값이 제한된다고 해도, 실제 lerpValue 값은 그 값을 넘어 계산되고 있다.
이점을 유의하여 스크롤을 통해 줌인 줌아웃을 만들었다.
새로 배운것
1.Vector3.Lerp, 벡터의 활용법
2.레거시 애니메이션 사용법
3.LOD (Level of Detail)
사용자에게서 멀다면, 굳이 렌더링 될 필요가 없기에, 이것을 위해 제공하는 기능, 사용자 카메라에서 먼 오브젝트의 디테일이 떨어지고, 멀리 떨어지면 완전히 Culling되어 렌더링 되지 않는다.
'유니티 심화' 카테고리의 다른 글
[과제]궁수의 전설 이동 및 공격 만들기(2023.08.23 00:01분 최종완성) (0) | 2023.08.19 |
---|---|
3D Space Shooter Test1 (0) | 2023.08.18 |
Space Shooter 카메라 Player Follow (0) | 2023.08.18 |
2D 탄막 게임 테스트 (적 피격 애니메이션 및 사망 애니메이션) (0) | 2023.08.18 |
2D 탄막 게임 1 (0) | 2023.08.16 |