Using Various Physics Joints

# Course Introduction

Let's see how to set the trip type of specific entities in a map that uses physics. You can use various JointComponents to create entities that perform various movements and use them to create Worlds.

# Joint

A joint refers to a specific link section that connects the particular entities on a map that applies the laws of physics, so that they can influence each other. Like the image below, the link section that allows Entity A and Entity B to influence each other is Joint. Once you set a Joint attachment location (LocalAnchor A) on Entity A, the standard entity, and set another Joint attachment location (LocalAnchor B) on the entity to connect to (TargetEntityRef), Entity B, Entity A and Entity B become connected.

[png](1663837353395619ae9a35f0a47a481baf3f797bb5446)

The Anchor's location sets the distance relative to the entity's ColliderOffset. Entities linked to each other may or may not collide, depending on the creator's intent.

  * Entity A: You can use another entity as TargetEntityRef by adding Joint as an entity with JointComponent.

    * ColliderOffset: An Entity's PhysicsColliderComponent's ColliderOffset. It is used as the origin of the LocalAnchor location.
    * LocalAnchorA: Set Anchor for Entity A with JointComponent. Take ColliderOffset of Entity A as the origin.
  * Entity B: Specify TargetEntityRef in JointComponent of Entity A as the entity to connect the Joint to.

    * TargetEntityRef: The Entity to connect the Joint to.
    * LocalAnchorB: Set the Anchor of Entity B, which is the Entity to connect the Joint to. Take ColliderOffset of Entity B as the origin.



[png](16638373662946c98c73c26ec4d78933f46034b0179c2)

#### Anchor

This is the reference point at which the joint operates. The entity's ColliderOffset location is used as the Anchor's origin. For example, as shown in the figure below, even if the values of LocalAnchor A and B are the same (3,0), the base entities' offset locations are different. LocalAnchor is located elsewhere, and the origin point of Entity A and B is the foothold.

The base Offset of LocalAnchor A is Entity A, and the base Offset of LocalAnchor B is Entity B.

[png](1663839068005e7743548cf8e44349be58cdf0cbf9300)

[gif](16638363593571f7fb2dde7e7440cb0c1b9447f4123e4)

#### Motor

Using Motor forces the Entity to move in a specific direction. It is used in RevoluteJointComponent, WheelJointComponent, and PrismaticJointComponent. If you set the MotorEnable property to true to use the motor, the entity will rotate according to the set target speed. Target speed means the value of MotorSpeed. For example, if MotorSpeed is 100, and the MotorSpeed value reduces to 10 once the speed reaches 100, the speed will decrease.

[gif](16638363279474aea43c2e0f849e78e12f9371b760269)

# Type of JointComponent

It includes six types: DistanceJointComponent, RevoluteJointComponent, PrismaticJointComponent, PulleyJointComponent, WeldJointComponent, and WheelJointComponent. Since each type has different characteristics, you should use the JointComponent that best fits what you want to create.

#### DistanceJointComponent

DistanceJointComponent sets the distance-related limits between two entities. The distance (Length) between LocalAnchorA and B remains constant.

[{"index":"Major Properties","0":"Length"},{"index":"Description","0":"Sets the distance that will be maintained between two Entities connected by a Joint."}]

[gif](1660634671012e4dbb294cfa94678b6af5dfc7804bc7f)

#### RevoluteJointComponent

RevoluteJoint sets the rotation-related limits between two entities. After activating UseLimits, you can control the rotation angle using LowerAngle and UpperAngle. When an entity rotates, the point where LocalAnchorA and B meet becomes the common Anchor. Also if you use Motor, you can receive the rotational power based on the Anchor.

[{"Major Properties":"UseLimits","Description":"Determines whether to set limits on relative angles."},{"Major Properties":"LowerAngle","Description":"Sets the minimum relative angle. It's based on the Entity's Local Vector2 (1, 0)."},{"Major Properties":"UpperAngle","Description":"Sets the maximum relative angle. It's based on the Entity's Local Vector2 (1, 0)."},{"Major Properties":"MotorSpeed","Description":"Sets the target speed of Motor. If it is a positive number, it rotates in a CCW (counterclockwise) direction."}]

[gif](1660634686437edf5ce687bf04396952bf91d804c774c)

#### PrismaticJointComponent

PrismaticJointComponent sets the entity to move linearly along the axis (LocalAxis). You can set the LowerTranslation and UpperTranslation values to limit the maximum and minimum distance the entity moves. The location of LocalAxis is relative to LocalAnchor.

[{"Major Properties":"UseLimits","Description":"Sets whether or not to limit the relative movement distance."},{"Major Properties":"LowerTranslation","Description":"Sets the minimum relative travel distance."},{"Major Properties":"UpperTranslation","Description":"Sets the maximum relative travel distance."},{"Major Properties":"MotorEnable","Description":"Sets whether to use Motor. If True, the attached Entity will receive a force in the direction of LocalAxis."},{"Major Properties":"MotorSpeed","Description":"Sets the target speed of Motor. MotorEnable must be True to operate."}]

[gif](16606347060771a318324cf13474ba3e52d4b6f847f92)

#### PulleyJointComponent

PulleyJointComponent maintains the sum of the total length of the distances between LocalAnchor and GroundAnchor. If one entity's line length (Length) gets shortened, the other entities' line length will get longer, maintaining the total length of the line. The total length is determined by the formula: Initial distance between Entity A and GroundAnchorA + Ratio * Initial distance between Entity B and GroundAnchorB. The lines of each entity are the distance between LocalAnchor and GroundAnchor, and the origin of GroundAnchor is the location of LocalAnchor. Ratio determines the percentage by which the distance between the Entity and GroundAnchor decreases. If the Ratio is 3 and the line of Entity A is reduced by 3, even if the line with Entity B is increased by 1, the line of Entity A has 1/3 of the constraint force compared to the line of Entity B.

[{"index":"Major Properties","0":"Ratio"},{"index":"Description","0":"Sets the constraint force ratio of both imaginary lines that form PulleyJoint."}]

[gif](1660634724636c6a1887dec234a97ad13994d906a7ebc)

#### WeldJointComponent

Sets it so that connected entities move together. They move while maintaining a certain distance apart, as if the two ends were attached to a skewer. Connected entities are constrained to relative movement and rotation.

[gif](1660634741001b728a6793af4499e8f64070bcf551639)

#### WheelJointComponent

WheelJoint sets the constraint to make the connected entity behave like a wheel. TargetEntityRef using Motor uses the MotorSpeed value as the target speed.

[{"Major Properties":"MaxMotorTorque","Description":"Sets the maximum strength applicable to the motor of the Joint in order to reach the target motor speed."},{"Major Properties":"MotorEnable","Description":"Sets whether to use Motor. If True, the attached Entity will receive a force in the direction of LocalAxis."},{"Major Properties":"MotorSpeed","Description":"Set the target motor speed of the Joint. MotorEnable must be True to operate."}]

[gif](16606347549715160d2650c9c4197a2b2b2ba189ecc6a)

# Adding Joint

The way to add a JointComponent is the same.

  1. Generate two entities with PhysicsRigidbodyComponent and PhysicsColliderComponent added and place them.
  2. Add the JointComponent you want to use. Enter the number of joints to generate in Size. [png](1690259361892e5e2bdd02e44452fb93da6ac7a30c4d6)
  3. After selecting the desired entity by using TargetEntityRef, set the location of LocalAnchor A and B. [png](1690259508600e65c1ca226c84bcfbdfa719299acb7a5)



# Example

Let's make a simple game that bounces a ball using RevoluteJointComponent. [gif](1660804708258db7c651cc14d4beb87fc23eee95cc3c8)

#### Ready

  1. Change the tile mode to RectTile. [png](16902702934039459adc7e8234eb4950ba11f2d11493f)
  2. Add Hierarchy - World - maps - map01 - PhysicsSimulatorComponent.
  3. Activate Hierarchy - World - maps - map01 - RectTileMap - RectTileMapComponent - PhysicsInteractable.
  4. Place a Static type physics entity so that the ball can hit it. Place it in a trapezoid shape with a hole in the bottom. 
     * SpriteRUID: 1ce2eff829ae4346bc89a3f0a357ac0e [png](169026003093236f6d51367a14dd4a906324c452a0d7d)



#### Making a Ball

  1. Create a new Ball model and add PhysicsRigidbodyComponent, PhysicsColliderComponent. 
     * Ball SpriteRUID: 164e94bea20441adac2af9c6f800bdf3
  2. Change PhysicsRigidbodyComponent's BodyType to Dynamic.
  3. Change PhysicsColliderComponent's ColliderType to Circle and adjust the CircleRadius to fit the sprite size.
  4. Place it in the air, allowing the ball to fall under gravity.



#### Creating Obstacles

  1. Create a new Obstacle model and add PhysicsRigidbodyComponent, PhysicsColliderComponent. 
     * SpriteRUID: 3ada0e4cc7f44cb988932f1b183ec778
  2. Change PhysicsRigidbodyComponent's BodyType to Static.
  3. Change PhysicsColliderComponent's ColliderType to Circle and adjust the CircleRadius to fit the sprite size.



#### Creating a Lever

  1. Generate a new object Entity of LeftEntity, LeftBar and add PhysicsRigidbodyComponent, PhysicsColliderComponent.

     * LeftEntity SpriteRUID: e75cac80f719471fa482195531ed57cc
     * LeftBar SpriteRUID: 0308ac89b10843fcab6384aa43f6ae22
  2. Add RevoluteJointComponent to the circular Entity, and enter 1 for Joint. Specify LeftBar to TargetEntityRef, and assign the values of LocalAnchorB, LowerAngle, UpperAngle, MotorSpeed, UseLimits as follows. [png](16902694608421c03f7e8bfc44e6eba274aefaef0bbf7)

  3. Copy the two entities above to create the opposite side. [png](1690269890755b731c1c566234f999b810610411cf45f)

  4. Create the new Swing script component and add it to DefaultPlayer.

  5. Enter as follows to make it so that when N or M is pressed, the motor of RevoluteJoint is used, and when released, it is not used.
         
         @Component
         script KeyboardMotorControl extends Component
         @Sync
         property Entity Left = "/maps/map01/LeftEntity"
         @Sync
         property Entity Right = "/maps/map01/RightEntity"
         
         @ExecSpace("ServerOnly")
         method void MoveLeft(boolean enable)
         self.Left.RevoluteJointComponent:SetMotorEnable(1, enable)
         end
         
         @ExecSpace("ServerOnly")
         method void MoveRight(boolean enable)
         self.Right.RevoluteJointComponent:SetMotorEnable(1, enable)
         end
         
         @EventSender("Service", "InputService")
         handler HandleKeyDownEvent(KeyDownEvent event)
         -- Parameters
         local key = event.key
         --------------------------------------------------------
         if key == KeyboardKey.N then
             self:MoveLeft(true)
         elseif key == KeyboardKey.M then
             self:MoveRight(true)
         end
         end
         
         @EventSender("Service", "InputService")
         handler HandleKeyReleaseEvent(KeyReleaseEvent event)
         -- Parameters
         local key = event.key
         --------------------------------------------------------
         if key == KeyboardKey.N then
             self:MoveLeft(false)
         elseif key == KeyboardKey.M then
             self:MoveRight(false)
         end
         end
         end
         



    
    
    7. Press Start to see if the bar moves when you press N and M respectively.
    
    ##### Reference Guide
    * [Using Physics](/docs?postId=757)
    * [Create Collision Group](/docs?postId=754)
    * [Applying Physics to Entities](/docs?postId=761)