Closed junhyungPARK78 closed 1 year ago
위 방향성 폐기
공이 벽에 충돌하는 순간의 벡터가 일정값 이하가 되면 자동으로 일정 이상의 벡터(일정 범위 랜덤으로)를 자동으로 입력하게 하기
Debug.DrawLine
를 사용할 경우 빌드하면 보이는지 확인하기vector의 의미 https://m.blog.naver.com/os2dr/221576752200
Vector2.Reflect
에 대해서
https://nekojara.city/unity-vector-reflect
ballVector 얻는 방법을 바꾸기
ballRigidBody.GetVector();
↓
ballRigidBody.velocity;
거의 동일하게 나오고 있다.
red : 일반 vector green : normalize한 vector
안심하고 .normalized
사용하자.
코드
int sampleNum = 10;
List<int> nums = new List<int>();
for (int i = sampleNum * -1; i <= sampleNum; i++)
{
nums.Add(i);
}
foreach (int numX in nums)
{
foreach (int numY in nums)
{
Debug.DrawLine(Vector2.zero, new Vector2(numX, numY), Color.red);
Debug.DrawLine(Vector2.zero, new Vector2(numX, numY).normalized, Color.green);
}
}
지금의 반사 확률을 로그로 찍어보면...
중간이 성기게 된다. y값 1로 고정으로 해서 x 값의 변동으로 반사시킬 vector를 구했기 때문. 각도의 분포가 고르게 될 수 있도록 조정할 필요가 있다.
int sampleNum = 10;
List<int> nums = new List<int>();
for (int i = sampleNum * -1; i <= sampleNum; i++)
{
nums.Add(i);
}
foreach (int numX in nums)
{
Debug.DrawLine(Vector2.zero, new Vector2(numX, 10), Color.red);
Debug.DrawLine(Vector2.zero, new Vector2(numX, 10).normalized, Color.green);
}
Vector3 direction = Quaternion.AngleAxis(-30, Vector3.forward) * dir
paddle 과 공의 상대 위치 (-1 ~ 1)에 따른 각도 공식
(상대위치 * -1) * (반사허용각 * 0.25) + 90
어우 변수명 정할 때 참 괴로웠는데 ChatGPT에 물어보니 꽤 괜찮게 대답해주네. 앞으로 유용하게 사용해야겠다.
"볼이 paddle에 반사할 때 제한 각도"를 변수명으로 바꾸려면 변수명이 어떤 값을 의미하는지 명확하게 알아볼 필요가 있습니다. 이에 따라 변수명은 다양하게 지을 수 있겠지만, 예를 들면 다음과 같은 변수명이 가능합니다.
maxReflectionAngleWhenBallHitsPaddle paddleReflectionLimitAngle ballPaddleBounceLimitAngle paddleBounceMaxAngle maxPaddleReflectionAngleOnBallBounce 등등 여러 가지 이름으로 가능합니다. 변수명은 의미를 명확하게 전달할 수 있도록 지어야 하며, 가독성을 높이기 위해서는 변수명을 적절하게 지어야 합니다.
「paddle 반사 각도가 위치에 따라서 일정하게 배분되도록 수정하기」관련 코드
float reflectAngleRangeOnPaddle = 160f;
Vector2 hitPos = other.ClosestPoint(this.transform.position);
if (other.tag == "Paddle")
{
// ball과 paddle이 접촉한 순간의 상대 위치 계산
float ballPositionOnPaddle = ((gameObject.transform.position.x) - (other.transform.position.x)) * 2f;
ballPositionOnPaddle = Mathf.Clamp(ballPositionOnPaddle, -1f, 1f);
// ballPositionOnPaddle에 의한 반사각 계산
float ballReflectQuaternion = (ballPositionOnPaddle * -1) * (reflectAngleRangeOnPaddle * 0.25f) +90;
ballReflectVector = Quaternion.AngleAxis(ballReflectQuaternion, Vector3.forward) * Vector2.right;
// 공 반사시키기
ballRigidBody.velocity = ballReflectVector * BallInitialVelocity;
}
Debug.DrawLine
붙이기istrigger
로 바꾸기istrigger
로 바꾸기Vector2. SignedAngle
사용해보기startVector
가 (1, 2)니까 각도로 계산하면 63.43도 나오게 된다.Vector2.SignedAngle
≤ 180vector 의 각도를 검출하는 방법 1
Vector2.SignedAngle
함수를 사용한다.
float testAngle = 0.0f;
Vector2 vector1 = new Vector2(1, 0);
Vector2 vector2 = new Vector2(-1, 1);
testAngle = Vector2.SignedAngle(vector1, vector2);
Debug.Log($"testAngle : {testAngle}"); // testAngle : 135
vector 의 각도를 검출하는 방법 2
Mathf.Atan2
함수를 사용한다
float testAngle = 0.0f;
Vector2 vector = new Vector2(-1, 1);
testAngle = Mathf.Atan2(vector.y, vector.x) * Mathf.Rad2Deg;
Debug.Log($"testAngle : {testAngle}"); // testAngle : 135
기준값이 되는 Vector2.right
를 사용할 필요가 없으므로 이쪽이 쉽게 구할 수 있을 듯.
위 두 방법을 1만회 반복시켜서 시간 계산 해 본 결과,
Vector2.SignedAngle : 11 ms Mathf.Atan2 : 1 ms
의 결과가 나옴.
Mathf.Atan2
가 가벼운 계산인 듯하다.
Code
testAngle = 0.0f;
vector1 = Vector2.right;
vector2 = new Vector2(-1, 1);
int testCount = 100000;
System.Diagnostics.Stopwatch watch1 = new System.Diagnostics.Stopwatch();
watch1.Start();
for (int i = 0; i < testCount; ++i)
{
testAngle = Vector2.SignedAngle(vector1, vector2) + i;
}
watch1.Stop();
Debug.Log($"Vector2.SignedAngle : {watch1.ElapsedMilliseconds} ms");
System.Diagnostics.Stopwatch watch2 = new System.Diagnostics.Stopwatch();
watch2.Start();
for (int i = 0; i < testCount; ++i)
{
testAngle = Mathf.Atan2(vector2.y, vector2.x) * Mathf.Rad2Deg + i;
}
watch2.Stop();
Debug.Log($"Mathf.Atan2 : {watch2.ElapsedMilliseconds} ms");
// Vector2.SignedAngle : 11 ms
// Mathf.Atan2 : 1 ms
가로 세로 모두 5도로 일단 설정. 하지만 따로 값을 빼두자.
5도 이하 벡터일 때는 일괄 5도로 설정한다.
삼각형 계산기 : https://ko.calcprofi.com/samgaghyeong-gyesangi.html
일단 오른쪽 벽에만 코드 설치했음. 플레이 하면서 막히는 부분 있으면 수정하자
추가
플레이 중 왼쪽 클릭하거나하면 공이 초기 속도로 돌아가는 문제 수정함
ballVectorAngle = Mathf.Atan2(ballVector.y, ballVector.x) * Mathf.Rad2Deg;
if (0f <= ballVectorAngle && ballVectorAngle < reflectLimitAngle)
{
ballVector = Quaternion.AngleAxis(reflectLimitAngle, Vector3.forward) * Vector2.right;
}
else if (reflectLimitAngle * -1 < ballVectorAngle && ballVectorAngle <= 0f)
{
ballVector = Quaternion.AngleAxis(reflectLimitAngle * -1, Vector3.forward) * Vector2.right;
}
일정 시간 동안 y축 이동이 일정 이하일 때 자동으로 움직임 추가 벡터를 줄 수 있는 방향으로 하면 될 듯