playMaker

Author Topic: Instantiate along a path....  (Read 6934 times)

brendang

  • Junior Playmaker
  • **
  • Posts: 63
    • View Profile
    • Out to Play Interactive
Instantiate along a path....
« on: March 04, 2013, 08:03:56 AM »
I'd like to set up a curved path and set randomly timed gameObjects to instantiate (create Object) on it.

Basically I'd like to create waves of enemies (very likely with a pooling plugin but that's another issue), that travel down the path at random time.  My thought was to instantiate empty GOs on the path, then use them as spawn points. But I'm not quite sure how to instantiate to a path.

Any thoughts would be really appreciated.

B.

Vallar

  • Junior Playmaker
  • **
  • Posts: 90
    • View Profile
Re: Instantiate along a path....
« Reply #1 on: March 04, 2013, 08:53:09 AM »
I am not sure if this helps:

You can create the object and use the "iTween Move Add" action where you can add in a position over time for the object that you created in which case you can change the location of the object based on its current location and create the path this way.
There is another way, you can place multiple empty game objects to markup "checkpoints" along that path. After doing that, you can create the object at the beginning of the path then use the "Move To" action to move towards the first empty game object (checkpoint) and when it arrives move it along to the next one and so on...

Hope that helped.

kiriri

  • Hero Member
  • *****
  • Posts: 506
    • View Profile
Re: Instantiate along a path....
« Reply #2 on: March 04, 2013, 09:24:08 AM »
[EDIT: Reading your post again, it looks like you already have a path setup. Can you tell us what kind of path that is? Are you using a plugin?]

I'd go in the same direction as Vallar. I can be a bit more specific since I've done this already a couple of times before.

First of all you need to decide what kind of path you want to use. Here's a few to choose from:

1) create an "master" empty and then create another ''waypoint'' empty for each waypoint in the path. Make all the waypoints children of master. Then name each waypoint by their respective position in the hierarchy ("1" for the first waypoint "2" for the second etc.). Unity sorts numbers specially, so unlike in most other programs 10 is actually right after 9 and not after or before 1.

2) Use Jean Fabre's awesome ArrayMaker plugin to either save the path as a list of empties or as a list of vector3s.

3) Create a new set of actions (if you want your waypoints to contain more than just position data)[and yes, this is certainly more tricky, but depending on what you want to do with your path, this may potentially be worth thinking about]

For now I'll just continue with v1, they are all essentially the same though :)

So to get a random waypoint, you can use:
get Child Count = Count ;
int add (Count - 1; [you need to use the index from now on, and the max index is the count - 1 because indices start with 0]
random int (0 to Count, save as Index);
GetChildNum (Count); [this now gets a random waypoint.]

Then you can use get position for the position. To move along the path, you get the position of waypoint 0 and move towards it . Then you can wait until the tween action or whatever says you've arrived, or you can compare the distance between your actor and the waypoint each frame. Then once that distance is low enough (like 0.5 or so) you can add one to the current index and get the next waypoint in the list/hierarchy. By moving on to the next waypoint before actually arriving at the waypoint you can somewhat smooth out the path the actor takes. But that's just asthetics I guess.

Hope that helped.
« Last Edit: March 04, 2013, 09:26:19 AM by kiriri »
Best,
Sven

brendang

  • Junior Playmaker
  • **
  • Posts: 63
    • View Profile
    • Out to Play Interactive
Re: Instantiate along a path....
« Reply #3 on: March 04, 2013, 09:52:13 AM »
Thanks guys,  I'll distill your great info and see what I can get going.



thanks guys,
Brendan
« Last Edit: March 04, 2013, 04:40:40 PM by brendang »

kiriri

  • Hero Member
  • *****
  • Posts: 506
    • View Profile
Re: Instantiate along a path....
« Reply #4 on: March 04, 2013, 10:10:33 AM »
Hey Brandon,
Interesting game, but you got me a bit confused there. If your monsters come from within the doors, why would you want them to be instantiated along the path?
(while I wait for a response from you I'll just quickly google iTweenPaths, never used them, but I'm sure we'll find a solution ;) )
Best,
Sven

brendang

  • Junior Playmaker
  • **
  • Posts: 63
    • View Profile
    • Out to Play Interactive
Re: Instantiate along a path....
« Reply #5 on: March 04, 2013, 10:27:39 AM »
Well... my thought was that I could just use some simple AI type set up where they move toward or Lerp the Vector3 of the player (sort of a stationary shooter), but I wanted to have a little control to the path that they take.  So if I wanted to make let's say, two different paths per door. one that 'walked' and one that 'flew' toward you.  I'd instantiate flying monster targets along the flying path, and walking monster targets on the walking path.   They'll sort of look like Carnival Targets in a blacklight shooting gallery.

Less about logic more about visual esthetic.  If you have an alternate idea, I'd love to hear it.  I'm a design guy, not much of a coder, so I'm sort of thinking like I would if I were animating this whole thing in Maya.

I appreciate your time and interest...alot.

B.

kiriri

  • Hero Member
  • *****
  • Posts: 506
    • View Profile
Re: Instantiate along a path....
« Reply #6 on: March 04, 2013, 10:57:09 AM »
Us maya users have to stand firm against the evil 3dsmax community ;) I'd help you anytime :P

My intense googling (first result really ^^) brought me to this site : http://pixelplacement.com/2010/12/03/visual-editor-for-itween-motion-paths/

Looking at it, the function he uses seems to take care of it automatically. The gameObject can be instantiated anywhere you like, and once it starts moving it will be set to the position of the start of the path.
If you want to do such a thing, then I can create an action which handles it for you. Won't take long :)
Best,
Sven

kiriri

  • Hero Member
  • *****
  • Posts: 506
    • View Profile
Re: Instantiate along a path....
« Reply #7 on: March 04, 2013, 11:30:21 AM »
How about this action (mostly done by Jean or Alex, whoever made the default itween stuff)

Code: [Select]
// (c) Copyright HutongGames, LLC 2010-2013. All rights reserved.

using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory("iTween")]
[Tooltip("Changes a GameObject's position over time to a supplied destination.")]
public class iTweenMoveOnPath : iTweenFsmAction
{
[RequiredField]
public FsmOwnerDefault gameObject;

[Tooltip("iTween ID. If set you can use iTween Stop action to stop it by its id.")]
public FsmString id;

[Tooltip("Move along this path")]
public FsmString path;

[Tooltip("The time in seconds the animation will take to complete.")]
public FsmFloat time;
[Tooltip("The time in seconds the animation will wait before beginning.")]
public FsmFloat delay;
[Tooltip("Can be used instead of time to allow animation based on speed. When you define speed the time variable is ignored.")]
public FsmFloat speed;

[Tooltip("Whether to animate in local or world space.")]
public Space space = Space.World;

[Tooltip("The shape of the easing curve applied to the animation.")]
public iTween.EaseType easeType = iTween.EaseType.linear;
[Tooltip("The type of loop to apply once the animation has completed.")]
public iTween.LoopType loopType = iTween.LoopType.none;

[ActionSection("LookAt")]
[Tooltip("Whether or not the GameObject will orient to its direction of travel. False by default.")]
public FsmBool orientToPath;
[Tooltip("A target object the GameObject will look at.")]
public FsmGameObject lookAtObject;
[Tooltip("A target position the GameObject will look at.")]
public FsmVector3 lookAtVector;
[Tooltip("The time in seconds the object will take to look at either the Look Target or Orient To Path. 0 by default")]
public FsmFloat lookTime;
[Tooltip("Restricts rotation to the supplied axis only.")]
public iTweenFsmAction.AxisRestriction axis = iTweenFsmAction.AxisRestriction.none;
[ActionSection("Path")]
[Tooltip("Whether to automatically generate a curve from the GameObject's current position to the beginning of the path. True by default.")]
public FsmBool moveToPath;
[Tooltip("How much of a percentage (from 0 to 1) to look ahead on a path to influence how strict Orient To Path is and how much the object will anticipate each curve.")]
public FsmFloat lookAhead;
[CompoundArray("Path Nodes", "Transform", "Vector")]
[Tooltip("A list of objects to draw a Catmull-Rom spline through for a curved animation path.")]
public FsmGameObject[] transforms;
[Tooltip("A list of positions to draw a Catmull-Rom through for a curved animation path. If Transform is defined, this value is added as a local offset.")]
public FsmVector3[] vectors;
[Tooltip("Reverse the path so object moves from End to Start node.")]
public FsmBool reverse;

private Vector3[] tempVct3;
public override void OnDrawGizmos(){
if(transforms.Length >= 2) {
tempVct3 = new Vector3[transforms.Length];
for(int i = 0;i<transforms.Length;i++){
if(transforms[i].IsNone) tempVct3[i] = vectors[i].IsNone ? Vector3.zero : vectors[i].Value;
else {
if(transforms[i].Value == null) tempVct3[i] = vectors[i].IsNone ? Vector3.zero : vectors[i].Value;
else tempVct3[i] = transforms[i].Value.transform.position + (vectors[i].IsNone ? Vector3.zero : vectors[i].Value);
}
}
iTween.DrawPathGizmos(tempVct3, Color.yellow);
}
}

public override void Reset()
{
base.Reset();
path = new FsmString();
id = new FsmString { UseVariable = true };
time = 1f;
delay = 0f; //new FsmFloat { UseVariable = true };
loopType = iTween.LoopType.none;
speed = new FsmFloat { UseVariable = true };
space = Space.World;
orientToPath = new FsmBool { Value = true };
lookAtObject = new FsmGameObject { UseVariable = true};
lookAtVector = new FsmVector3 { UseVariable = true };
lookTime = new FsmFloat { UseVariable = true };
moveToPath = true; // new FsmBool { UseVariable = true };
lookAhead = new FsmFloat { UseVariable = true };
transforms = new FsmGameObject[0];
vectors = new FsmVector3[0];
tempVct3 = new Vector3[0];
axis = iTweenFsmAction.AxisRestriction.none;
reverse = false; //new FsmBool { UseVariable = true };

}

public override void OnEnter()
{
base.OnEnteriTween(gameObject);
if(loopType != iTween.LoopType.none) base.IsLoop(true);
DoiTween();
}

public override void OnExit(){
base.OnExitiTween(gameObject);
}

void DoiTween()
{
GameObject go = Fsm.GetOwnerDefaultTarget(gameObject);


System.Collections.Hashtable hash = new System.Collections.Hashtable();
hash.Add(speed.IsNone ? "time" : "speed", speed.IsNone ? time.IsNone ? 1f : time.Value : speed.Value);
hash.Add("delay", delay.IsNone ? 0f : delay.Value);
hash.Add("easetype", easeType);
hash.Add("looptype", loopType);
hash.Add("oncomplete", "iTweenOnComplete");
hash.Add("oncompleteparams", itweenID);
hash.Add("onstart", "iTweenOnStart");
hash.Add("onstartparams", itweenID);
hash.Add("ignoretimescale", realTime.IsNone ? false : realTime.Value);
hash.Add("name", id.IsNone ? "" : id.Value);
hash.Add("islocal", space == Space.Self );
hash.Add("axis", axis == iTweenFsmAction.AxisRestriction.none ? "" : System.Enum.GetName(typeof(iTweenFsmAction.AxisRestriction), axis));
if(!orientToPath.IsNone) {
hash.Add("orienttopath", orientToPath.Value);

}
if(!lookAtObject.IsNone) {
hash.Add("looktarget", lookAtVector.IsNone ? lookAtObject.Value.transform.position : lookAtObject.Value.transform.position + lookAtVector.Value);
} else {
if(!lookAtVector.IsNone) {
hash.Add("looktarget", lookAtVector.Value);
}
}
if(!lookAtObject.IsNone || !lookAtVector.IsNone){
hash.Add("looktime", lookTime.IsNone ? 0f : lookTime.Value);
}

hash.Add("path", iTweenPath.GetPath(path.Value));
hash.Add("movetopath", moveToPath.IsNone ? true : moveToPath.Value);
hash.Add("lookahead", lookAhead.IsNone ? 1f : lookAhead.Value);


itweenType = "move";
iTween.MoveTo(go, hash);
}
}
}
Best,
Sven

brendang

  • Junior Playmaker
  • **
  • Posts: 63
    • View Profile
    • Out to Play Interactive
Re: Instantiate along a path....
« Reply #8 on: March 04, 2013, 11:50:31 AM »
Wow.... Thanks so much!  So this script will basically do that? How damn cool is that?

So to recap, I should instantiate (Create Object in Playmaker vernacular),  targets but have this script on the when created as prefabs first?  then they will travel along the given path.    I guess I should set up a quick scene to test this stuff out.

Really appreciate your help, Sven.  If you ever find yourself in NYC   We'll hit a Maya user's group and the beers and burgers are on me!

kiriri

  • Hero Member
  • *****
  • Posts: 506
    • View Profile
Re: Instantiate along a path....
« Reply #9 on: March 04, 2013, 12:57:23 PM »
I'll take you on your word ;)
The script is an (FSM) action script. Put it wherever you want (preferably in the PlayMaker/Actions/iTween/ folder) and use it in an FSM like any other action (it's called iTweenMoveOnPath I think) and it moves your stuff along the path.
Make sure to install the package from the previous link and use ITweenPath modifiers for your paths. Then set the path input in the action to the Path Name on the ITweenPath component.
« Last Edit: March 04, 2013, 01:02:38 PM by kiriri »
Best,
Sven