Another CollisionManager question...

Chipmunk2D Bindings for the Unity3D engine
Post Reply
ensomniac
Posts: 17
Joined: Thu Sep 05, 2013 1:54 pm
Contact:

Another CollisionManager question...

Post by ensomniac »

Hey guys,
I'm having trouble, like some other people seem to be having, in getting collision detection to work. The documentation is a little unclear and the examples don't seem to provide a clear JavaScript example. I'm not quite sure where to put my ChipmunkCollisionManager class.

I have only one object called crate that is duplicated many times. I'm trying to determine when two crates collide with each other.

1. I have named my prefab crate, "crate".
2. On the Chipmunk Box Shape, I have entered "crate" into the "Collision type" field.
3. On a script attached to each crate, I have this code:

Code: Select all

class collisionMananger extends ChipmunkCollisionManager {

	function ChipmunkBegin_crate_crate(arbiter : ChipmunkArbiter){
		print(arbiter);
		return true;
	}
	
}
4. I never get any response.

Is this where the ChipmunkCollisionManager belongs? Does it belong on an object unrelated to the crates? Any idea what I'm doing wrong? Any help would be great.

Thanks
Ryan
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Another CollisionManager question...

Post by slembcke »

Collision managers are global objects, and not something that you attach to individual game objects. You only get a single callback per pair of colliding types and not per pair of colliding shapes. If you look at the examples, the code tends to look something like this:

Code: Select all

protected bool ChipmunkBegin_player_monster(ChipmunkArbiter arbiter){
  ChipmunkShape playerShape, mushroomShape;
  arbiter.GetShapes(out playerShape, out monsterShape);
  
  // Need to use GetComponent() to get components attached to the player:
  PlayerController player = playerShape.GetComponent<PlayerController>();
  MonsterController monster = monsterShape.GetComponent<MonsterController>();

  player.HitByMonster(monster);
  return true;
}
There are two reasons it works this way.
1) Unity provides absolutely no efficient way to dispatch events (like OnCollisionEnter) to other components like they do internally. In fact, the only API they provide for native code that is similar to SendMessage() is even slower and more limited.
2) Chipmunk collision events work using global "handlers". Several of the handler callbacks (like begin) return a boolean to decide to filter the collision or not. So it calls a single function when the player and monster collide, and it's return value says to keep the collision or not. Calling two functions, one telling you that a player shape collided with a monster shape and one telling you a monster shape collided with a player shape really only makes sense in Unity. Because of #1, we opted to offer features that Unity didn't have by more closely matching how Chipmunk works instead of giving it awful performance trying to make it work exactly like Unity.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
ensomniac
Posts: 17
Joined: Thu Sep 05, 2013 1:54 pm
Contact:

Re: Another CollisionManager question...

Post by ensomniac »

Thanks for replying, I really appreciate it.

I was able to get my collision detection working in C#. I was trying to accomplish this in Javascript and that was not working. Is it possible to do collision detection in Javascript or should this remain in C#?

If I have to detect collisions inside C#, can I call JavaScript components attached to my colliding objects from C#?

crateA.GetComponent<crateControllerJS>;

The above doesn't seem to work since I get a namespace error. I'm not used to Unity C# code so this might be outside of the scope of Chipmunk documentation. Any help would be awesome. Thanks!
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Another CollisionManager question...

Post by slembcke »

Yeah, it works fine with Unity's "javascript". You can also call between C# and javascript since they run on the same VM, but that's another matter.

I should have just pointed to the javascript example in the documentation. I wasn't even thinking about that. Sorry. http://chipmunk-physics.net/unityDocs/A ... nager.html The GetComponent() syntax in javascript is a little different since it doesn't support generic types. Otherwise it's pretty much the same.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
ensomniac
Posts: 17
Joined: Thu Sep 05, 2013 1:54 pm
Contact:

Re: Another CollisionManager question...

Post by ensomniac »

Thanks for the clarification. I have everything working now and it's working as expected. I'm not sure what I was doing wrong when I initially tried to hook up my collision manager in JS but it's working now.

One last question about collisions - should I expect a substantial performance hit from reading collision values from the arbiter?

The simple act of printing out the value in this return script brings my game to its knees: body.gameObject.GetComponent(controller).collide(arbiter.kineticEnergy);

"Collide" is a function inside controller where I'm affecting the color of the object based on the kinetic energy. I seem to have lost a ton of performance. Since I haven't delved too deeply into performance yet and I potentially have my own issues to optimize, i'm just curious if I should expect such a performance hit from simply sending values from the arbiter to a script. Thanks!
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Another CollisionManager question...

Post by slembcke »

Hmm. I guess it depends on what your Collide() function is doing. When you say "The simple act of printing out the value" do you mean calling Debug.Log()? Logging can get very expensive depending on how many times per frame you print things. Otherwise calling that specific arbiter function should be very inexpensive compared to the GetComponent() call and logging anyway.

Also:
body.gameObject.GetComponent(controller).collide(arbiter.kineticEnergy)

Can become:
body.GetComponent(controller).collide(arbiter.kineticEnergy)

Though I doubt that would have any real performance impact.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
ensomniac
Posts: 17
Joined: Thu Sep 05, 2013 1:54 pm
Contact:

Re: Another CollisionManager question...

Post by ensomniac »

Cool, thanks for the feedback. I need to test some more to identify exactly where my slowdown is coming from. I'm manipulating the shader each frame based on the kineticEnergy parameter of the collision and I have about 60 objects colliding so it might just be too overwhelming in general.
Post Reply

Who is online

Users browsing this forum: No registered users and 6 guests