junhyungPARK78 / chuchuUnity

0 stars 0 forks source link

볼 반사 각도 일정 범위 안에서 움직이도록 지정하기 #39

Closed junhyungPARK78 closed 1 year ago

junhyungPARK78 commented 1 year ago

일정 시간 동안 y축 이동이 일정 이하일 때 자동으로 움직임 추가 벡터를 줄 수 있는 방향으로 하면 될 듯

junhyungPARK78 commented 1 year ago

위 방향성 폐기

공이 벽에 충돌하는 순간의 벡터가 일정값 이하가 되면 자동으로 일정 이상의 벡터(일정 범위 랜덤으로)를 자동으로 입력하게 하기

junhyungPARK78 commented 1 year ago
junhyungPARK78 commented 1 year ago

vector의 의미 https://m.blog.naver.com/os2dr/221576752200

junhyungPARK78 commented 1 year ago

Vector2.Reflect 에 대해서 https://nekojara.city/unity-vector-reflect

junhyungPARK78 commented 1 year ago

ballVector 얻는 방법을 바꾸기

ballRigidBody.GetVector();ballRigidBody.velocity;

junhyungPARK78 commented 1 year ago

거의 동일하게 나오고 있다.

スクリーンショット 2023-02-10 19 16 14

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);
    }
}
junhyungPARK78 commented 1 year ago
junhyungPARK78 commented 1 year ago

지금의 반사 확률을 로그로 찍어보면...

スクリーンショット 2023-02-15 14 27 03

중간이 성기게 된다. 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);
}
junhyungPARK78 commented 1 year ago

어우 변수명 정할 때 참 괴로웠는데 ChatGPT에 물어보니 꽤 괜찮게 대답해주네. 앞으로 유용하게 사용해야겠다.

"볼이 paddle에 반사할 때 제한 각도"를 변수명으로 바꾸려면 변수명이 어떤 값을 의미하는지 명확하게 알아볼 필요가 있습니다. 이에 따라 변수명은 다양하게 지을 수 있겠지만, 예를 들면 다음과 같은 변수명이 가능합니다.

maxReflectionAngleWhenBallHitsPaddle paddleReflectionLimitAngle ballPaddleBounceLimitAngle paddleBounceMaxAngle maxPaddleReflectionAngleOnBallBounce 등등 여러 가지 이름으로 가능합니다. 변수명은 의미를 명확하게 전달할 수 있도록 지어야 하며, 가독성을 높이기 위해서는 변수명을 적절하게 지어야 합니다.

junhyungPARK78 commented 1 year ago

「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;
}
junhyungPARK78 commented 1 year ago
junhyungPARK78 commented 1 year ago

https://velog.io/@juliajh/Unity-Particle-System-%EC%A2%85%EB%A3%8C%EC%8B%9C-%EC%9E%90%EB%8F%99%EC%9C%BC%EB%A1%9C-Destroy%ED%95%98%EA%B8%B0

https://qfood.tistory.com/529#:~:text=2.%20%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8%EA%B0%80%20%EC%83%9D%EC%84%B1%EB%90%9C%20%EC%9D%B4%ED%9B%84%20%ED%8A%B9%EC%A0%95%20%EC%8B%9C%EA%B0%84%EC%9D%B4%20%EA%B2%BD%EA%B3%BC%20%ED%95%9C%EB%92%A4%EC%97%90%20Destroy%20%EC%8B%9C%ED%82%A4%EA%B8%B0

junhyungPARK78 commented 1 year ago
junhyungPARK78 commented 1 year ago
junhyungPARK78 commented 1 year ago
junhyungPARK78 commented 1 year ago

vector 의 각도를 검출하는 방법 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
junhyungPARK78 commented 1 year ago

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 를 사용할 필요가 없으므로 이쪽이 쉽게 구할 수 있을 듯.

junhyungPARK78 commented 1 year ago

위 두 방법을 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
junhyungPARK78 commented 1 year ago
junhyungPARK78 commented 1 year ago

가로 세로 모두 5도로 일단 설정. 하지만 따로 값을 빼두자.

5도 이하 벡터일 때는 일괄 5도로 설정한다.

삼각형 계산기 : https://ko.calcprofi.com/samgaghyeong-gyesangi.html

junhyungPARK78 commented 1 year ago

일단 오른쪽 벽에만 코드 설치했음. 플레이 하면서 막히는 부분 있으면 수정하자

junhyungPARK78 commented 1 year ago

추가

플레이 중 왼쪽 클릭하거나하면 공이 초기 속도로 돌아가는 문제 수정함

junhyungPARK78 commented 1 year ago
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;
}