본문 바로가기
Unity/2D

[Unity]2D게임만들기 #3_플레이어 이동,저항설정 / 리지드바디 오브젝트가 구를 때 해결방법/fixedUpdate와 Update의 차이점

by Meaning_ 2021. 8. 30.
728x90
반응형

물리이동 - player 양옆으로 이동 + 속도조절 


PlayerMove 스크립트를 만들어준 후, Player 객체에 넣어준다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class PlayerMove : MonoBehaviour
{
    Rigidbody2D rigid;
    void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();
    }
 
    // Update is called once per frame
    void FixedUpdate()
    {
        float h = Input.GetAxisRaw("Horizontal");
        rigid.AddForce(Vector2.right*h,ForceMode2D.Impulse);
    }
}
cs

 

+) Input.GetAxisRaw

 

:-1,0,1 중 한가지 값이 반환되는데 키보드를 눌렀을때 바로 반응해야하는 경우 사용한다. 

 

Input.GetAxisRaw("Horizontal")

 

: 입력값을 축 값으로 받아온다. Horizontal은 '가로의'를 뜻하며, 왼쪽 화살표를 누르면 -1,오른쪽 화살표를 누르면 1을 출력한다.

 

cf) 만약에 "Vertical"이 들어온다면 이는 '세로의'를 뜻할 것이고, 아래 화살표를 누르면 -1, 위쪽 화살표를 누르면 1을 출력한다.

 

<참고 사이트>

https://onecoke.tistory.com/entry/%EC%9C%A0%EB%8B%88%ED%8B%B0-GetAxis%EC%99%80-GetAxisRaw

 

유니티 :: GetAxis와 GetAxisRaw

1. Input.GetAxis(string name) -1.0f 부터 1.0f 까지의 범위의 값을 반환한다. 즉, 부드러운 이동이 필요한 경우에 사용된다. 2. Input.GetAxisRaw(string name) -1, 0, 1 세 가지 값 중 하나가 반환된다. 키보드..

onecoke.tistory.com

 

+) rigid.AddForce

 

리지드 바디에서 엄청 많이 쓰이는 오브젝트를 이동시키는 기능이다. 

AddForce(방향*힘 값, 힘의 종류)

 

rigid.AddForce(Vector2.right*h,ForceMode2D.Impulse);

 

여기서 ForceMode2D는 무엇일까?

어떤 식으로 힘을 전달할 것인가를 결정하는 것인데 종류가 4가지가 있다. Acceleration,Force,Impulse,and VelocityChange

 

 

Impulse 불연속 + 질량무시 x
짧은 순간의 힘, 충돌이나 폭발과 같은 것에 많이쓰임

Force 연속 + 질량무시 X
현실적인 물리현상을 나타낼때 많이 씀
Accel 연속+ 질량무시 O
질량과 관계없이 가속 , 오브젝트의 질량에 관계없이 가속을 주고 싶을 때 이용
Velocity Change 불연속+ 질량무시 O
질량에 관계없이 속도를 바꿈

 

<참고사이트>

https://luv-n-interest.tistory.com/687

 

AddForce에 대한 모든 것(+RelativeForce) [Unity]

Rigidbody에서 엄청 많이 쓰이는 AddForce를 알아보자 어떠한 form을 가지고 있냐? 2가지 형태가 있다. 하지만 비슷한 메커니즘을 가진다. public void AddForce(Vector3 force, ForceMode mode = ForceMode...

luv-n-interest.tistory.com

https://docs.unity3d.com/ScriptReference/Vector2.html

 

Unity - Scripting API: Vector2

Success! Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable. Close

docs.unity3d.com

 

이렇게 하면 플레이어를 양옆으로 움직일 수 있다. 하지만 문제점이 AddForce이기 때문에 꾸욱 누르면 player가 튕겨나간다...!

 

그렇기에 최대속력을 정해야한다. maxSpeed 변수를 만들어주고, 오른쪽 방향키와 왼쪽 방향키의 속력을 정해주겠다.

 

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class PlayerMove : MonoBehaviour
{
    public float maxSpeed;
    Rigidbody2D rigid;
    void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();
    }
 
    // Update is called once per frame
    void FixedUpdate()
    {
        float h = Input.GetAxisRaw("Horizontal");
        rigid.AddForce(Vector2.right*h,ForceMode2D.Impulse);
        if (rigid.velocity.x > maxSpeed)//오른쪽
        {
            rigid.velocity = new Vector2(maxSpeed,rigid.velocity.y);//y값을 0으로 잡으면 공중에서 멈춰버림
        }else if (rigid.velocity.x < maxSpeed*(-1))//왼쪽
        {
            rigid.velocity = new Vector2(maxSpeed*(-1), rigid.velocity.y);
        }
    }
}
cs

Velocity : 리지드바디의 현재 속도

 

maxSpeed를 3정도로 잡아준다. 

 

 리지드바디 오브젝트가 구를 때 해결방법


근데 문제가 생겼다.

 

방향키로 옆으로 이동시켜줬는데 애가 때굴때굴 굴러다니기 시작했다. 이유는 오브젝트가 CapsuleCollider2D여서 구르는거라 생각했고, BoxCollider2D로 바꿔봤지만 여전히 굴렀다. 

 

그래서 해결방법은 2가지가 있다.

 

1. RigidBody 2D -> FreezeRotation 클릭 

 

다행히 구르지 않지만, 이 방법을 사용하면 z축의 모든 회전발생을 막게 된다.

 

2. 스크립트에서 설정

 

 

rigid.freezeRotation =true; 코드를 추가해주면 된다. 이렇게 되면 플레이 버튼을 눌렀을 때 자동으로 앞서 봤던 Freeze Rotation이 켜진다. 이제는 굴러다니지 않고 양옆으로 잘 움직인다. 

 

 

<참고 사이트>

https://rank-brothers.com/615/unity-prevent-rigidbody-from-rotating

 

[Unity] Rigidbody 회전 방지하는 법 - 랭크 브라더스

Rigidbody(리지드바디)와 Collider(콜라이더) 컴포넌트를 붙였을 때 AddForce 등으로 속도를 붙이게 되면 오브젝트가 데굴데굴 구르는 경우가 있습니다. 어떤 경우에 회전이 발생하는지에 대한 예시와,

rank-brothers.com

https://docs.unity3d.com/ScriptReference/Rigidbody-freezeRotation.html

 

Unity - Scripting API: Rigidbody.freezeRotation

If freezeRotation is enabled, the rotation is not modified by the physics simulation. This is useful for creating first person shooters, because the player needs full control of the rotation using the mouse. See Also: Rigidbody.constraints.

docs.unity3d.com

 

물리이동 - 바닥재질 변경



바닥을 오르막길로 만들어볼것이다. 이렇게 하려면 바닥의 재질을 바꿔야하고, 빙판처럼 미끄럽게 만들어볼 것이다.

재질을 바꾸는 법은 Assets > Create > Physics Material 2D (Physic Material 은 3D이다)

 

이름을 Platform으로 지어주고 마찰력을 0으로 지정해준다.

 

모든 바닥 오브젝트(floor)의 Box Collider 2D -> material에  Platform을 넣어준다.

 

 

저항설정 - 공기저항


마찰력이 없기 때문에(floor의 material을 바꿔서)  Player가 미끌어져서 멀리 가버린다. 이것을 어떻게 해결할 수 있을까?

바로 공기저항으로 잡아볼 것이다!

 

RigidBody -> Linear Drag 로 가면 공기저항을 조절할 수 있다.

Linear Drag: 공기저항, 이동 시 속도를 느리게 해준다. 

Linear Drag를 2정도로 잡아준다. 너무 크게 잡으면 플레이어가 떨어질 때도 공기저항을 받는다..!

공기저항을 설정해주면 살짝 미끌어지다가 멈춘다!

 

저항설정 - 속력이 급격하게 줄어드는 효과 


 

살짝 미끌어지는 것을 보완하기 위해 키보드에서 손을 떼면 속력이 급격하게 줄어드는 효과를 만들어볼것이다. 

 

그냥 0.5를 쓰면 오른쪽(+)으로 가는지 왼쪽(-)으로 가는지 모르므로 rigid.velocity.normalized  를 이용해준다. 

이는 방향구할때 쓰는 것으로 오른쪽으로 가면 +1, 왼쪽으로 가면 -1이된다. getAxisRaw와 기능이 비슷하다.

코드 쓸 때는 rigid.velocity.normalized.x로 써줘서 x축을 가져오도록 한다. 

 

 

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
32
33
34
35
36
37
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class PlayerMove : MonoBehaviour
{
    public float maxSpeed;
    Rigidbody2D rigid;
    void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();
        rigid.freezeRotation = true;
    }
 
    // 키보드에서 손을 뗐을 때 완전 stop 
    private void Update() //즉각적인 키 입력 ,단발적인 키 입력
    {
        if (Input.GetButtonUp("Horizontal"))
        {
 
            rigid.velocity = new Vector2(rigid.velocity.normalized.x * 0.5f, rigid.velocity.y);
        }
    }
    void FixedUpdate() //지속적인 키 입력
    {
        float h = Input.GetAxisRaw("Horizontal");
        rigid.AddForce(Vector2.right*h,ForceMode2D.Impulse);
        if (rigid.velocity.x > maxSpeed)//오른쪽
        {
            rigid.velocity = new Vector2(maxSpeed,rigid.velocity.y);//y값을 0으로 잡으면 공중에서 멈춰버림
        }else if (rigid.velocity.x < maxSpeed*(-1))//왼쪽
        {
            rigid.velocity = new Vector2(maxSpeed*(-1), rigid.velocity.y);
        }
    }
}
 
cs

 

cf)normalized : 벡터크기를 1로 만든 상태 

 

 

+) 유니티에서 Input

 

마우스 관련 컨트롤 할 때 많이 사용되는 것 같다.

GetButtonUp 이라던지 GetMouseButton 등등.. 더 자세한 내용을 알고 싶으면 아래 링크의 유니티 스크립트를 보면되겠다!

https://docs.unity3d.com/kr/530/ScriptReference/Input.html

 

Unity - 스크립팅 API: Input

Input Manager에 설정된 각 축을 읽고 모바일 장치의 멀티터치/가속도계 데이터에 접근을 하는 경우에 이 클래스를 사용합니다. 다음의 기본 설정 축과 Input.GetAxis 함수를 이용해서 해당 축을 읽습니

docs.unity3d.com

 

+) FixedUpdate() 와 Update()

 

주석에도 서술해놓은것과 같이 FIxedUpdate는 지속적인 키 입력이 있을 때 쓰고, Update는 즉각적인 키 입력이 있을 때 쓴다. 키보드에서 손을 떼자마자 플레이어가 멈춰야 하는 경우 Update를 써야 즉각적으로 효과가 실행이된다. 만약, FixedUpdate를 쓴다면 효과가 실행되지 않을 수 있다.

 

 

728x90
반응형

댓글