Setting and Controlling Player

# Course Introduction

Player models are useful when making the initial properties of characters, but they are also useful when moving characters or controlling their status. Let's look into the concept of PlayerComponent and PlayerControllerComponent, and the relationship between an action and state animation so that the creator can make the player move as intended.

# PlayerComponent Concept

The PlayerComponent component is a collection of traits of players that differ from entities. The most common example is in PvP mode, where players can damage each other. The function of PlayerComponent is used to control players. You can let the player die, or move the player to another map or location. Player models without PlayerComponent will not be recognized as players. As it is only used in Players, you can also use PlayerComponent to identify Players. For instance, you can move the entity with PlayerComponent to a certain location, or put it in dead status under an additional condition.

#### Introducing Major Properties

[{"Property":"MaxHp","Explanation":"Sets the Player's maximum HP. Default value is 1000. The value is linked with HP in the UI status window model, so the change will be reflected in the UI model."},{"Property":"PVPMode","Explanation":"If activated, players can damage each other."},{"Property":"RespawnDuration","Explanation":"Sets the time taken until respawn after player's death. Default value is 5 seconds."},{"Property":"Enable","Explanation":"Sets whether to activate or deactivate the component."},{"Property":"Nickname","Explanation":"Refers to nickname Player set in web. If Player model has NameTagComponent, the player's nickname will be shown. It is not shown in the Property Editor. You can use it when composing scripts."},{"Property":"RespawnPosition","Explanation":"Sets the location where player will respawn. If not specified, it will follow SpawnLocation or the map entrance location. It is not shown in the Property Editor. You can use it when composing scripts."},{"Property":"RespawnTime","Explanation":"Refers to time taken until player re-enters map. It is not shown in the Property Editor. You can use it when composing scripts."},{"Property":"UserId","Explanation":"A unique identifier for the player. It can be used in the targetUserId parameter of the Client execution space control function."}]

# Concept of PlayerControllerComponent

PlayerControllerComponent executes actions and processes certain conditions according to input. For example, if you connect an action where a particular animation is played upon pressing the attack key, it will operate at every input of the attack key. However, when the player is climbing a ladder, the climbing animation will play. In this case, the attack animation should not be played. Therefore, when the player is on a ladder, you can add a condition: Pressing the attack key will not play the attack animation.

The basic Player model has both PlayerControllerComponent and StateComponent. However, if you delete either of them, the model will not work properly. That's because PlayerControllerComponent is referring to StateComponent. In order for PlayerControllerComponent to work, Player model also needs StateComponent.

> Tip PlayerControllerComponent processes input, action, and condition, while StateStringToAvatarActionComponent takes care of playing the animation. If the user presses a key to trigger Input, PlayerControllerComponent detects it and processes the Action after changing to a proper State. Then StateComponent processes the change of State and the action, triggering StateChangeEvent. Animation-related component like AvatarRendererComponent will receive this event to play the animation. 

#### Introducing Properties

[{"Property":"AlwaysMovingState","Explanation":"If activated, the moving animation will keep playing, even if character stays still."},{"Property":"FixedLookAt","Explanation":"If you change the value, the direction of the moving animation will not change, even if the character changes direction. You can use it to make the character face one direction only."},{"Property":"LookDirectionX","Explanation":"If you change the value to a positive number, the default state is the character looking to the right."},{"Property":"Enable","Explanation":"Sets whether to activate\/deactivate the component."}]

#### Basic Controls - key, value

These are default moving and action keys in MapleStory Worlds. You can use the keys as they are, or add more keys if necessary.

[{"key":"W, UpArrow","value":"MoveUp"},{"key":"A, DownArrow","value":"MoveLeft"},{"key":"S, LeftArrow","value":"MoveDown"},{"key":"D, RightArrow","value":"MoveRight"},{"key":"Space","value":"Jump"},{"key":"LeftAlt","value":"Jump2"},{"key":"LeftControl","value":"Attack"},{"key":"C","value":"Sit"}]

> Tip LeftAlt will be integrated to Jump. Please keep it in mind when creating.

# Example

#### Moving to a Different Map after a Limited Time

You can use `MoveToMapPosition()` to move players to a particular position. You can use this function to move users to several maps so that they can play a new game in a new map.

  1. In [png](1634600723422190820861d63456fa40e21031bd5ffa2) MyDesk, create a new PlayerManagement component, and add it to [png](16346008379922a9b756c3912461db7195808cb554abd) DefaultPlayer.
  2. Let's use `TimerService` to count 10 seconds, and enter the name and location of the map to move to in 10 seconds.  
The name of the map must be the same as the name in Hierarchy.



> Learn more `TeleportService:TeleportToEntityPath()` can move all Entities, but `PlayerComponent:MoveToMapPosition()` can only move players.
    
    
    @Component
    script GlobalPlayerRelocator extends Component
        @ExecSpace("ServerOnly")
        method void OnBeginPlay()
        _TimerService:SetTimerOnce(function()
            for userId, userEntity in pairs(_UserService.UserEntities) do
                userEntity.PlayerComponent:MoveToMapPosition('map02',Vector2(2,2)) 
            end
        end, 10)
        end
    end
    

[gif](1656586279970675fa3b0db73418d92fccc5d03da1a6e)

#### Respawning from Where the Player Died

Player's respawn position depends on SpawnLocation and map entrance location, but the creator can choose to respawn the player from where they died.

  1. In [png](1634600723422190820861d63456fa40e21031bd5ffa2) MyDesk, create a new PlayerSetting component, and add it to [png](16346008379922a9b756c3912461db7195808cb554abd) DefaultPlayer.
  2. We'll use `ConnectEvent` to get the location where the player died and set it as the respawn location.


    
    
    @Component
    script RespawnAnchor extends Component
        @ExecSpace("ClientOnly")
        method void OnBeginPlay()
        --     self.Entity:ConnectEvent(DeadEvent, function()
        --         self.Entity.PlayerComponent.RespawnPosition = self.Entity.TransformComponent.Position
        --     end)
        -- [Commented: MLUA requires @EventSender + handler pattern]
        end
    end
    

[gif](16565863334284c08832fec434f4789427b1b5a33d6ef)

#### Moving the Player to Certain Location

Among numerous entities, you can identify an entity with PlayerComponent as a player and move the player to a certain location. Let's make sure the TriggerComponent included in certain entities can identify PlayerComponent. Only players can identify this entity, so entities in the same space, like monsters, cannot be moved.

  1. Place an entity that can collide with the player in the map, name it MagicStone, and add TriggerComponent.
  2. To designate a certain entity's path as the destination, add a portal object in the map.
  3. In [png](1634600723422190820861d63456fa40e21031bd5ffa2) MyDesk, add a new PlayerMangement component, and add it to [png](16346008379922a9b756c3912461db7195808cb554abd) DefaultPlayer.
  4. If the entity that collided with a certain entity has PlayerComponent, the player will be moved to the input path ('maps/map01/portal-3').


    
    
    @Component
    script MagicStoneTeleporter extends Component
        @ExecSpace("ServerOnly")
        method void OnBeginPlay()
             local MagicStone = _EntityService:GetEntityByPath('/maps/map01/MagicStone') -- Enter the path of the entity that will collide with player. 
        --      MagicStone:ConnectEvent(TriggerEnterEvent, function(event)
        --         if event.TriggerBodyEntity.PlayerComponent then
        --             event.TriggerBodyEntity.PlayerComponent:MoveToEntityByPath('/maps/map01/portal-3')
        --         end
        --      end)
        -- [Commented: MLUA requires @EventSender + handler pattern]
        end
    end
    

[gif](1656586368440e1c78d968dba467b9b2d5cca978b4996)

#### Creating Conditional Actions

You can add a condition that can influence players' basic properties. With `AddCondition()` function, you can add conditions that can limit player actions. You can put limitations on the basic functions, attack, jump, and so on, under certain conditions for more fun.

  1. In [png](1634600723422190820861d63456fa40e21031bd5ffa2) MyDesk, create a PlayerSetting component, and add it to [png](16346008379922a9b756c3912461db7195808cb554abd) DefaultPlayer.
  2. Write a condition under which Jump action will be executed.  
If you write the condition to execute Jump when the value is bigger than 10, the opposite will also be true.
  3. Add a log so that you can see whether pressing the space bar to jump executes the jumping action.


    
    
    @Component
    script HealthJumpLimiter extends Component
        @ExecSpace("ClientOnly")
        method void OnBeginPlay()
        local playerController = self.Entity.PlayerControllerComponent
        playerController:AddCondition("Jump", function()
            if self.Entity.PlayerComponent.Hp < 10 then
                log("Stop Jumping")
                return false
            end
            return true
        end)
        end
    end
    

[gif](1656586397424b751fb67c7974fe694521961c9a7ecab)

#### Deleting Existing Key, Creating New Key

Creators can choose to delete existing keys and replace them with new keys. You can use this function to delete the moving keys (W, A, S, and D), and replace them with other keys.

  1. In [png](1634600723422190820861d63456fa40e21031bd5ffa2) MyDesk, create a PlayerSetting component, and add it to [png](16346008379922a9b756c3912461db7195808cb554abd) DefaultPlayer.
  2. Use `RemoveActionKey` to delete the action connected to the left Ctrl key. Then use SetActionKey to compose a script that links Attack to F key.


    
    
    @Component
    script ActionKeyInitializer extends Component
        @ExecSpace("ClientOnly")
        method void OnBeginPlay()
        local playerController = self.Entity.PlayerControllerComponent
        playerController:RemoveActionKey(KeyboardKey.LeftControl)
        playerController:SetActionKey(KeyboardKey.F, "Attack")
        end
    end
    

##### Reference Guide

  * [Editing Initial Character Properties](/docs?postId=48)
  * [Attack and Hit](/docs?postId=206)