Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

3D Tower Defense Starter Kit

Discussion in 'Assets and Asset Store' started by Baroni, Mar 30, 2012.

  1. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Hi,

    thanks for pointing this one out! The Tower Manager prefab does not require any setup. It's a bug on my side, I'm sorry.

    Please copy+paste this block of code at the end of TowerEditor.cs to fix this issue.

    Code (csharp):
    1.         if (GUI.changed)
    2.         {
    3.             //we have to tell Unity that a value of the TowerManager script has changed
    4.             //http://unity3d.com/support/documentation/ScriptReference/EditorUtility.SetDirty.html
    5.             EditorUtility.SetDirty(script);
    6.             //Register the snapshot state made with CreateSnapshot so the user can later undo back to that state
    7.             Undo.RegisterSnapshot();
    8.             //repaint editor GUI window
    9.             Repaint();
    10.         }
    11.         else
    12.             //clear the snapshot at end of call
    13.             Undo.ClearSnapshotTarget();
    14.     }
    15. }//end class
    I'll release a hotfix (containing this code) as soon as possible.

    Thanks again
     
  2. Progeny

    Progeny

    Joined:
    Sep 17, 2012
    Posts:
    32
    Hi, I'm trying to change the game speed by using Time.timeScale, everything is ok, except projectiles. It seems that with timeScale > 1, projectiles are missing enemies.

    In Projectile.cs at line 119 I changed in this way multiplying with Time.timeScale

    transform.Translate(Vector3.forward * (speed * 10) * Time.deltaTime * Time.timeScale);

    Should it be sufficient? On the Unity's simulator it seems ok, but on the device not at all.
     
  3. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    I switched the build platform to Android and could reproduce this behavior, thanks for reporting.

    What device are you testing with? A slow / low end device?

    When the projectile flies through the air, it checks whether it reached its target. That code is directly beneath line 119. If the projectile gets out of its range, it gets despawned or explodes. Your device executes this check before the actual collision with an enemy. Try adding a buffer value, so the device has more time to check against collisions. Like this:

    Code (csharp):
    1. if (!executed  Vector3.Distance(transform.position, startPos) > (Vector3.Distance(startPos, endPos) + 2)))
    2. {  ...  }
    A similiar check exists in the Lob() method.
     
  4. Progeny

    Progeny

    Joined:
    Sep 17, 2012
    Posts:
    32
    iPad 3! I'll try to follow your suggestion, thanks!

    Thanks it's working now. I have another issue with devices with LOW frame rate like iPad 1...

    http://forum.unity3d.com/threads/158123-Camera-Script-check-for-world-s-bounds

    I've edited the camera script in order to use only touches instead of joystick. When I scroll to fast, the bound's checking isn't working properly...
    Now when we have lower frame rate, I think that Time.deltaTime becomes > 1 and this cause the problem because I calculate the new coords multiplying something with deltaTime which is usually < 1.

    I've put a check to see if deltaTime > 1 then multiply something with 0.8 instead of deltaTime. I have to see whether this fix works.

    What do you think about that?

    ps.: thanks for all your support, I've just give you a 5-star review on the asset store
     
    Last edited: Nov 17, 2012
  5. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Great, glad I could help.

    Oh wow, quite complicated camera script... I've lost the track at all those Time values. Since you're setting up a square playing field, wouldn't it be simpler to not use my bounds method and hardcode these values instead?

    E.g. when moving to the left, check for x-axis < -a. Do not move to the left if x-axis value exceeds -a.
    When moving to the right, check for x-axis > b. And so on.

    Every device has to calculate this per frame before moving. This should work fine?
    Thank you very much for your review!
     
  6. Progeny

    Progeny

    Joined:
    Sep 17, 2012
    Posts:
    32
    yeah i've tried, hardcoding this values didn't the trick. I dunno why, the problem happens when I use a older device like iPad 1 and there are many enemies, then scroll very very very fast nearby my world's bounds. It seems LastUpdate() is not being called soon, it's like there is a sorta of delay. In that situation when I scroll too fast, the screen "freezes" for some instant (time like 0.1 - 0.8 second) and when it come back responsive i'm yet out of the world.

    Removing timeDelta in my calculus I hope will fix, I've to try as I have an old device in my hands.
     
  7. Progeny

    Progeny

    Joined:
    Sep 17, 2012
    Posts:
    32
    It didn't work.

    I want to report another thing... when I launch in a wave about 10 horse_knight the frame rate begins to be incredibly slow... it seems 3 horse_knight is the limit for an acceptable framerate... this issue happens also when I have a wave with about 20 peasants and 15 raves simultaneously...

    I'm using Unity 3d 3.5.6, iOS deployment target 5.1, iPad 3th gen.

    Do you experience that with your android device too? Do you think there should be a possible fix for that?

    ps.: In the poolmanager I've increased the value for peasants to 20, horse_knight to 10, but this doesn't speed up the frame rate...
     
  8. Progeny

    Progeny

    Joined:
    Sep 17, 2012
    Posts:
    32
    I have to report another issue, this is a critical bug that prevents the game going ahead...

    On the Xcode console I got the following error, I have to point out that there are *several* enemies in this wave

    Wave 10 launched! StartUp GameTime: 428.84

    (Filename: /Applications/buildAgent/work/14194e8ce88cdf47/Runtime/ExportGenerated/iPhonePlayer-armv7/UnityEngineDebug.cpp Line: 43)

    ArgumentException: An element with the same key already exists in the dictionary.
    at System.Collections.Generic.Dictionary`2[System.Int32,ProgressMapObject].Add (Int32 key, .ProgressMapObject value) [0x00000] in <filename unknown>:0
    at ProgressMap.AddToMap (UnityEngine.GameObject mapObjectPrefab, Single totalDist, Int32 objID) [0x00000] in <filename unknown>:0
    at iMove+<OnSpawn>c__Iterator8.MoveNext () [0x00000] in <filename unknown>:0

    (Filename: Line: -1)
     
  9. Progeny

    Progeny

    Joined:
    Sep 17, 2012
    Posts:
    32
    problem solved (I think based on 1 run - it was happening every run in scenes with many enemies)

    ProgressMap.cs, line 88, changed the following

    yield return new WaitForSeconds(2);

    with

    yield return new WaitForSeconds(0);


    ---

    I've solved the problem with camera out of world's limit. I moved my code from LateUpdate to FixedUpdate and replaced deltaTime with fixedDeltaTime, now I can't go out of the world.

    The latest problem I've to fix is when there are too many (about 30 or more) enemies simultaneously... but this one I dunno how to fix, ideas?
     
    Last edited: Nov 18, 2012
  10. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Thanks for keeping me updated on your integration! I'll investigate the ProgressMap error, there must be another way than yielding for 0 seconds to fix this.

    Good to know you've solved the camera problem you're experiencing too.

    I've run a quick test with 40 enemies of type horse_rome in the editor, the framerate has gone really bad after 20 simultaneous enemies. Then I've deleted the terrain and everything worked fine with 40 enemies. I would say that's a matter of optimization. Maybe devices can't handle terrains and skinned meshes / animated enemies at once. Also, since the terrain is crafted with Unity's terrain engine, it's not optimized at all. On top of that, 30+ enemies in the game view are pretty heavy. If you want a fluent game with lots of enemies, the only suggestion I can give you is to not use the progress map, use as few waypoints as necessary, create a terrain object in a modelling software and limit the camera's field of view, so you can't see all objects at a time. This shouldn't be related to code.
     
  11. EskemaGames

    EskemaGames

    Joined:
    Jun 23, 2010
    Posts:
    319

    Just to "help" a bit Baroni, mobile devices are NOT suited to handle a tower defense game in 3D, I mean, can you create a game?, sure, but just as you said, the amount of enemies, the level mesh, etc, everything should be adjusted with the lowest amount of polys, the skinned meshes needs to have just a few bones, etc,etc.
    For me this breaks the concept of tower defense games, because you cannot have 50 enemies (or more) attacking you with a fluent framerate on mobile devices, 30 skinned meshes is too much for almost all mobile devices. So, for me a good tower defense game needs to have tons of enemies, and this is something you CANNOT do with a mobile and 3D, it's not a limit of this package it's just a matter of technology limits :)
    If you want to handle a "decent" tower defense game for mobiles you have to stick with 2d or limit your game to the newest devices like the ipad4 or iphone5G or other android top level to get a decent performance with 3D.
     
  12. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Unless they're cubes or sprites :)
    Thanks Eskema, well said. Optimization and keeping as much enemies as needed at the same time is the hardest part, really depends on the mobile devices and the desired gameplay style.
     
  13. Progeny

    Progeny

    Joined:
    Sep 17, 2012
    Posts:
    32
    You are not saying nothing new from what we've discovered :p However, profiling performance with Xcode reports a GPU usage of 20% I will investigate whether there is a possibility to optimize the _code_. I'll try with unity profiler too...

    We have many games with 3D graphics on mobile devices working very well... Why don't give a chance in this one?


    I don't have my MBP right now, if you use itween for moving the characters, search on google for "itween performance iPhone". -> http://forum.unity3d.com/threads/58675-iTween-iPhone-Performance
     
    Last edited: Nov 19, 2012
  14. EskemaGames

    EskemaGames

    Joined:
    Jun 23, 2010
    Posts:
    319

    Yes, I'm not saying anything new, but it seems that people really don't know what a mobile is, and then you see a lot of posts like "my scene has XX characters and polys and shaders and works great on pc, I don't know why is running so slow on mobile", well, before complain and ask about the package itself and the package flaws, you should check the limits of the platform you are working with, and this is something that people only do AFTER they have discovered the issues instead of checking upfront the limits of the platform.

    Of course you can create a tower defense game in 3D, but it will be a very limited game with just a few enemies on screen, no matter how hard you optimise the code, 30 skinned characters on screen (or more) won't work (with a decent framerate) unless you aim for the fastest device.
    A tower defense game with less characters than the ones showed in "fieldrunners" cannot be considered a tower defense game (for me), and yes I know, that's 2D game
     
  15. Progeny

    Progeny

    Joined:
    Sep 17, 2012
    Posts:
    32
    the code provided with the starter kit isn't optimized for multi-core devices, in my experience with computer vision on mobile device, using threads had reduced a task that took 30seconds to 2.3 - 3 seconds to finish.
    i'm not saying that mobile device may have the same performance as desktop ones have, as a student of computer science engineering i know that ;-)
    i'm just trying to say that there could be space for more optimization, to bring this limit from 30 enemies to 50-60, it could be enough for an average game "made" by an indie developer in his first experience with games.
    what i would try now is to using enemies with threads. let's cross our finger.
     
  16. EskemaGames

    EskemaGames

    Joined:
    Jun 23, 2010
    Posts:
    319
    There's always room for improvements :) I will be waiting for your results
     
  17. barnEbiss

    barnEbiss

    Joined:
    Nov 15, 2012
    Posts:
    6
    Tried accessing the asset store and clicking the link to go to buy it but its giving error about url, you might want to check and look into it...
     
  18. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Thanks for the hint! Fixed our product page link - the Asset Store link does work on my side?
     
  19. barnEbiss

    barnEbiss

    Joined:
    Nov 15, 2012
    Posts:
    6
    clicking the button on the page that says open asset store still brings up an error.
     
  20. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    You're trying to open the link on this page

    http://u3d.as/content/rebound-games/3d-tower-defense-kit/3ab

    with a web browser, right? If so, I get an "Not Found" error too. But this link was created by Unity and their Asset Store team - you have to open that link with Unity and it will automatically open the Asset Store for you. It is not meant to be opened with a web browser.
     
  21. barnEbiss

    barnEbiss

    Joined:
    Nov 15, 2012
    Posts:
    6
    how do I open it with unity?
     
  22. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    I don't know how to connect this link with Unity, usually the installer does that for you. Try mailing at support@unity3d.com.

    You can also open the Asset Store within Unity, go to Window > Asset Store, then search it there.
     
  23. RandAlThor

    RandAlThor

    Joined:
    Dec 2, 2007
    Posts:
    1,293
    Got some yellow errors in the console on unity 4, will you make an updated version to fix them?
     
  24. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Yeah, I'll submit the next update with Unity 4. I won't fix the SetActive() errors in NGUI's free version, though. [...].

    Edit: I won't submit the next update with Unity4. I will submit it with Unity 3.5.5 and attach an additional zip file which contains updated scripts for Unity4.
     
    Last edited: Dec 7, 2012
  25. miroku000

    miroku000

    Joined:
    Sep 12, 2010
    Posts:
    22
    Hi.

    This is pretty cool. I just started using it. I think it will be a good starting point for me to make my game.

    For mobile, I really don't like the way the camera is moved around using the joystick. I would prefer to just drag my finger around and have it move based on that. It probably doesn't ever need to move up or down either. Maybe that is just me though. As I do not own NGUI, it will take a lot of work to modify the gui. Is the old GUI still available somewhere? I thought I saw mention of legacy gui stuff in the documentation, but I don't really know how to make use of it.

    I wish there was a video tutorial that started with an empty unity project, created a simple terrain, painted a road on it and added all the components necessary to get a simple level going. Or alternatively, even a simple scene with a terrain with one road in a straight line and no scenery would be cool. I am thinking of maybe starting with the mobile level, deleting all the scenery, painting over the roads so all that was left was a flat landscape, and making a basic level template where all you would need to do was recreate the grid, the paths, and define the waves. I think that would be really useful for someone trying to get something up and running quickly.
     
  26. miroku000

    miroku000

    Joined:
    Sep 12, 2010
    Posts:
    22
    There seems to be a problem with Deleting Waypoints using the Waypoint Manager in Unity 4.0.

    If you use the "-" button to delete a waypoint (in the middle somewhere, not the start or end one) in the Waypoint manager, it starts throwing the following errors:

    NullReferenceException: Object reference not set to an instance of an object
    PathEditor.OnSceneGUI () (at Assets/3D Tower Defense Starter Kit/Scripts/Editor/PathEditor.cs:276)
    System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Applications/buildAgent/work/3df08680c6f85295/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)
    Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
    System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Applications/buildAgent/work/3df08680c6f85295/mcs/class/corlib/System.Reflection/MonoMethod.cs:232)
    System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at /Applications/buildAgent/work/3df08680c6f85295/mcs/class/corlib/System.Reflection/MethodBase.cs:115)
    UnityEditor.SceneView.CallOnSceneGUI () (at C:/BuildAgent/work/812c4f5049264fad/Editor/Mono/SceneView/SceneView.cs:1335)
    UnityEditor.SceneView.HandleSelectionAndOnSceneGUI () (at C:/BuildAgent/work/812c4f5049264fad/Editor/Mono/SceneView/SceneView.cs:839)
    UnityEditor.SceneView.OnGUI () (at C:/BuildAgent/work/812c4f5049264fad/Editor/Mono/SceneView/SceneView.cs:728)
    System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Applications/buildAgent/work/3df08680c6f85295/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)

    I have tried this with both the mobile scene and also the Sample Waypoint scene.
     
  27. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Hi miroku,

    thanks for using our kit.

    The joystick is a single script which accesses the main camera gameobject, of course you can swap it out with your own solution as we cannot provide a script for all situations. The old GUI was built with Unity's GUI methods and discontinued since the last version (1.1). If you do want an older version please drop me a pm with your invoice number and I'll set something up.

    It was not our intent to explain how to set up a terrain, since that's one of the things that do not necessarily have anything to do with our kit. There are a lot video tutorials on youtube and other sites on how to create terrains. All components that are necessary have their own example scene, so you can investigate them one by one. The documentation provides a step-by-step guide through the whole kit, so once you completed all chapters you learned how to configure the scene, create paths, towers, enemies and waves. We haven't provided a basic level template, because you will likely create a new project for your game and maybe skip some of our settings. Please correct me if I'm wrong here or if you need any further assistance.

    Thanks for pointing this out, I'll make sure the error gets fixed when I release the Unity 4 compatible version in the course of this week.
     
  28. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Christmas rebate incoming: 30% off all our products!

    Announcing Version 1.2 (Pending review) - Release notes:

    Fixes Changes
    • TowerEditor.cs: fixed serialization issue when changing tower settings
    • TowerRotation.cs: auto disables on awake, prints debug message if a turret was set but script is missing
    • SV_obsolete.cs: removed since totally obsolete
    • Projectile.cs: added buffer value when leaving tower radius, fixing missed hits when timescale is greater than 1
    • Various checks for prefab null references before instantiating them
    • GUIImpl.cs, Adv_GUIImpl.cs: Showing the exit menu now stops the game
    • Unity4 compatibility through updated scripts in separate zip file: see README

    Features
    • PoolManager.cs: added method “DeactivateAllInstances” of a specific pool
    • Advanced scene (see WebPlayer):
      -Fast-forward button added
      -Laser tower added (new tower model, projectile + additional script)
    • iTween switched to HOTween:
      -HOTween now supports linear curved paths - thanks to the author for a generous cooperation! -
      -Renamed iMove to TweenMove, fixed references in Properties.cs, PathIndicator.cs, WaveManager.cs, EnemySetup.cs and enemy prefabs
      -TweenMove.cs: removed support for easetypes
      -PathManager/PathEditor: added option to draw curved path gizmos
      -Restructured ProgressMap with HOTween to require less calculations

    Please do note that your own enemy prefabs will lose their reference to the new TweenMove script (breaking changes), I would suggest making a backup before upgrading.
     
    Last edited: Dec 11, 2012
  29. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Version 1.2 has been accepted and is available on our stores out now!

    Back to first post...
     
  30. LandonC

    LandonC

    Joined:
    Dec 20, 2012
    Posts:
    83
    Hi, I'm a newbie at Unity, can anyone point out how to successfully import a enemy model together with the animation? Currently I am stucked at applying animations into the enemy prefab. It just don't animate the death scene and walking scene. Did I do something wrong with creating the FBX or it is just a trick I do not know about Unity?
     
  31. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Hi Landon,

    did you had the chance to look at Unity's animation component?

    http://docs.unity3d.com/Documentation/Components/class-Animation.html

    For testing purposes, to see whether your object gets animated correctly, assign the animation clips to this component too and check "Play Automatically". Drag and drop the object in the scene. If you press play, it should play its animation.

    If everything looks ok, remove the object again. Then assign the animation clips to the prefab's animation component (if not done already) and properties script. When playing the game your object should have a walk and death animation. Please report back if any of these steps fail.
     
  32. WJ

    WJ

    Joined:
    Oct 25, 2012
    Posts:
    97
    Hi, Thanks for the great framework, I've got my game up and running now however your waypoint system doesn't work well and is pretty bad on uneven terrain.

    I want to use A* instead but am not sure how to replace it, there seems to be a lot of calls to tween's. Is there a point in the code where I can trigger a spawn and then inform your framework when the enemy has reached the end point?

    Thanks
     
  33. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Hi WJ,

    the WaveManager script spawns enemies per wave and starts their movement in SpawnEnemy(), that would be your starting point. When the enemy has reached the end point, TweenMove.cs calls PathEnd() in Properties.cs, which deals damage to the user's health and removes the enemy. You can call this method via your A* implementation. Properties.cs also stops the enemy's movement if it dies, you would want to add that functionality to your implementation too.

    During the game, the ProgressMap gets the path progress of TweenMove.cs. Therefore I do not recommend using the ProgressMap with your A*, otherwise you have to completely rewrite it. The last reference to TweenMove exists when a projectile slows the enemy. The projectile calls Slow() in Properties.cs, which forwards the call to TweenMove.
     
  34. Dawson8

    Dawson8

    Joined:
    Jul 12, 2012
    Posts:
    22
    Hi, this is a great kit, well organised and well documented thanks!

    I am wanting to implement a save function, I see that you store an array of used grids so that 2 towers cannot be placed on the same grid, but is there a way to easily find out which tower is on which grid?

    I would like to save this data and then reload it and instantiate all the towers in the same place. Could you point me in the right direction for doing this please?

    Thanks
     
  35. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Hi Dawson,

    thank you for the kind words!

    There is no method in any script right now, but you can use the same code as in GUILogic's SellTower() for raycasting. New towers are instantiated as a child of the TowerManager, so we start searching there:

    Code (csharp):
    1. GameObject towerManager = GameObject.Find("Tower Manager");
    2.  
    3. foreach(Transform tower in towerManager)
    4. {
    5.         //define ray with down direction to get the grid beneath
    6.         Ray ray = new Ray(tower.position + new Vector3(0, 0.5f, 0), -transform.up);
    7.         RaycastHit hit;
    8.  
    9.         //raycast downwards of the tower against our grid mask to get the grid
    10.         if (Physics.Raycast(ray, out hit, 20, SV.gridMask))
    11.         {
    12.             Debug.Log(tower.name + " is standing on " + hit.transform.name);
    13.         }
    14. }
     
  36. Dawson8

    Dawson8

    Joined:
    Jul 12, 2012
    Posts:
    22
    Thanks for the advice that looks like a great starting point.
     
  37. Dawson8

    Dawson8

    Joined:
    Jul 12, 2012
    Posts:
    22
    Hi,

    I could not get it to work the way that you posted I kept getting the following error:

    Code (csharp):
    1.  
    2. error CS1579: foreach statement cannot operate on variables of type `UnityEngine.GameObject' because it does not contain a definition for `GetEnumerator' or is not accessible
    3.  
    However I have managed to save the tower name and grid position, I added a new method which handles the saving and I call it by passing the name and grid to it (SaveTower(towerBase.name, currentGrid.name)) at the end of BuyTower() in GUILogic.cs

    I was planning to update this at the end of your Upgrade method so that I could save the curLvl also

    I can reload this data back into the game but my next problem is getting it to instantite the tower on the correct grid automatically, any ideas?

    Thanks
     
  38. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Sorry, actually is has to be

    Code (csharp):
    1. foreach(Transform tower in towerManager.transform)
    good to know you already solved it within BuyTower().

    That would be another method which searches for the correct grid in the scene and instantiates the correct tower stored in TowerManager.towerPrefabs. Optionally placed in GUILogic.cs. For example, you can search the grid via

    Code (csharp):
    1. GameObject grid = GameObject.Find("your saved grid name")
    and then instantiate the tower by using

    Code (csharp):
    1.  
    2. for(int i = 0; i < towerScript.towerPrefabs.Count; i++) //loop through towers
    3. {
    4.    if(towerScript.towerNames[i] == "your saved tower name") //we found the correct tower prefab in the TowerManager script
    5.    {
    6.       //instantiate tower on grid
    7.       GameObject tower = (GameObject)Instantiate(towerScript.towerPrefabs[i], grid.transform.position, Quaternion.identity);
    8.       //Do the other important stuff here!
    9.    }
    10. }
    Do not forget to rename the tower, parent it to the tower container gameobject and enable the TowerBase and TowerRotation script of the tower. For the grid, you have to add its name to the occupied grid list and change the grid material. You don't have to code these steps again, you'll find them at the end of InstantiateTower() and BuyTower() in GUILogic.cs. Hope that helps!
     
  39. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    This is the last week of the sale!
    Don't miss out on a 30% rebate if you are interested in one of our products.


    Happy Holidays!
     
  40. gevarre

    gevarre

    Joined:
    Jan 19, 2009
    Posts:
    132
    Hi, great kit. This is one of the best I've used, and the documentation is really well-done, except there really needs to be a lot more on getting an enemy into the game, including how it needs to be set up for import from the modeling package. I've tried everything and I can't get this to work. I can export the model from Maya okay as an .fbx file, but when I then use your Enemy Setup window to try to create the prefab from the exported model, I get this:

    Code (csharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. EnemySetup.ProcessModel () (at Assets/3D Tower Defense Starter Kit/Scripts/Editor/EnemySetup.cs:265)
    3. EnemySetup.OnGUI () (at Assets/3D Tower Defense Starter Kit/Scripts/Editor/EnemySetup.cs:137)
    4. System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Applications/buildAgent/work/3df08680c6f85295/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)
    The result is a copy of the model placed in the scene, but it has nothing attached to it: no scripts, health/blob prefabs, or anything else, and no prefab is actually created. The error seems to be referring to an animation problem, but since you don't mention anything about animation in your documentation, that's about all I can figure out.

    Further investigation reveals that if I just use one of the enemy models you already have in the kit, it works fine: a new prefab is created and there are variables in the attached script for attaching the animations. However, even if I directly import the .fbx file of your included enemies into Maya and then re-export, I get the same error.

    It's also confusing to me that only two of your enemy models seem to have animations attached to them (dragon and raven). None of the others do. They seem to get attached in the properties script once the prefab is made, so that's telling me that it really doesn't matter if the original models have animation or not. You can just attach the animations later. You have a folder containing animations, but you don't say how they were created. Could you provide some clarification on this process? An additional section in the documentation devoted to this would be nice, but for now it would help a lot just to get some insight as to what's causing the error.

    Anyway, here's a list of questions I have that may or may not have anything to do with the problem:
    • How does the model in the animation package need to be set up (In my case, Maya)?
    • Anything special about the skinning?
    • Does the skeleton need a certain number of joints?
      (I hope not, because you have way too many for a mobile game. I would prefer very few, like 2 or 3, or in some cases none at all)
    • Do the joints need to be named anything in particular?
    • How are you creating your animations, such as peasant@running and peasant@dying?
      (I'm guessing this is more to do with using Unity's animation system rather than your kit, but it would help to know the process as far as how it relates to what is required by your kit since the errors seem to have something to do with the animation.)
    • Can I have animations without a skeleton or skinning?
      (I'm doing mechanical enemies, so all I really need is a hierarchy of objects with animation, which is much easier on the processor than skins. I could skin one object to each bone, but this is really overkill, and again, for a mobile game, this creates a lot of undesirable overhead. The simplest case would be where all I do is import a sprite with a texture that I then set to always face the camera, and then just put a basic animation on the sprite.)

    Again, great kit. It just needs a little polish to make it awesome, and I'm impressed by the amount of work you're putting into responding to people's concerns and requestions. If I can get these enemies to work, I'll definitely be giving it a great review and the best possible rating.

    Thanks :)
     
  41. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Hi gevarre,

    thank you very much for taking the time to share your feedback on the kit. I'll try to answer all your questions one by one:

    The EnemySetup widget could not find an animation attached to the model you've imported, that's why it throws a null reference exception. In the current state, the script requires an animation component on the enemy model. I should have seen that coming, sorry for the confusion. Please modify the block in line 265 of EnemySetup.cs to

    Code (csharp):
    1. //disable animation autoplay
    2. Animation anim = enemyModel.GetComponentInChildren<Animation>();
    3. if(anim != null)
    4.    anim.playAutomatically = false;
    Now you can import models without animation (and without errors). Regarding your question about animations and the animation folder:

    The dragon and raven were created and animated directly in blender. Then we exported the fbx including their animations. If you investigate the dragon model, you'll see the animation component and a "Flying" animation attached to it. Unity automatically has taken care of the import process.
    For the human models, we used a more "customizable" approach. They were created in blender, but exported without animation. On the "knight", you'll see that he has an animation component but no actual animation. It's just the model. We then created the animation clips "running" and "dying" in blender and exported them to Unity - without model! because we don't need it more than once. Because of the naming convention (knight@animationclip), Unity assigns the animation clip to the model. Well, it should. But that's somehow deprecated or broken since Unity4. You can read more about the convention and advantages here.
    The cubic enemy "Adv_Enemy" is used for the example scenes and uses yet another animation scheme. For this object, the animations were created directly within Unity with its default animation window, since it didn't make any sense to bring up blender for a cube. After the creation, the clips were saved in the "Animation" folder as "CubeWalk" and "CubeDie".

    When setting up the Properties script with animations, first the enemy objects needs to have an animation component containing all animation clips. Then drag drop these clips in the slots for "Walk Anim" and "Die Anim" too. You can refer to the "Adv_Enemy" object for details. Also, see this link.

    Now, to your list of questions from top to bottom.

    1. You can set up your model in Maya as decribed above - include the animations in the fbx, export them separately, or export without animation and animate it within Unity. These are the basics of Unity's animation system, the kit does not require a special setup.
    2. + 3. + 4. Nothing special, no certain number of joints or a special naming of joints. What the Properties script does is to just play the animation you attached to the object. It does not control or somehow verify your animations.
    5. Already described above.
    6. Yes, the "Adv_Enemy" object does not have a skeleton, it's just a cube.

    If you have any further questions, please contact me here again. I'll be out of the office for the next two days and unable to reply, but keep em coming :)
     
    Last edited: Dec 26, 2012
  42. Dawson8

    Dawson8

    Joined:
    Jul 12, 2012
    Posts:
    22
    Thanks Baroni,
    This was really useful information
     
    Last edited: Dec 27, 2012
  43. gevarre

    gevarre

    Joined:
    Jan 19, 2009
    Posts:
    132
    @Baroni: Thanks for the quick reply. You do a great job of taking care of your users :)

    The info was very helpful. I should have known it was something to do with Unity 4 changes (something I neglected to mention I was using). The import and animations work fine now with the change you suggested.

    Now that that's working, I have one more problem though. I've set up an enemy and it's working correctly in game as far as spawning and following paths. The towers are shooting at, but it isn't taking any damage. I'm noticing that the hit effects are not playing, so maybe the collision isn't being detected? The collider on the enemy is active and set to "is trigger". I'm not sure what else to look for.

    Before I try to list every single property and everything else, any general ideas on what might be wrong?
     
    Last edited: Dec 28, 2012
  44. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Hmm... I only can image two missing things: Does the same gameobject which holds the collider component also have a rigidbody?

    Optionally, it could be that the problem does not have something to do with your enemies, but with the projectiles. They also need to be on the "Projectile" layer, have a collider with "Is Trigger" set to false, a rigidbody set to "Is Kinematic" and without gravity.

    If you expand the Pool Manager gameobject and investigate the child for projectiles, you can track whether the projectiles correctly collide (thus despawn). Please report back :)
     
  45. gevarre

    gevarre

    Joined:
    Jan 19, 2009
    Posts:
    132
    Okay, so the enemy prefab does have a rigid body on it, just like the peasant and the other enemies. I don't think it could be the projectiles because I'm just using your included towers in order to make debugging easier (in these test cases, I'm only using the arrow tower). I looked into them anyway like you suggest just to be sure.

    The projectiles do seem to be spawning and despawning correctly (as in, they start grey in the hierarchy, turn black when they are spawned, and go back to grey again, so they must be detecting a collision. For further debugging, I set the "Time To Last" variable to 10 seconds and made the capsule collider on my enemy very large. Watching carefully, I'm seeing that the arrow will stop just when it reaches the edge of the very large collider, so that confirms that the projectiles are indeed detecting the collision with the enemy collider.

    Also, since you gave me the clue of looking at what's happening in the hierarchy window, I'm looking at the splatFX: when I use the peasant, I can see them spawning and despawning just fine in the pool manager. When I assign that same splatFX to the "Hit Effect" variable on my enemy, I can see that that effect never spawns, so evidently, even though the projectile is colliding with the enemy's collider, whatever is supposed to control playing the hit effect and updating the health is never getting the signal to do so. I'll poke around in the hit effect code to try to trace it back, but since it's C# rather than JS, I don't know how far I'll get.
     
  46. gevarre

    gevarre

    Joined:
    Jan 19, 2009
    Posts:
    132
    Aha!
    Update: by stepping through the Properties and Projectile scripts one section at a time and using numerous Debug statements to see what was going on, I figured out the problem. In the Hit function of the Properties script, you check to see if the enemy is dead or already playing the death animation with this line:

    Code (csharp):
    1. if (health <= 0 || (dieAnim  anim.IsPlaying(dieAnim.name)))
    The problem was that I was lazy and didn't make a seperate death animation yet, so I just assigned my walk animation to both the "Walk Anim" and "Die Anim" variables just because I didn't want an empty field. Since the walk animation was already playing when the check was made, the function assumed I was already dying and ignored me. I removed the Die Anim, and now it behaves perfectly.

    I'll say again that you have done a very good job of documenting; something a lot of people forget. The comments were clear and the code easy to follow. As a result I now have a much better understanding of how the whole thing functions :D
     
  47. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    I'm glad you found out what's going on and that you've explained your progress, I probably couldn't help you that much in this case and already wanted to ask you for a simple repro project... since that's solved now, again I thank you for your feedback (commenting everything took a while, it's great to hear it helped) and I wish you much fun when altering the kit :)


    Edit:
    Last two days of the sale!
    Don't miss out on a 30% rebate if you are interested in one of our products.
     
    Last edited: Dec 29, 2012
  48. Penguin_Tamer

    Penguin_Tamer

    Joined:
    Nov 2, 2012
    Posts:
    4
    I've got a quick question about how enemies move along the path. I've looked at the documentation for HOTween but its not really helpful, so I'd like to ask here and see if this has come up before.

    I'm trying to create an enemy that, upon death, spawns more enemies where it was destroyed. The issue is that I don't think HOTween is designed to have objects spawn in the middle of a path. Right now when the second enemies are spawned they move back to the first waypoint, then proceed along the path as normal, rather than just continuing from where they spawned. Is there a way that you know of to handle starting in the middle of a path?
     
  49. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,256
    Hi Penguin and a happy new year,

    HOTween's tween does have a method named "GoTo" (link to documentation), which sends the tween to the given time. You can get the time of the current tween via tween.fullElapsed and pass it to that method, directly after calling StartMove(). That should do it!
     
  50. Penguin_Tamer

    Penguin_Tamer

    Joined:
    Nov 2, 2012
    Posts:
    4
    That kind of works, and I had done something similar to begin with (though using tween.position instead of fullElapsed). It works somewhat, but there are strange bugs and I'm not sure why. It seems that part of it is that the two types of enemies (the original and the one it spawns) have different speeds, so setting their positions to the same thing doesn't actually work. With what you suggest, the spawned enemies (which are faster) often spawn far ahead of the original.

    Ideally I'd like to just calculate the waypoints that the original enemy has passed, and remove them from the list of waypoints the spawned enemies use to calculate their path. I don't suppose HOTween has a way to figure out that?