Unity DOTS/따라하며 배우기

UNITY DOTS - State Machine(상태 머신) 만들기 #2 Player

개양반 2022. 8. 5.

오늘 알아볼 내용

WSAD로 Player를 이동시키는 기능을 구현한다. (오늘은 매우 심플하다!)


사용자 입력에 따라 방향값 받아오기

ASDW 또는 상하좌우 방향키 입력에 따라 Player가 이동해야 하는 방향값(x,y)을 설정하는 기능을 구현할 예정이다. 아래 코드를 작성한다.

using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;

struct UserInputData : IComponentData
{
    public float2 Move;
}

public partial class GetherInputSystem : SystemBase
{
    protected override void OnUpdate()
    {
        var horizontal = Input.GetAxis("Horizontal");
        var vertical = Input.GetAxis("Vertical");

        Entities
            .WithName("GatherInput")
            .ForEach((ref UserInputData inputData) =>
            {
                inputData.Move = new float2(horizontal, vertical);
            }).ScheduleParallel();
    }
}

#코드 설명

Input.GetAxis을 사용하기 위해 Using UnityEngine 네임스페이스를 추가했다. .ScheduleParallel(); 으로 예약했으므로 GetherInputSystem은 멀티스레드에서 병렬로 처리될 것이다.

사실 이렇게 가벼운 시스템은 Run으로 설정해서 메인스레드에서 동작하게 해도 상관없어 보인다.

 


플레이어 이동 System

using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;

struct MovementSpeed : IComponentData
{
    public float MetersPerSecond;
}

public partial class MovePlayerSystem : SystemBase
{
    protected override void OnUpdate()
    {
        var deltaTime = Time.DeltaTime;

        Entities
            .WithName("MovePlayer")
            .ForEach((ref Translation translation, in UserInputData input, in MovementSpeed speed) => {
               
                translation.Value
                   += new float3(input.Move.x, 0.0f, input.Move.y) * speed.MetersPerSecond * deltaTime;

            }).ScheduleParallel();
    }
}

#코드 설명

Input으로 전달받은 x, y에 따라 플레이어가 이동하는 시스템이다. 

 


Player에게 ComponentData 추가하기

Player GameObject가 런타임이 되면 Entity로 전환되고 이때,  Player에게 ComponentData를 추가하고 이동속도 값을 설정하는 기능을 구현한다.

using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;

[GenerateAuthoringComponent]
public struct PlayerTag : IComponentData
{
}


[DisallowMultipleComponent]
public class PlayerAuthoring : MonoBehaviour, IConvertGameObjectToEntity
{
    public float MovementSpeedMetersPerSecond = 5.0f;


    public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
    {
        dstManager.AddComponents(entity, new ComponentTypes(
            typeof(PlayerTag),
            typeof(UserInputData),
            typeof(MovementSpeed)
            ));


        dstManager.SetComponentData(entity, new MovementSpeed { MetersPerSecond = MovementSpeedMetersPerSecond });
    }
}

#코드 설명

기존 유니티의 Tag는 EntityQuery에서 사용할 수 없다. 그래서 Tag도 Componet로 만들어서 사용하고 있다.

GameObject가 Entity로 전환될때 EntityManager를 통해 PlayerTag, UserInputData, MovementSpeed를 추가하고 MetersPerSecond 값을 설정하는 코드이다.

 


Player 게임오브젝트 만들기

Hierarchy 뷰에서 게임오브젝트를 만들고 아래와 같이 설정한다. 

 

Play 버튼을 눌러 상하좌우로 이동이 제대로 구현되었는지 확인한다. 

댓글

💲 추천 글