논타겟팅 게임의 에임
-사이퍼즈는 논타겟팅 게임이다. 논타겟팅 게임이란 공격을 누구한테 할지, 타겟을 정하지 않고도 때렸더니 맞았다면 공격이 되는 게임이다. 즉 이펙트가 어떻게 날아가고 부딪히냐에 따라 맞을수
도 맞지않을 수도 있는 것이다.
https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/Mouse.html
사이퍼즈에서 마우스는 여러 역할을 한다.
-첫째, 플레이어는 마우스를 통해 시점을 이동할 수 있다. 왼쪽으로 마우스를 움직이면 플레이어의 시점이 왼쪽으로 가고, 오른쪽으로 움직이면 오른쪽으로 시점이 이동한다.
- 둘째, 에임을 맞춰, 스킬 입력이 있으면 공격한다.
에임 생성
-먼저 마우스의 에임을 만들어주려한다.
-사이퍼즈의 에임은 정중앙에서 고정되어있지 않다. 마우스의 움직임에 따라 위치가 변하며, 에임에 오브젝트가 감지되면 파란색이되며 사이즈가 줄어든다.
- 움직이는 에임이지만 최고 위치, 최저 위치가 있다.
https://docs.unity3d.com/ScriptReference/Cursor.SetCursor.html
-에임의 이미지를 바꿔주기 위해 Cursor.SetCursor를 사용했다.
-texture type이 Cursor로 되어있어야한다.
기존의 플레이어의 Rotation을 없애주고, 마우스의 위치에 따라 회전하도록 코드를 수정하였다.
-MouseController의 GetMouseScreenPosition에서 마우스의 현재 위치를 받는다.
-MouseLook 메서드에서 이를 그냥 호출하게 되면 값이 변하지 않더라도 멤버변수에 저장할 수 있으므로, 기존 멤버변수의 값과 새로운 GetMouseScreenposition 값을 비교해 다른 경우에만 멤버변수에 저장하도록하였다.(37라인)
-마우스를 오른쪽으로 움직였는지 왼쪽으로 움직였는지를 알기 위해 어떤 값이 큰지 비교하였다. 기존에 멤버 변수 값이 크다면 새로 입력된 값이 더 작은 것이므로 왼쪽이다.
-다시 게임을 확인해보니 에임의 방향에 따라 카메라가 그 방향을 바라본다. 수정이 필요하다.
-현재에는 마우스 커서의 위치가 화면의 어디든지 갈 수 있다. 그러나 사이퍼즈의 에임은 가운데의 일정 범위 내에서만 상하로 움직인다. 커서의 이미지를 투명한 것으로 바꾸고 일정 범위 내에서만 crossHair를 움직이도록 수정하자.
-일정범위 내에서 crossHair는 커서의 위치(y축)를 받는다. 에임은 상,하로 움직인다.
-마우스의 위치를 받아 회전 시켜주되, 최대 회전 각도를 제한한다. 제한하지 않으면 360도로 회전할 수 있기 때문이다.
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
public class MouseController : MonoBehaviour
{
[SerializeField] GameObject cameraGo;
[SerializeField] private Image aimImage;
[SerializeField] private Texture2D cursorTexture;
private CursorMode cursorMode = CursorMode.Auto;
private Vector2 hotSpot = Vector2.zero;
private Vector3 mousePosHorizontal;
private Vector3 mousePosVertical;
// Start is called before the first frame update
void Start()
{
//set image on center
this.hotSpot.x = cursorTexture.width / 2;
this.hotSpot.y = cursorTexture.height / 2;
}
// Update is called once per frame
void FixedUpdate()
{
Cursor.lockState = CursorLockMode.Confined;
this.ChangeMouseMode();
this.MouseLook();
this.MouseVertical();
// Debug.Log(this.cameraGo.transform.rotation.eulerAngles);
var layerMask = 3 << LayerMask.NameToLayer("Tower");
// Vector3 rayPos = new Vector3(this.cameraGo.)
Transform rayTrans = this.aimImage.transform;
Ray ray = new Ray(rayTrans.position, cameraGo.transform.forward);
// Ray ray = new Ray(this.aimImage.rectTransform.anchoredPosition, this.cameraGo.transform.forward);
Debug.DrawRay(ray.origin, ray.direction * 10f, Color.red, 0.5f);
RaycastHit hit;
if (Physics.Raycast(ray.origin, ray.direction, out hit, 10.0f, layerMask))
{
Debug.Log(hit.collider.gameObject);
}
}
private void ChangeMouseMode()
{
Cursor.SetCursor(cursorTexture, hotSpot, cursorMode);
}
private void MouseLook()
{
Vector3 mousePos = GetMouseScreenPosition();
this.aimImage.rectTransform.anchoredPosition = new Vector3(0, mousePos.y * 0.4f - 80, 0);
// if (this.mousePosHorizontal != GetMouseScreenPosition())
{
if (this.mousePosHorizontal.x > GetMouseScreenPosition().x)
{//마우스를 왼쪽으로 움직이는 경우
this.mousePosHorizontal = GetMouseScreenPosition();
this.transform.Rotate(Vector3.up * -150f * Time.deltaTime);//좌우는 몸이 통째로 돌아간다.
// this.cameraGo.transform.LookAt(this.transform.position);
// this.cameraGo.transform.Rotate(Vector3.up * -150f * Time.deltaTime);
}
else if (this.mousePosHorizontal.x <GetMouseScreenPosition().x)
{//마우스를 오른쪽으로 움직이는 경우
this.mousePosHorizontal = GetMouseScreenPosition();
this.transform.Rotate(Vector3.up * 150f * Time.deltaTime);//좌우는 몸이 통째로 돌아간다.
// this.cameraGo.transform.LookAt(this.transform.position);
// this.cameraGo.transform.Rotate(Vector3.up * 150f * Time.deltaTime);
}
else
{
this.mousePosHorizontal = GetMouseScreenPosition();
}
}
}
private void MouseVertical()
{
float vertical = this.mousePosVertical.y - GetMouseScreenPosition().y;
//Debug.Log(vertical);
if (vertical != 0)
{
// Debug.Log(GetMouseScreenPosition().y);
if (vertical <= 0)
{
float rotationValue = 0;
// Debug.LogFormat("Up: {0} ", GetMouseScreenPosition().y - this.mousePosVertical.y);
this.mousePosVertical = GetMouseScreenPosition();
rotationValue = -this.mousePosVertical.magnitude * 0.04f * Time.deltaTime;
if (345 < this.cameraGo.transform.eulerAngles.x && this.cameraGo.transform.eulerAngles.x < 360)
{
this.cameraGo.transform.Rotate(Vector3.right * rotationValue);
}
else if (this.cameraGo.transform.eulerAngles.x < 20f)
{
this.cameraGo.transform.Rotate(Vector3.right * rotationValue);
}
else
{
// Debug.Log("maximum");
}
// this.cameraGo.transform.rotation = Quaternion.Euler(Vector3.right*rotationValue*10f);
}
else if (vertical>0)
{
//Debug.LogFormat("Down: {0} ", this.mousePosVertical.y - GetMouseScreenPosition().y);
float rotationValue = 0;
this.mousePosVertical = GetMouseScreenPosition();
//rotationValue = this.mousePosVertical.y * 0.07f * Time.deltaTime;
rotationValue = this.mousePosVertical.magnitude * 0.04f * Time.deltaTime;
//if (this.cameraGo.transform.rotation.x < 0.04)
if (this.cameraGo.transform.eulerAngles.x < 360f && this.cameraGo.transform.eulerAngles.x > 50)
{
this.cameraGo.transform.Rotate(Vector3.right * rotationValue);
}
// this.cameraGo.transform.rotation = Quaternion.Euler(Vector3.right * rotationValue * -10f);
}
}
}
private Vector3 GetMouseScreenPosition()
{
return Mouse.current.position.ReadValue();//mouse position
}
}
'[3D] Cyphers 모작' 카테고리의 다른 글
[Cyphers] 클레어 평타 구현 (0) | 2023.10.04 |
---|---|
[Cyphers] 에임 조준(CrossHair) (0) | 2023.09.27 |
[Cyphers] Player 이동구현(New Input System) + 카메라 컨트롤 (0) | 2023.09.25 |
[Cyphers] 1차 목표 구현계획 (0) | 2023.09.23 |
[Cyphers]리버포드 맵 분석 (0) | 2023.09.22 |