Say I am using a game engine that provides the following. More importantly, the HitResult is the only thing provided to me when I ray trace from a Player. Thus I cast the HitActor to see if I hit a player or not. Is there a way around using a dynamic cast in this situation without changing any Engine code? Thanks! Edit: I realize I should be using smart pointers and some bad formatting ;)
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
/** Engine Code Start */
class Actor
{
public:
Actor() = default;
Actor(string name) : m_name{name} {};
virtual ~Actor() = default;
string GetName() { return m_name; }
void SetName(string name) { m_name = name; }
private:
string m_name{""};
};
class Person : public Actor
{
public:
Person() = default;
Person(string name) : Actor{name} {};
virtual ~Person() = default;
};
class Wall : public Actor
{
public:
Wall() = default;
Wall(string name, uint32_t height) : Actor{name}, m_height{height} {};
virtual ~Wall() = default;
uint32_t GetHeight() { return m_height; }
void SetHeight(uint32_t height) { m_height = height; }
private:
uint32_t m_height{0};
};
struct HitResult
{
HitResult() = default;
HitResult(Actor* actor, uint8_t damage) : m_hitactor{actor}, m_damage{damage} {};
virtual ~HitResult() = default;
Actor* m_hitactor = nullptr;
uint8_t m_damage;
Actor* GetHitActor() { return m_hitactor; }
uint8_t GetHitDamage() { return m_damage; }
};
/** Engine Code End */
// Determine if actor hit is Person or something else?
int main(){
Person* player1 = new Person("Bob");
Person* player2 = new Person("Phil");
Wall* wall1 = new Wall("Wall1", 15);
if (player1 == nullptr || player2 == nullptr || wall1 == nullptr)
{
delete player1;
delete player2;
delete wall1;
return -1;
}
cout << "Player1's Name: " << player1->GetName() << endl;
cout << "Player2's Name: " << player2->GetName() << endl;
cout << "Wall1's Name: " << wall1->GetName() << ", height = " << wall1->GetHeight() << endl;
// Player1 Shoots at Player2, determine if object shot is Wall or Player object:
// Caveat: Engine only provides Base Class (Person) _not_ a Derived Class (Actor)!
HitResult hr(player2, 50);
// Question: Is there a way to _not_ use a dynamic cast here?
Person* HitPlayer = dynamic_cast<Person*>(hr.GetHitActor());
if (HitPlayer != nullptr)
{
cout << "Player hit!" << endl;
}
else
{
cout << "Person not hit!" << endl;
}
delete player1;
delete player2;
delete wall1;
return 0;
}
The live example is here: Live Example
Edit: Main Question: Given the HitResult
struct as input is there a way, besides dynamic_cast
, to check if the hit actor is a Person object and not a Wall object?
Standard Out:
Player1's Name: Bob
Player2's Name: Phil
Wall1's Name: Wall1, height = 15
Player hit!