Game Development Community

2 Questions: Mounting particles to an object? How to make the player rotate with the object he's standing on?

by Orion the Hunter · in Torque Game Builder · 11/15/2012 (9:13 am) · 40 replies

Hello,

I tried to mount a particle effect to an enemy but whenever he moves, the particle stays where it is. I tried to mount the particle to the enemy, and that didn't work so I mounted the enemy to the particle and that didn't work either. It's supposed to follow the enemy like a dark aura. Is there a way to make it follow the enemy?

I have another question. How can I make it so that instead of looking like the player is like this:

s11.postimage.org/mpq36gv1f/Screen_Shot_2012_11_15_at_12_08_35_PM.png
He is more like this:

s8.postimage.org/5grj7ncp1/Screen_Shot_2012_11_15_at_12_08_53_PM.png
I assume it should be something like this:

$Game::Player.rotation = getGroundRotation();

But I don't quite know where to start.
Page «Previous 1 2
#1
11/15/2012 (7:53 pm)
Is there rotation offset that you can use?
#2
11/15/2012 (9:41 pm)
You should mount the particle effect to what you want it attached to. There's a couple ways to do it, either in the editor or from a script call. I believe through script you'd want to set it up like:
function enemyClass::onLevelLoaded(%this, %scenegraph)
{
  %aura = new t2dParticleEffect()
  {
   scengraph = %scenegraph;
   effectFile = "path.eff";
   //effectMode, size, etc..
  };
  %link = %aura.mount(%this, "0 0");
  %aura.playEffect(false);
}


As for rotation.. There are a few ways you could handle it, really depends on what works best. If I were to do it, I would have each object that the "player" lands on have a %rotation value, and use onCollision to set the rotation to the player. That way if you want him straight and the rotation is 0, he should be straight, if it's 30 degrees, he's 30degrees, etc..

Hope that helps.
#3
11/16/2012 (5:18 am)
Thanks for the help!

So with your code, if I had several enemies and one effect file, it wouldn't make a difference, right? And for:

%link = %aura.mount(%this, "0 0");

It has 0 0. Did you add that as the place on the map where it's mounted or the place on the drill where it's mounted?
#4
11/16/2012 (5:38 am)
So long as they were each loaded individually to the level it would give it to each element of that class.
And the mount function is setup that way so if you need to adjust something else (rotation and other things) you can do it with the variable %link, and yes you may very well have to adjust the "0 0" to best work with how your effect is setup.

Now I will back up a little a say this, if you don't have all enemies loaded into your project initially (unlikely) you'd most likely want to move where you put your particle effect. So for instance, you call a function spawnEnemy, and within that function you could mount the emitter so that every instance would receive it.
#5
11/16/2012 (7:56 am)
(As usual with my codes :P) This isn't functioning properly...


function DrillClass::onAddToScene( %this )
{
    Parent::onAddToScene( %this );

  %aura = new t2dParticleEffect()
  {
   scengraph = %scenegraph;
   effectFile = "~/data/particles/SpeedshotExplode.eff";
   //effectMode, size, etc..
  };
  %link = %aura.mount(%this, "0 0");
  %aura.playEffect(false);

    if ( isObject( DrillHeadTemplate ) )
    {
        %this.DrillHead = new t2dSceneObject()
        {
            Config     = DrillHeadTemplate;
            Scenegraph = %this.Scenegraph;

            FlipX = %this.FlipX;
        };

        %this.DrillHead.mount( %this );
    }
}

It gives me the following errors when I load the level:

Quote:t2dSceneObject::mount() - Object '1979' is not in a SceneGraph!
t2dParticleEffect::playEffect() - Cannot Play; no emitters!

I'm a little confused... I placed the code you gave me between the "onAddToScene" function... but as I said, it give me an error. And for some reason all the game's sound is messed up but that's irrelevant.

Thanks, Doc!
#6
11/16/2012 (9:07 am)
A couple things might be happening, first and foremost you need to check some grammatical errors (see code below) Capitol Letters make a difference!!

Also, you may need to add more information to your effect, there are a TON of things that particles use, I just gave a crude example, but most likely you will need: effectMode(INFINITE) or whatever your life span is.. size, etc.. Really depends on the emitter itself and what all you want it to do.

The grammatical fixes may fix the problem, but it might not. I'd need a bit more information in order to truly diagnose what might be causing the problem. That's why I go by Doc.. I like to fix things ;)

If you feel like it's causing more hiccups, you can send me an e-mail, and I can potentially hope you out a bit more. Rather than going back in the forums. Not that it's a bad thing to get others input, but tends to speed up the process a bit in my opinion.

Here's what should be your function:
function DrillClass::onAddToScene( %this, %scenegraph )
{
    Parent::onAddToScene( %this );

  %aura = new t2dParticleEffect()
  {
   scenegraph = %scenegraph;
   effectFile = "~/data/particles/SpeedshotExplode.eff";
   effectMode = "INFINITE";
   effectTime = "0";
   //size = "10 10" //(whatever size it should be)
  };
  %link = %aura.mount(%this, "0 0");
  %aura.playEffect(false);

    if ( isObject( DrillHeadTemplate ) )
    {
        %this.DrillHead = new t2dSceneObject()
        {
            config     = DrillHeadTemplate;
            scenegraph = %scenegraph; //%this.scenegraph would probably work here as well

            FlipX = %this.FlipX;
        };

        %this.DrillHead.mount( %this );
    }
}

Also note you can set information for the emitter using %aura.(Field) as well. It may take some tweaking, but I would assume you played with the emitter to get the desired result in your editor first. So make sure to use the relevant information.
#7
11/16/2012 (10:37 am)
Hey Doc,

Thanks! I'm still getting similar errors. Question: If my particle is in "(Game's name)/game/data/particles/speedshotExplode.eff" then what should I write in the effectFile part?

It says that 1790 is not a scene graph in the error console. Tweaking suggestions?

P.S. I would prefer to keep the discussion on the forum, if that's alright. ;)
#8
11/16/2012 (11:32 am)
The path is correct for where you have it. I don't mind it here, it helps everyone out in the long run. Let's try adding a few more lines and see if we can get this working:
function DrillClass::onAddToScene( %this, %scenegraph )
{
    Parent::onAddToScene( %this );

  %aura = new t2dParticleEffect()
  {
   scenegraph = %scenegraph;
   effectFile = "~/data/particles/SpeedshotExplode.eff";
   effectMode = "INFINITE";
   effectTime = "0";
   size = "10 10" //(whatever size it should be)
  };
  %link = %aura.mount(%this, "0 0");
  %aura.playEffect(false);
  %aura.isPlaying = true;

    if ( isObject( DrillHeadTemplate ) )
    {
        %this.DrillHead = new t2dSceneObject()
        {
            config     = DrillHeadTemplate;
            scenegraph = %scenegraph; //%this.scenegraph would probably work here as well

            FlipX = %this.FlipX;
        };
        %this.DrillHead.addToScene(%scenegraph);
        %this.DrillHead.mount( %this );
    }
}

Ok, I have added %aura.isPlaying (let's make sure it's playing), and DrillHead.addToScene (you created the object, now add it to the scene).

Now.. if for some reason the effect is still not working, it may be an issue with creation. You may not have the emitters and stuff setup as they should be. I un-commented out size to make sure a size is applied (it may be too large, but that's up to your design).

One last thing if this still coughs up scenegraph errors. It may be that it's not registering the scenegraph correctly. So add the line below, and switch out %scenegraph inside the function (not the parameter calls though, they should stay as %scenegraph)
$theScenegraph = sceneWindow2D.getSceneGraph();
#9
11/16/2012 (12:42 pm)
Huh. I'm still getting problems. This is odd. The game is giving me a syntax error on your scenegraph function and it still gives the emitter error as well as the scenegraph one. In other words, it didn't work... I'm pretty sure there is no creative issue.

Oh yeah, I should mention that when I tried:
t2dparticleeffect::playeffect(speedshotexplode);
in the console, the game quit on me.
#10
11/16/2012 (1:05 pm)
Perhaps you should back up a few steps and do this in the editor first, and then see if it can be re-produced as expected through script.

Try putting in your DrillClass object, and mount the effect to it (may need to add a mount point). (It should show up in your effects, if not reload project).

For simplicity sake, you could give it behavior movements and just test and make sure the emitter works as a level loaded object. Once you know that portion is complete and working, you can take the parameters out of your level file to pass back into the script.

Make sure to comment out any scripts that are causing errors, so you get a clean build and then can work into getting a fully functioning product.

Sometimes you gotta take 2 steps back in order to take a step forward.
#11
11/17/2012 (6:29 am)
Problem fixed! It turned out I could get the scenegraph to work. I just dug through a few core files and found the correct code. Then I got as many parameters as possible from the level file and added them in. Here is what I got:

function DrillClass::onAddToScene( %this, %scenegraph )
{
    Parent::onAddToScene( %this );

  %aura = new t2dParticleEffect()
  {
      scenegraph = %this.getSceneGraph();
      effectFile = "~/data/particles/SpeedshotExplode.eff";
      useEffectCollisions = "1";
      effectMode = "INFINITE";
      effectTime = "100";
      canSaveDynamicFields = "1";
      Position = "44.630 34.560";
      size = "30.400 30.293";
      SortPoint = "-0.037 -0.295";
      CollisionMaxIterations = "1";
      MountOffset = "-0.024 0.488";
      MountOwned = "0";
      MountInheritAttributes = "0";
         mountID = "10";
         mountToID = "9";
  };
  %link = %aura.mount(%this, "0 0");
  %aura.playEffect(true);
  %aura.isPlaying = true;

    if ( isObject( DrillHeadTemplate ) )
    {
        %this.DrillHead = new t2dSceneObject()
        {
            config     = DrillHeadTemplate;
            scenegraph = %scenegraph; //%this.scenegraph would probably work here as well

            FlipX = %this.FlipX;
        };
        %this.DrillHead.addToScene(%scenegraph);
        %this.DrillHead.mount( %this );
    }
}

So now I can mount it to the drill. When I play my game, the particles follow the drill. Thanks everyone, and especially Doc. I guess you really live up to your name. ;)
#12
11/17/2012 (8:51 am)
Dude, can't wait to see your game. Seems like it's an intense platformer.
#13
11/17/2012 (11:53 am)
;) Thanks! I can't wait till it's done either. But I could never have done it with you guys helping me out. :) Does anyone know where the rotation variables are stored where I could edit them to %this.Rotation?
#14
11/17/2012 (12:29 pm)
(Sorry for double posting!)

Okay, so I added this in the fields for the particle that I mounted:

layer = %this.getLayer();
That makes it so that when the drill is going behind something, the particle doesn't float around behind it.
#15
11/19/2012 (9:29 am)
Sorry, must've overlooked your other question, any t2dSceneObject houses a .rotation value.

So, assuming it's referring to the 1st question, you'd want to do something similar to this:
function playerClass::onCollision(%srcObject, %dstObject, %srcRef, %dstRef, %time, %normal, %contacts, %points)
{ 
  if (%dstObject.class $= "platformClass")
  {
    %scrObject.rotation = %dstObject.rotation;
  }
}

This would make your player (assuming it's class is playerClass rotate to the platform's (assuming it's class is platformClass) rotation.
#16
11/20/2012 (7:21 pm)
Hmm. Still is giving me problems. :( Any suggestions?
#17
11/20/2012 (7:55 pm)
What is the problem??
#18
11/20/2012 (8:05 pm)
Only thing to double check is make sure your platforms "receive" collisions, and your player "sends" (and probably receives). And make sure that your platforms rotation value is being adjusted as you'd want your player to rotate.
An alternative.. and it depends on how you want the interaction to be, is to setup triggers in areas you want your player to assume a different rotation.
This might prove more effective if, for some instance, you jump on a slanted platform then jump off, and when you jump off you're stuck at the rotation angle (probably an undesirable effect). Instead if you use a Trigger scene object, you can call upon trigger::onEnter, trigger::onLeave and adjust you're players rotation. So, on enter, rotate to set angle, on leave return to normal.
Just depends on how you "want" it to work.
#19
11/22/2012 (7:54 am)
I tried using $Gam::player.Rotation = "45"; in the console. It doesn't give an error, it just doesn't do anything... That may be the problem.
#20
11/22/2012 (8:36 am)
Why aren't you using the setter function for rotation?

$Game::player.setRotation(45)

Though I think that your code would work if you didn't put 45 in quotes.
Page «Previous 1 2