총구가 조이스틱 방향으로 회전한다
- 핸들의 Vector2와 Vector2.Zero를 Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg를 이용하여 각도 계산
- 플레이어 스케일이 -일때 각도에 180를 더해준다. (플레이어가 이동 방향에 때라 좌우 반전을 하기 때문)
- 조이스틱에서 손을 때면(핸들의 Vector2가 Vector2. Zero이면)
총구가 플레이어의 전방을 바라본다 (Quaternion.Euler(0, 0, 0))
추가해야 되는 것
-조이스틱 방향으로 총알 발사
-총알은 화면 벽과 적에게 부딪히면 사라짐(벽이 둘러쌓여 있지만 화면 밖으로 나가도 삭제)
-적에게 부딪힐경우 데미지를 입힌다
무기 회전코드
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestPlayer : MonoBehaviour
{
[SerializeField]
private Joystick attackJoystick;
[SerializeField]
private GameObject weapon;
public void FixedUpdate()
{
//공격
Vector2 attackDir = Vector2.up * this.attackJoystick.Vertical + Vector2.right * this.attackJoystick.Horizontal;
float weaponAngle = GetAngle(attackDir, Vector2.zero);
//플레이어의 X축과 조이스틱이 반대일 경우
if(this.transform.localScale.x < 0)
{
weaponAngle += 180;
}
//핸들의 위치가 (0,0)이라면 각도를 초기화
if(this.attackJoystick.Direction == Vector2.zero)
{
this.weapon.transform.rotation = Quaternion.Euler(0, 0, 0);
}
else
{
this.weapon.transform.rotation = Quaternion.Euler(0, 0, weaponAngle);
}
}
public static float GetAngle(Vector2 vStart, Vector2 vEnd)
{
Vector2 v = vEnd - vStart;
return Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg;
}
}
| 무기의 회전을 transform.rotate에 weaponAngle을 넣었는데 weaponAngle이 계속 update되어 계속 회전하는 문제가 생김 (회전된 무기가 다시 회전하는 문제) this.weapon.transform.rotation = Quaternion.Euler(0, 0, weaponAngle); 를 이용하여 해결 (회전한 Rotation을 무기의 rotation에 할당하는 방식) Transform.Rotate 오브젝트를 회전 시킴 https://docs.unity3d.com/ScriptReference/Transform.Rotate.html Quaternion.Euler z축 주위로 z, x축 주위로 x, y축 주위로 y 각도만큼 회전한(순서대로) Rotation을 반환합니다. https://docs.unity3d.com/kr/530/ScriptReference/Quaternion.Euler.html |
| 두 벡터 사이의 각도를 구하는 공식 using UnityEngine;
// return : -180 ~ 180 degree (for unity)
public static float GetAngle (Vector3 vStart, Vector3 vEnd)
{
Vector3 v = vEnd - vStart;
return Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg;
}
출처: https://minhyeokism.tistory.com/19 [programmer-dominic.kim]
--------------------------------------------------------------------------- public static float GetAngle(Vector2 vStart, Vector2 vEnd) { Vector2 v = vEnd - vStart; return Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg; } 벡터2로 변경하여 사용 ---------------------------------------------------------------------------- 반대로 회전될경우 public static float GetAngle(Vector3 vStart, Vector3 vEnd) { Vector3 v = vEnd - vStart; //return Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg; return Mathf.Atan2(v.x, v.y) * Mathf.Rad2Deg; } Mathf.Atan2(v.y, v.x) -> Mathf.Atan2(v.x, v.y) ---------------------------------------------------------------------------- Mathf.Atan2 Tan이 y/x인 각도를 라디안 단위로 반환합니다. 반환 값은 x축과 0에서 시작하여 (x,y)에서 끝나는 2D 벡터 사이의 각도입니다. 참고: 이 함수는 x가 0인 경우를 고려하여 0으로 나누기 예외를 던지지 않고 올바른 각도를 반환합니다. https://docs.unity3d.com/ScriptReference/Mathf.Atan2.html Mathf.Rad2Deg 라디안을 각도로 변환해주는 상수를 나타냅니다.(읽기전용) 이 값은 360 / (PI * 2)와 같습니다. https://docs.unity3d.com/kr/530/ScriptReference/Mathf.Rad2Deg.html |
전체코드
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestPlayer : MonoBehaviour
{
public float speed;
[SerializeField]
private Joystick moveJoystick;
[SerializeField]
private Joystick attackJoystick;
//플레이어 방향 0 or 1
private int reverseScale = 0;
[SerializeField]
private GameObject weapon;
public void FixedUpdate()
{
//이동(조이스틱)
//Vector2 moveDir = Vector2.up * this.moveJoystick.Vertical + Vector2.right * this.moveJoystick.Horizontal;
//Debug.Log(direction);
//if (moveDir.x < 0)
//{
// if(this.reverseScale != 0)
// {
// this.reverseScale = 0;
// this.transform.localScale = new Vector2(this.transform.localScale.x * -1, this.transform.localScale.y);
// }
//}
//else if (moveDir.x > 0)
//{
// if (this.reverseScale != 1)
// {
// this.reverseScale = 1;
// this.transform.localScale = new Vector2(this.transform.localScale.x * -1, this.transform.localScale.y);
// }
//}
//this.transform.Translate(moveDir * this.speed * Time.deltaTime);
//이동(키보드)
//좌 이동
if (Input.GetKey(KeyCode.LeftArrow))
{
//방향 * 속도 * 시간
this.transform.Translate(Vector2.left * this.speed * Time.deltaTime);
if (this.reverseScale != 0)
{
this.reverseScale = 0;
this.transform.localScale = new Vector2(this.transform.localScale.x * -1, this.transform.localScale.y);
}
}
//우 이동
if (Input.GetKey(KeyCode.RightArrow))
{
this.transform.Translate(Vector2.right * this.speed * Time.deltaTime);
if (this.reverseScale != 1)
{
this.reverseScale = 1;
this.transform.localScale = new Vector2(this.transform.localScale.x * -1, this.transform.localScale.y);
}
}
//상 이동
if (Input.GetKey(KeyCode.UpArrow))
{
this.transform.Translate(Vector2.up * this.speed * Time.deltaTime);
}
//하 이동
if (Input.GetKey(KeyCode.DownArrow))
{
this.transform.Translate(Vector2.down * this.speed * Time.deltaTime);
}
//공격
Vector2 attackDir = Vector2.up * this.attackJoystick.Vertical + Vector2.right * this.attackJoystick.Horizontal; //노멀라이즈?
float weaponAngle = GetAngle(attackDir, Vector2.zero);
if(this.transform.localScale.x < 0)
{
weaponAngle += 180;
}
if(this.attackJoystick.Direction == Vector2.zero)
{
this.weapon.transform.rotation = Quaternion.Euler(0, 0, 0);
}
else
{
this.weapon.transform.rotation = Quaternion.Euler(0, 0, weaponAngle);
}
}
public static float GetAngle(Vector2 vStart, Vector2 vEnd)
{
Vector2 v = vEnd - vStart;
return Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg;
}
}
| 각도구하기 참고 블로그 https://wiseraintown.tistory.com/8 |
'[ProjectT] > 개발일지' 카테고리의 다른 글
| [21.11.30] 몬스터 랜덤한 방향으로 이동 (0) | 2021.11.30 |
|---|---|
| [21.11.24] 조이스틱 공격_02 (0) | 2021.11.24 |
| [21.11.23] 조이스틱 이동 (0) | 2021.11.24 |
| [ProjectT] 프로토타입 R&D 목록 (0) | 2021.11.24 |
| [ProjectT] 전투화면 리소스 배치 (0) | 2021.11.24 |