Archive 17/01/2023.

How to retrieve specific data from collision

Durell

Hi there.

Currently making a simple game where i have a character swimming around and colliding with fish. Currently, i have it setup so when i collide with anything, a log is output to the handleupdate() function in my character.cpp.

I want to make it so on collision with a fish a flag inside the fish header file is changed from false to true, causing it to not be rendered etc using “pObject->SetEnabled(false);”

I had a look on the documentation for physics and collision and the only things mentioned in detail are location of the object etc.

Currently I dont know how to grab the specific fish that im colliding with and apply that flag to that specific fish.

Thanks!

Eugene

How do you handle collisions now?

Durell

Currently in my character cpp:

void Character::Start()
{
SubscribeToEvent(GetNode(), E_NODECOLLISIONSTART,
URHO3D_HANDLER(Character, HandleNodeCollision));
}

and

void Character::HandleNodeCollision(StringHash eventType, VariantMap& eventData)
{
// Check collision contacts and see if character is standing on
//ground(look for a contact that has near vertical normal)
Log::WriteRaw("(Collision!");
using namespace NodeCollision;

MemoryBuffer contacts(eventData[P_CONTACTS].GetBuffer());
while (!contacts.IsEof())
{
	Vector3 contactPosition = contacts.ReadVector3();
	Vector3 contactNormal = contacts.ReadVector3();
	/*float contactDistance = */contacts.ReadFloat();
	/*float contactImpulse = */contacts.ReadFloat();
	// If contact is below node center and mostly vertical, assume
	//it's a ground contact
	if (contactPosition.y_ < (node_->GetPosition().y_ + 1.0f))
	{
		float level = Abs(contactNormal.y_);
		if (level > 0.75)
			onGround_ = true;
	}
}

}

Eugene

eventData contains collided Nodes, see E_NODECOLLISIONSTART description.

Durell

I have looked on the urho physics wiki and googled the term but i cant find any description about what it returns and how to access it etc.

Eugene

Code is the best documentation :wink:
Quite easy to read if you use IDE. Just navigate to event name declatation. Or look here:

Durell

Okay so ive found what i needed

NodeCollisionStart
Body : RigidBody pointer
OtherNode : Node pointer
OtherBody : RigidBody pointer
Trigger : bool

but now how do i access this information? Ive tried eventdata.??? and none of the options my ide gives me are the node its colliding with.

Eugene

It’s like any other event property: eventData[P_OTHERNODE].GetPtr() or eventData["OtherNode"].GetPtr() in script.

Durell

is it also possible to despawn the object from the node pointer? Currently ive been using

pObject->SetEnabled(true);
pObject->SetEnabled(false);

to toggle objects on or off but this is using the staticmodel of the object.

Can this be done just using information from this event?

Eugene

It’s better to always toggle Nodes instead of components. Unless you really need the opposite.

Durell

so just to clarify, do i assign eventData[P_OTHERNODE].GetPtr() to a node first? such as

node* nodetodelete = eventData[P_OTHERNODE].GetPtr()

then

nodetodelete->SetEnabled(false)?

not quite sure how to turn an Urho3DRefCounted into an URHO3DNode

Eugene

Yes.

Do static_cast for the pointer. Or dynamic_cast if you are paranoid about types.

Bluemoon

Just as @Eugene rightly said, below is a line of code in one of my projects

Node* otherNode = static_cast<Node*>(eventData[P_OTHERNODE].GetPtr());