Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

move in unison

Discussion in 'Scripting' started by zumwalt, May 8, 2007.

  1. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Logic : (code is at home)
    I have an arraylist of invader types.
    I have 5 rows of 10 invaders.
    I have a global variable to set whether they are moving left or right as a group.
    I have another global variable to set the group movement speed.
    Finally I have a final global variable that determines the step motion for when they drop a line at a time.

    So what is my problem? On each move, some rows get slightly 'skewed', meaning for the first few trips they are in synch, but as time goes on they get slightly out of sync, and not the way one would expect.

    I would expect that an entire row would get out of synch, not individual invaders in individual rows. My loop before the movement has a local variable that is the Time.getdeltatime, this then is multiplied by my speed, that result then is used by all invaders in the loop and isn't set again until the move method is called.

    Theoretically, this should keep all invaders moving at the same speed, same distance each time within there own row. If any single invader hits the board edge, all invaders are flipped to move to the new direction. After 3 itterations of hitting the right edge of the board, all invaders move 1 full row down.

    The problem seems to be with the shifting from left to right then right to left. Does my logic sound correct or will I need to post the movement code tonight for input?
     
  2. Omar Rojo

    Omar Rojo

    Joined:
    Jan 4, 2007
    Posts:
    494
    Always post your code.

    Another simpler approach is to create an EGO that is the parent of every invader, so you move the EGO to move all of them removing the loop requirement.

    Omar Rojo
     
  3. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    But the empty game object as a parent and move it wouldn't be possible. I mean, if it moved the collection of all invaders, then the movement would not match the actual edge of the rows of invaders. For instance, if you blast the entire right row of invaders and remove it from the collection, an EGO would still move the collection as if that row still existed.
     
  4. aaronsullivan

    aaronsullivan

    Joined:
    Nov 10, 2005
    Posts:
    986
    Not if you used the rightmost invader to check like you do already. :) Just MOVE using the parent GO, do your checking like you do now. (You can access parents and children from any transform)

    Also... I think the original Space Invaders did advance as if the dead invaders were still there. If not, they'd catch up with each other. Not that it matters. :)
     
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Yep, there's always more than one way to skin a cat. ;) When instantiating lots of invaders, making them be children of a parent is also useful for not spamming your hierarchy with dozens of entries when you run the game. I actually ended up not dealing with individual invaders at all for movement (I did a raycast for boundary checking). It's still useful to know how to do things the "hard way" though, since sometimes you can't take shortcuts like that.

    --Eric
     
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    ...Speaking of cats and multiple skinning techniques, it just occured to me that the raycast method could potentially fail if the invaders are moving sufficiently fast coupled with a sufficiently bad framerate. (Not, at 240fps, that this is gonna happen on my machine. ;) ) Now, instead of doing that, I have a couple of trigger boxes used for boundaries, and the entire horizontal movement logic is down to 4 lines. (Plus a one-liner on the trigger boxes.) Of course, that only works if the invaders have rigidbodies, but mine do already because I needed rigidbodies for other things.

    --Eric
     
  7. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    How did you determine in 3d space where to put the collision boxes? My max bounding area is 120x120 even though my ortho is set to 100. Basically when I get to >120 I flip direction via a global variable that all invaders act on.

    Even if I put a trigger box and didn't check location at all, that would reduce some code, but I imagine I would run into the same problem where one row will be off synch from another row, but this is some intesting idea, my invaders are in fact 3d not flat although they look flat they have depth.

    hmmm...
     
  8. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Just visually (you can switch the scene view to orthogonal, if you didn't already know). That's the other cool thing about doing it this way...you can just move the boxes around in the scene view to get wider/narrower boundaries without touching any code or variables. And then you turn off the renderers of the boxes, of course...you can delete the rendering pipeline altogether since only the colliders matter, but it's useful to have around just in case.

    Shouldn't be an issue...this is the script on my boundary boxes:

    Code (csharp):
    1.  
    2. var dir : int;
    3.  
    4. function OnTriggerEnter () {
    5.     if (InvaderControl.iDirection == dir) {InvaderControl.iDirection = -dir;}
    6. }
    7.  
    iDirection is a static variable that's 1 or -1 for right or left, so I make "dir" -1 on the left boundary box, and 1 on the right box. So you can just move your invaders without checking for boundaries, and they'll stay in sync. There are probably multiple OnTriggerEnter events if there's more than one invader existing in that column when it hits, but only the first one will do anything because of the "if ()" check.

    --Eric
     

    Attached Files:

  9. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Cool, heading home now, going to try this out tonight! New ways to do things is always good, and this seems simple enough.
     
  10. aaronsullivan

    aaronsullivan

    Joined:
    Nov 10, 2005
    Posts:
    986
    I guess I like numbers. :)

    I'm working on a 2.5D game and since there is a sort of 2D tetris-like element to it, I set the whole thing up to work in whole number increments (each "square" on the grid is actually a distance of 1 apart.) For the boundaries I use numbers and have a script with a visible gizmo on an empty gameobject that draws lines for the boundary. That way I can manipulate boundaries with numbers in scripts and also get the visual cues.

    Nothing wrong with other methods, of course. Just sharing.
     
  11. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Very true, well now I am stuck, I have created 2 boxes with box colliders and turned them into triggers, they have there ontriggerenter setup as follows:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. public class RightWall : MonoBehaviour {
    5.     public int iDirection=1;
    6.     void Start () {
    7.     }
    8.     void Update () {   
    9.     }  
    10.     void OnTriggerEnter()
    11.     {
    12.         Debug.Log("Invader hit right wall");       
    13.     }
    14. }
    15.  
    And of course one for LeftWall, so then I setup a new line in a script file for the invaders as follows:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. public class InvaderControl : MonoBehaviour {
    5.     public int iDirection=1;
    6.     void Start () {
    7.         gameObject.AddComponent ("MeshCollider");  
    8.     }
    9.     void Update () {
    10.     }
    11. }
    12.  
    Then attached that to the invaders. Now of course the invaders are still created in code with instansiate. So I figured since this was attached to the prefab and the prefab is what is used to create the invaders, all invaders would automatically get a MeshCollider assigned to them when they start.

    Problem is, when they do collide with the box bar, they do not put anything out to the debug log.

    This image shows in 3d that they do connect.
     

    Attached Files:

  12. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    A few things: 1) Having a collider isn't enough to cause an OnTrigger event...you need also need a rigidbody for that. 2) It's generally not a good idea to use a mesh collider for moving objects. 3) You can attach colliders, rigidbodies, etc. to prefabs, so they will be instantiated with these already in place...no need to attach them by code.

    It occurs to me that I might have led you astray a little...I found the trigger box technique to be simpler and it takes very little code to run, but there might be some value in doing it the "traditional" way first, so you don't get too much Unity overload all at once. :) The point about mesh colliders still stands, however...you should use a box collider instead. Mesh colliders are mostly intended for complex, stationary background objects.

    --Eric
     
  13. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    :) its cool, I got that figured out accidently, and notice that all 5 rows are triggering a hit on the walls, here was my code after the walls were setup with ontriggerenter, and I only attach to prefabs not to the object directly.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. public class InvaderControl : MonoBehaviour {
    5.     public int iDirection=1;
    6.     void Start () {
    7.         gameObject.AddComponent ("MeshCollider");
    8.         gameObject.AddComponent ("Rigidbody");
    9.         rigidbody.useGravity=false;
    10.     }
    11.     void Update () {
    12.     }
    13. }
    14.  
    Notice something else, I had to turn off gravity for the body, or I get a really cool invader group falling from the sky as it is effected by gravity.

    edit:
    hey wait a sec, I could actually use the gravity to my advantage.. this ones going to be interesting to figure out a nice bell curve for movement so I don't have to use my 'step' anymore... hmm.. got to think this one over... a new gravity variable that effects the group so the more they are alive the faster they start to fall towards the player... hmm

    errr.. edit edit... i have it in code at the moment for testing but will switch it to the actual prefabs..


    I thought about box colliders, will have to attach those instead of meshcollider to the prefab and see what results i get... thanks again for all the suggestions.

    Yet another edit :)
    Man, colliders, rigid bodies, and figuring out how to put public variables on objects, seriously making my life 10000x easier... I just updated on a 'hunch' my ontriggerenter, thinking I can overload them, and I was right...

    Code (csharp):
    1.  
    2.     void OnTriggerEnter(Collider obj)
    3.     {
    4.         Debug.Log(obj.name + " hit right wall");       
    5.     }
    6.  
    so at this point, I can safely assume that I can overload all internal methods in this thing.. trippin.. dumb question, will have to look it up to see, but I assume all created entities have a unique ID associated with them.. if so... joy joy on the way
     
  14. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Ok, I have gotten rid of individual wall scripts and made 1 wall script with conditions along with ignoring the player collision for changing the direction the invaders move, going to update it tomorrow to clamp the player from moving past it, that is once I figure out if clamp will work against what I am trying to do, if not, I'll just reset the players left to the wall and right to the wall if the player collides etc. Here is as far as I got tonight with this and its all runnin thanks to the suggestions. Still alot more work to get rid of 3/4 of my current code which will be a good thing.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. public class Walls : MonoBehaviour {
    5.     public int iDirection=1;
    6.     void Start () {
    7.     }
    8.     void Update () {   
    9.     }  
    10.     void OnTriggerEnter(Collider obj)
    11.     {
    12.         switch(this.name)
    13.         {
    14.             case "RightWall":
    15.                 if(obj.tag != "tagPlayer")
    16.                 {
    17.                     Debug.Log(obj.name + " hit " + this.name + " wall " + " with a tag of " + obj.tag);
    18.                     iDirection=-1;
    19.                 }
    20.                 break;
    21.             case "LeftWall":
    22.                 if(obj.tag != "tagPlayer")
    23.                 {
    24.                     Debug.Log(obj.name + " hit " + this.name + " wall" + " with a tag of " + obj.tag);
    25.                     iDirection=1;
    26.                 }
    27.                 break;
    28.             default:
    29.                 break; 
    30.         }
    31.     }
    32. }
    33.  
     
  15. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Heh. :) Also you normally want the "is Kinematic" box to be checked if you're moving rigidbodies around by code. Otherwise the physics engine can do some wacky things.

    Box colliders are faster, mesh colliders can't collide with other mesh colliders, and mesh colliders can do some seriously wrong stuff if your mesh is not 100% closed and you try to have the physics engine act on it (like moving with gravity etc.). I know this from experience. ;)

    Yep, and for future reference, if you do OnCollision stuff as opposed to OnTrigger stuff, you have to use the Collision class rather than Collider. Which means you would have to do "Debug.Log(obj.collider.name);" And you can get other useful info out of a Collision...check the docs....

    GetInstanceID(). But you might want to check this topic.

    --Eric
     
  16. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Well, unfortunately the answer in that thread has no resolve (or isn't appropriate) for what I do. All of my entities have the same names for each group of objects because they are all clones created from prefabs. I don't see why an instance ID wouldn't be unique on every object in the scene. I don't care if it changes on every load, and personally I don't care if it changes when I refresh the list, what I do care about is that there is some unique way to identify each object while it is 'alive' and during its life cycle.

    What I took by reading that thread was that it might be possible that 2 items have the same instanceID, which to me within the scene, is well, useless. How can you get constant anything if there is no guarantee each created object doesn't have a unique way to identify it when it is a clone of another object?

    That makes absolutly no sense to me.
     
  17. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Sorry...to quote the docs, "The instance id of an object is always guaranteed to be unique." If you don't care that it changes every load, then it's fine. The possibility of 2 items having the same id was just related to using the naming technique (i.e., whatever.name = "something" + idnum.ToString() ) because that depends on your code.

    --Eric
     
  18. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    That thread had me confused compared to the docs based on this post:

    I took that the project lead was stating that there could be confusion between objects if you use there ID's, and the last paragraph confused me because I couldn't translate its meaning.
     
  19. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Yeah, by "the same" he just meant "repeatable." Which you don't care about...sorry to cause confusion.... :oops:

    --Eric
     
  20. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Thanks :) this will help me with the project, been toiling with how to deal with the player lives, since they are all clones and I don't want to do a get all by type more than 1 time, then once I have them I can get all there unique ID's, so when one is destroyed, I can just hope to the next ship by its id in the stack.
     
  21. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Aha...yeah, I was doing something similar, but my logic wasn't working, and instead of thinking about how to fix it (the instanceID sounds good!), I ended up putting them all on the screen and turning the renderers off/on as appropriate. i.e.,

    Code (csharp):
    1.  
    2. if (extraLives-- > 0) {
    3.     lifeArray[extraLives].renderer.enabled = false;
    4. }
    5.  
    and

    Code (csharp):
    1.  
    2. if (score >= 1500  !gotBonusLife) {
    3.     lifeArray[extraLives++].renderer.enabled = true;
    4.     gotBonusLife = true;
    5. }
    6.  
    Will remember the GetInstanceID() idea for stuff like this, when just turning renderers off and on wouldn't work...I knew about it but haven't yet used it for anything....

    --Eric
     
  22. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Yup, you already have the object plus this allows you to literally create a new ship object in the life section and have more than the base 3. When you add a new life you just work with the stack by ID's, now you can actually destroy them if you feel like it and add another by clone. Depends on how indepth the game is really. show/hide will probably work for this thing, but what if you end up with an extra life and now have 4 then 5 etc. My theory is, I just instansiate a new objec based on the prefab, add it to the stack and position it next to the last ship in the queue.

    Anyway, this gets me out of my rut tonight and I can get further with the rewrite.
     
  23. aaronsullivan

    aaronsullivan

    Joined:
    Nov 10, 2005
    Posts:
    986
    Hmm... why not just keep your gameObjects in an array, or better yet, something more dynamic like ArrayList?
     
  24. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    All of the invaders are in an Arraylist, so are the player ships and the bunkers. I loop through the list when I move the invaders, but I need to keep track of the bunkers and players from an extra point of view that is unique. I can't remove and object at point within the list unless I can identify which one was destroyed.

    The player ship is what is giving me the headache at the moment, most likely because I was very tired when I setup its variables. So to ease my pain, I was looking for a unique way outside of the list to identify which one it was. Was thinking about creating a hashtable and use objects by ID and maybe store them all into a single collection and find them by the key since the key=uniqueID of the object.
     
  25. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Again, I took the cheap way out and just turned off the renderer for the player when necessary. ;) (Plus a static variable called playerCanMove that the player script checks against.) I think in this case that might actually be the best way, since there's only ever going to be one player. Then again, it's about how dynamic you want to be...like if you were doing a Galaga clone instead. I wrote the game pretty fast and just went for "space invaders clone" specifically, rather than "generic arcade shooter scripts that can be used to make a space invaders clone", which in hindsight might have been better....

    --Eric
     
  26. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Well, the idea behind my end result, after about 10 pots of cofee, is to have a core set of rules created so that I could make clones of many of the old retro games. They all pretty much follow the same rules and concepts, just different logic for the invaders and for the player. I got a few other ideas to, since I already have myself a portable webservice DLL that all I have to do is just drop it into my project and call my method with some values, so I can have an online scoring system for competitions.
     
  27. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Ha, check out the edit to my post I just made as you were posting that. ;)

    --Eric
     
  28. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Yup, but you can always enhance and go dynamic :) A few alterations and you can also have a breakout clone.
     
  29. aaronsullivan

    aaronsullivan

    Joined:
    Nov 10, 2005
    Posts:
    986
    Instead of messing with instanceID's, how about calling something like this from the enemy when it gets hit:
    Code (csharp):
    1. EnemyManager.DestroyEnemy(gameObject);
    That calls the function sending it a reference to itself. (I actually use EnemyManager.instance.DestroyEnemy(gameObject); as described here.)

    The DestroyEnemy() function in your EnemyManager script could be like this:
    Code (csharp):
    1. public void DestroyEnemy( GameObject enemy )
    2. {
    3.     enemyArrayList.Remove(enemy);
    4.     Destroy(enemy);
    5. }
    In other words, let the ArrayList do the work for you. :)
     
  30. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Looks cool and simple, I'll check this out tonight!
     
  31. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Haven't found it but still looking, don't know a good keyword to use, I want to get the value of a variable on another GameObject that exists in the scene. Lets say I have a public variable in a script that is attached to a cube named ScriptManager, the script that is attached to the cube is called SetupObjects, so now in my script that is on my player object, I want to see that variable, I have tried:

    ScriptManager.variablename

    Doesn't work, I have seen references where I can call script by its name for the full script and switch scripts, but its not what I want to do.

    Edit, I did try SetupObjects.variablename also, what is even more troubling is that not all of my public items are being seen as public in the inspector, I have had this happen to me on numerous occasions and typically deleting the CS file and recreating it fixes it, but not this time.
     

    Attached Files:

  32. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Ok, update, someone please tell me that this is just not necessary to be able to pass variables around??? please...

    Sender object code:
    Code (csharp):
    1.  
    2.     void placeLife()
    3.     {
    4.         activePlayer=GameObject.Find("pGun(Clone)");
    5.         pPos=activePlayer.transform.position;
    6.         pPos[0]=-100;
    7.         pPos[1]=-85;
    8.         activePlayer.transform.position=pPos;
    9.         activePlayer.SendMessage("ApplyActive",1);
    10.         activePlayer.SendMessage("ApplyLeft",fieldLeft);
    11.         activePlayer.SendMessage("ApplyRight",fieldRight);
    12.         activePlayer.SendMessage("ApplyLives",Lives);
    13.     }
    14.  
    Receiver Object Code:
    Code (csharp):
    1.  
    2.     public void ApplyLives(int Lives)
    3.     {
    4.         this.Lives=Lives;
    5.     }
    6.    
    7.     public void ApplyActive(int isActive)
    8.     {
    9.         this.isActive=isActive;
    10.     }
    11.    
    12.     public void ApplyLeft(float fieldLeft)
    13.     {
    14.         this.fieldLeft=fieldLeft;  
    15.     }
    16.    
    17.     public void ApplyRight(float fieldRight)
    18.     {
    19.         this.fieldRight=fieldRight;
    20.     }
    21.  

    This is way overkill for wanting to call Object.Class.publicVariable and set its value.. There has to be a one liner way to make it happen...
     
  33. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Two things you can do...

    Code (csharp):
    1.  
    2. var otherScript : ScriptName = FindObjectOfType(ScriptName);
    3. otherScript.someVariable = 10; // or whatever
    4.  
    Where ScriptName is the actual name of the script you want to access. In that case, someVariable has to be public, of course. Or you can use static variables, where you just do

    Code (csharp):
    1.  
    2. otherScript.someVariable = 10; // or whatever
    3.  
    In that case, someVariable has to be static. Note that static variables can't be edited in the inspector, and they keep their values even after you stop play (so you have to initialize them yourself; usually Start() or Awake() is a good place for doing that).

    --Eric
     
  34. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    What "type" is othersctipt?
    I have to explicitly use its type in C#.

    Edit:
    And how am I guaranteed it is going to call the right object since typically find always returns the one on the top of the stack...
     
  35. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The name of the script is the type. If I do "var otherScript : ScriptName = FindObjectOfType(ScriptName);", that means otherScript is explicitly defined as type "ScriptName". Like "var x : int = 5;" explicitly defines x as an int.

    You can also do stuff like:

    Code (csharp):
    1.  
    2. var objectClone : ScriptName = Instantiate (object);
    3. objectClone.someVariable = whatever;
    4.  
    Or another way:

    Code (csharp):
    1.  
    2. var objectClone : GameObject = Instantiate (object);
    3. var objectScript : ScriptName = objectClone.GetComponent(ScriptName);
    4. objectScript.someVariable = whatever;
    5.  
    There might be some C# "gotchas" in there...not sure....

    --Eric
     
  36. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Can't seem to get any of those methods to work, I'll have to stick with sendmessage for now. Ran into another issue though.. just when I thought I had it licked.

    Take a look at the pic, I know that the bullet is clearly hitting the invaders and the top wall, but nothing is being written to debug, does anything stick out?
     

    Attached Files:

  37. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Yep, it's a kinematic rigidbody, which doesn't generate OnCollision events. Turn off kinematic, and instead of manually updating the position every frame, give it a velocity of (0, 30, 0) when you instantiate it. (The whole "which collides with which trigger/rigidbody/etc." thing can be a little confusing at first...but there's a use for all of it....)

    --Eric
     
  38. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    The only object it is reporting collision with now is the gun that fired it.
    Edit:
    BAH wouldn't you know it, upon being shot, it is reflected away from the gun, thus changing its angle. *sigh* Should I change it to a trigger? All I want to do is detect if it collided but then let it pass through what it collided with, without appling force to the collision.

    edit again.. nevermind, i'll just work on my destruction sequence instead, it won't matter on this game, i'll work on the rounded code later for pass through destruction, that will be for my breakout clone.
     
  39. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You'd either want to instantiate it farther away so it doesn't collide, or use Physics.IgnoreCollision().

    Yeah, if you don't want it to apply force, then you don't want it to be a non-kinematic rigidbody. A trigger would be fine for that.

    --Eric
     
  40. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Well, for now, all I have left to do is work on trigging the move of the invaders based on the wall triggers, haven't switched it yet, but atleast I have bullets to destroy the invaders with and they work very well.. ok that and to look over that scoring stuff again :)
     

    Attached Files:

  41. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    New or old twisted theory on parenting.
    I have read the docs on how parenting works and it states I have to use the hierarchy in the editor to create the parenting structure, but here is my problem and maybe its a simple answer.

    If I createa new empty game object and call it "parentInvader", then use the hierarchy and drag all the prefabs into it as a child, will anything created with that prefab automatically be a child of the 'parentInvader' object?

    If so, then great, if not is it possible to create an object in code and child objects to that object via code? The thought is, that if I child all the alien invaders to a dummy object, no matter where that object lives in world space, it can be moved around and the children will move appropriately left and right as a group.

    So, I detect child collision to the walls and adjust the parents movement variable, so I only move the parent and the children follow. I know this has been brought up before as to why I am not using a single object to move the collection, but my original thoughts couldn't grasp the child collisions vs the parent collision, since I never want to have the parent collide with anything, but only the children so that the children determine the movement variable of the parent.

    If any of that made sense, then I haven't had enough coffee yet.
     
  42. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Nope. But...

    Yep.

    Code (csharp):
    1.  
    2. invaderClone[thisone].transform.parent = invaderDummy.transform;
    3.  
    Exactamundo....

    Drink up! :)

    --Eric
     
  43. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Heh, ok so if I understand correctly:

    Code (csharp):
    1.  
    2. invaderClone[thisone].transform.parent = invaderDummy.transform;
    3.  
    Is done in the code that generates the clone, and I can take my game object that the code script is on and use it for movement. In other words, I make an invaderDummy empty game object, and connect them all to that, and move it around instead, which means it doesn't matter where it lives in world space, just as long as it moves along the correct axis's.
     
  44. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Precisely. Not much to add to that (well, except that the plural is "axes". ;) )

    --Eric
     
  45. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    Cool, many thanks's again :)
    I'll be working on this at the house in about 2 hours, will post more later on the results with some code blocks to show what is going on.
     
  46. zumwalt

    zumwalt

    Joined:
    Apr 18, 2007
    Posts:
    2,287
    I now have everything parented, still working out the logic for the movement and the positioning, but this is my new movement code (incomplete, but works)
    Code (csharp):
    1.  
    2.     void moveControler()
    3.     {
    4.         pos=this.transform.position;
    5.         pos[0]=pos[0] + (moveSpeed * Time.deltaTime)* iDirection;
    6.         this.transform.position=pos;
    7.     }
    8.  
    Works smooth and no one is out of sync.
    My missiles hit the invaders like they should and I added some code to remove them from the array list that they live in:

    Code (csharp):
    1.  
    2.     public void RemoveInvader(GameObject detract)
    3.     {  
    4.         int i=0;
    5.         foreach (GameObject obj in tmpObjs)
    6.         {
    7.             if(obj.GetInstanceID()==detract.GetInstanceID())
    8.                 break;
    9.             i++;
    10.         }
    11.        
    12.         try
    13.         {
    14.             tmpObjs.RemoveAt(i);
    15.         }
    16.         catch
    17.         {
    18.             // Note, it is possible to have more than one bullet collide
    19.             // before the frame has ended, which throws a null item to the
    20.             // mix.. so just ignore the message
    21.             }  
    22.         Debug.Log(tmpObjs.Count);
    23.         Debug.Log(i + " item was removed");
    24.     }
    25.  
    I have a sendmessage on my invadercontrol script to send into my objectcontrol script to tell it to remove the invader from the list..
    Code (csharp):
    1.  
    2. void OnCollisionEnter(Collision obj)
    3.     {
    4.         //Debug.Log("I'm HIT");
    5.         Destroy(gameObject);
    6.         invaders=GameObject.Find("ScriptManager");
    7.         invaders.SendMessage("RemoveInvader",gameObject);
    8.         //Debug.Log(obj.collider.name);
    9.     }
    10.  
    Now, with all this in play, all I had to do was make sure I had something to kill otherwise, reset them all, and it was as simple as having the following in my Update() for my setupobjects code:

    Code (csharp):
    1.  
    2. if(tmpObjs.Count > 0)
    3.     moveControler();
    4. else
    5.     setupAllInvaders();
    6.  
    At which point the entire collection is recreated and attached to the parent cube which the setupobjects code lives with.

    I think overall, my original approach worked but each invader object was independent, so hard to control, now that they are parented and I am only dealing with the parent for movement, and the children for everything else, the game is much smoother.

    At this point, all that is left is to re-enable my tick counter for verticle movement, add in the scoring, add some random bomb dropping from the invaders, throttle the players bullet rate, and put in some sort of level algorithm or something, then I am done. First level though minus all the items mentioned here is practically done.

    Thanks everyone for all there instructions through this, I am in the home stretch!