모바일 기기의 중력 센서 사용하기

# 학습 과정 소개

`MobileGyroscopeService`를 활용해 모바일 기기에서 자이로스코프 센서 기능을 지원하는지 확인하고, 값을 측정할 수 있습니다.

# MobileGyroscopeService

`MobileGyroscopeService`를 활용하면 모바일 기기의 중력, 중력 가속도, 회전 가속도 값 등을 측정해 기기가 어디서, 얼마만큼의 힘을 받아 움직였는지 알 수 있습니다. 예를 들어 핸드폰을 위로 던졌을 때 얼마나 위로 올라갔는지 측정할 때 이 서비스를 사용합니다.

MobileGyroScopeService는 모바일에서만 테스트와 활용이 가능합니다. 그러므로 기기가 자이로스코프 센서를 지원하는지 확인하고, 이를 지원하지 않는 기기를 사용 중이라면 안내해야 합니다.
    
    
    @Component
    script MobileGyroscopeController extends Component
        method void GyroscopeCheck(boolean onoff)
        if _MobileGyroscopeService:IsHWSupported() then
        	if _MobileGyroscopeService:IsEnabled() then
        		_MobileGyroscopeService:StopAndWait(false)
        	else
        		_MobileGyroscopeService:StartAndWait()	
        	end
        else
        	_UIToast:ShowMessage("Failed to start gyroscope")
        end
        end
    end
    

# 활용 예제

모바일 기기를 특정 방향으로 흔들었을 때 공이 해당 방향으로 힘을 받아 움직이게 만들어 봅시다. [gif](1669112286682bf20fdee201444148bdcf22b3e9c2a8c)

#### 벽 만들기

  1. Hierachy - World - maps - map01에서 콘텍스트 메뉴를 열어 Switch to RecTileMap을 선택합니다.

  2. Hierachy - World - maps - map01에 PhysicsSimulatorComponent를 추가합니다.

  3. 새로운 Wall 엔티티를 생성하고, TransformComponent, SpriteRendererComponent, CustomeFootholdComponent를 추가합니다.

  4. 벽 모양 RUID를 SpriteRendererComponent - SpriteRUID에 입력하고, 스프라이트 길이만큼 CustomFootholdComponent로 발판을 생성합니다.

     * SpriteRUID: 9b518d2cf3a549f4bdbbac8662fecd42
  5. PhysicsColliderComponent를 추가하고, 충돌 영역을 스프라이트 크기에 맞게 조정합니다.

  6. PhysicsRigidbodyComponent를 추가하고, 프로퍼티를 설정합니다.

     * BodyType: Static
     * Friction: 0.5
     * Restitution 0.2
     * CollisionDetectionMode: Continuous
  7. 만든 벽을 3개 복사해 사각형 벽을 만듭니다.




#### 공 만들기

  1. 새로운 TiltBall 엔티티를 생성하고,TransformComponent, SpriteRendererComponent를 추가합니다.

  2. 공 모양 RUID를 SpriteRendererComponent - SpriteRUID에 입력합니다.

     * SpriteRUID: 777ee92d25c84f839a12739590d149b6
  3. TiltBall에 PhysicsColliderComponent를 추가하고, ColliderType을 Circle로 설정한 뒤 충돌 영역을 스프라이트에 맞게 지정합니다.

  4. PhysicsRigidbodyComponent을 추가하고, 프로퍼티를 아래와 같이 설정합니다.

     * BodyType: Dynamic
     * Mass: 1
     * Friction: 0.2
     * Restitution: 1
     * CollisionDetectionMode: Discrete
     * GravityScale: 1
     * SleepingMode: StartAwake



#### 공 움직이게 만들기

  1. 새로운 GyroscopeLogic을 생성합니다.

  2. Property를 추가하고, BallEntityRef에 TiltBall을 지정합니다.
         
         @Component
         script BallForceController extends Component
         property EntityRef BallEntityRef = "/maps/map01/TiltBall"
         property number ForcePower = 100
         end
         



    
    
    3. `MobileGyroscopeService:IsHWSupported()`를 활용해 기기에서 자이로스코프 센서를 지원하는지 확인한 후, 값 측정을 시작합니다.
    
        ```lua
    @Component
    script GyroscopeActivator extends Component
        @ExecSpace("ClientOnly")
        method void OnBeginPlay()
        if _MobileGyroscopeService:IsHWSupported() then
        	local enabled = _MobileGyroscopeService:StartAndWait()
        	if enabled then
        		_UIToast:ShowMessage("Gyroscope Started!")
        	else
        		log_error("Failed to start gyroscope")
        	end
        end
        end
    end
    

  4. 기기가 받은 힘과 방향에 따라 움직이도록 아래와 같이 작성합니다.
         
         @Component
         script GyroBallController extends Component
         method void OnUpdate(number delta)
         if _MobileGyroscopeService:IsEnabled() then
             local userAcceleration = _MobileGyroscopeService:GetUserAcceleration()
             local userAccelDir = Vector2(userAcceleration.x, userAcceleration.y)
             self:Tilt(userAccelDir)
         end
         end
         
         @ExecSpace("ServerOnly")
         method void Tilt(Vector2 direction)
         if direction.x > 0.2 or direction.y > 0.2 then
             self.BallEntityRef.PhysicsRigidbodyComponent:ApplyForce(direction * self.ForcePower)	
         end
         end
         end
         



    
    
      5. 월드를 출시하고, 모바일에서 확인합니다.
    
    ##### 참고 가이드
    * [발판 만들기](/docs/?postId=71)
    * [RectTileMap의 활용](/docs/?postId=589)
    * [물리 사용하기](/docs/?postId=757)