Raycasting with Lumberyard – Part 2 – The Correct Way

When I wrote the original raycast tutorial, I thought Lumberyard did not provide a way to do this in C++ and we were stuck using CryEngine’s Raycasting. Fortunately I was wrong.

If you followed the first tutorial, I’m still going to use the PhysicsWrapper and all the other setup, but merely change the PhysicsWrapper gem to use Lumberyard’s EBus instead.

PhysicsWrapperSystemComponent.cpp:

Hit PhysicsWrapperSystemComponent::PerformRayCastWithParam(float distance, int colisionFlags)
{
    auto hit = AZStd::make_unique<ray_hit>();

    auto &cam = GetISystem()->GetViewCamera();

    auto direction = cam.GetViewdir();
    auto start = cam.GetPosition() + direction;

    LmbrCentral::PhysicsSystemRequests::RayCastConfiguration config;
    config.m_origin = LYVec3ToAZVec3(start);
    config.m_direction = LYVec3ToAZVec3(direction);
    config.m_maxHits = 1;
    config.m_maxDistance = distance;

    LmbrCentral::PhysicsSystemRequests::RayCastResult result;
    EBUS_EVENT_RESULT(result, LmbrCentral::PhysicsSystemRequestBus, RayCast, config);

    Hit phit;

    if (result.GetHitCount() > 0)
    {
        auto hit = result.GetHit(0);
        phit.position = hit->m_position;
        phit.normal = hit->m_normal;

        if (hit->IsValid())
        {
            phit.hit = true;
            phit.entity = hit->m_entityId;
        }
    }

#if !defined(_RELEASE)
    if (auto *pPersistentDebug = gEnv->pGame->GetIGameFramework()->GetIPersistentDebug())
    {
        const ColorF green(0.000f, 1.000f, 0.000f);
        const ColorF red(1.000f, 0.000f, 0.000f);

        pPersistentDebug->Begin("FG_Line", true);

        auto end = start + direction * distance;

        if (!!phit.hit && phit.entity.IsValid())
        {
            pPersistentDebug->AddLine(start, end, green, 500);
        }
        else
        {
            pPersistentDebug->AddLine(start, end, red, 500);
        }
    }
#endif

    return phit;
}

You will also need to add the LmbrCentral gem to your PhysicsWrapper gem dependencies.

Gems/PhysicsWrapper/gem.json:

{
    "Dependencies": [
        {
            "Uuid": "ff06785f7145416b9d46fde39098cb0c",
            "VersionConstraints": [
                "~>0.1"
            ],
            "_comment": "LmbrCentral"
        }
    ],
    "GemFormatVersion": 3,
    "Uuid": "453b88cf44d041709924810814c70a70",
    "Name": "PhysicsWrapper",
    "DisplayName": "PhysicsWrapper",
    "Version": "0.1.0",
    "LinkType": "Dynamic",
    "Summary": "Physics Wrapper",
    "Tags": ["Untagged"],
    "IconPath": "preview.png"
}

This should be work like it did before with one exception. The default settings for the Lumberyard Raycast does not consider the floor a valid target and will not return it as an entity.

Written By Greg Horvay

3 thoughts on “Raycasting with Lumberyard – Part 2 – The Correct Way

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s