Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

[UPDATED] ICECreatureControl v1.4.0 - creature AI for enemies, animals, monsters, zombies ...

Discussion in 'Assets and Asset Store' started by icetec, Aug 11, 2015.

  1. jonfinlay

    jonfinlay

    Joined:
    Aug 25, 2015
    Posts:
    535
    Cheers, I'll download 2017.4.13 which was released on October 12th this year. Fingers crossed ;)
     
  2. dsilverthorn

    dsilverthorn

    Joined:
    May 14, 2017
    Posts:
    313
    I’m pretty sure the last release of ICE was for 2017 versions, I get some bugs here and there, but I had that with previous versions of Unity as well. I think you’re pretty safe sticking with latest 2017.
     
    jonfinlay likes this.
  3. AndyNeoman

    AndyNeoman

    Joined:
    Sep 28, 2014
    Posts:
    870
    It does work with 2018 if you deal with the audio = null issue described earlier in the thread.

    I do have an issue with the creature register and objects if anyone can help though :-(. DO you have to have all objects in the scene to use with ICE. I have some food which I need to change the tag on toallow different AI interactions but that means "Myfood" tag is not in the scene initially. Is there any way around this issue?

    To give a bit more detail when the player picks up a food item they can then feed the AI. So I change the tag of the food so the AI then interacts with it. But it is not finding the tag in game because it was not there initially. Any ideas?
     
    jonfinlay and dsilverthorn like this.
  4. cheesee09

    cheesee09

    Joined:
    Mar 30, 2018
    Posts:
    35
    Is there any tutorial on how can flying creatures attack while on air?
     
  5. C_p_H

    C_p_H

    Joined:
    Nov 24, 2014
    Posts:
    146
    Here's tutorial link regarding flying Ice_CC on YouTube.

    Hope it's helpful.
     
    dsilverthorn likes this.
  6. cheesee09

    cheesee09

    Joined:
    Mar 30, 2018
    Posts:
    35
    Tnx for the reply but I already did that. What I want to accomplish is I want my dragon behaves like in skyrim where the dragon will randomly fly and circle around then attack the player with long range attacks and when its health is low it will land and attack the player.
     
  7. AndyNeoman

    AndyNeoman

    Joined:
    Sep 28, 2014
    Posts:
    870
    Hello all, I'm hoping for a little bit api help if possible. I'm trying to get a reference to the current target for player (Ice player) and any AI that might target another AI or player. Anyone got an idea of how to get it?

    Thanks all and happy holidays.
     
    Last edited: Dec 22, 2018
  8. Gregorik

    Gregorik

    Joined:
    Dec 11, 2014
    Posts:
    334
    Any of you guys tried the (relatively) new Eliot AI or Polarith AI packs as an ICE replacement?
    Any positive experiences?
     
  9. SickaGamer

    SickaGamer

    Joined:
    Jan 15, 2018
    Posts:
    790
    I am use Emerald AI and with the improvements he is making, I think it will be up there soon!
     
  10. AndyNeoman

    AndyNeoman

    Joined:
    Sep 28, 2014
    Posts:
    870
    I haven't tried them but from reading the docs I'm not thinking to change. Emerald is good for enemies etc.. and is about to be updated with some nice new features. The emotes feature might even be able to add the things I need from ICE for my current project so I can see myself switching to that totally in time. MY next game is just emerald although I don't need some of the features my current game uses ICE for.
     
  11. C_p_H

    C_p_H

    Joined:
    Nov 24, 2014
    Posts:
    146
    @AndyNeoman
    I think this might be what you're looking for to get the current GameObject Target.

    "
    7.3 INTERACTOR TARGET
    Interactors are mostly objects of interest, which will be normally interesting for other objects of interest as well, such as the Player Character or other NPCs and therefore such objects have to be registered in the creature register to provide a quick access to relevant data during the runtime. For this reason, you have to use the popup to select your desired interactor. If your desired interactorisn’t listed currently, switch to your creature register to add the interactor. Please note, that yourinteractor object doesn’t need additional scripts to be listed in the register, unless your interactor is a player character or a NPCs, which is not controlled by ICECreatureControl, in such a case you should add the ICECreatureResident Script to your interactor, which will handle the registration and deregistration procedures during the runtime.

    "
     

    Attached Files:

    AndyNeoman likes this.
  12. mattis89

    mattis89

    Joined:
    Jan 10, 2017
    Posts:
    1,070
    really still people using this asset even when its dead..
     
  13. Gregorik

    Gregorik

    Joined:
    Dec 11, 2014
    Posts:
    334
    And I imagine it's more broken than ever under Unity 2018.3 with its fundamental changes... It's time to ice ICE.

    Emerald is OK, but Eliot seems to be more promising.
     
    mattis89 likes this.
  14. zenGarden

    zenGarden

    Joined:
    Mar 30, 2013
    Posts:
    4,538
    I agree when a plugin is no more supported it's better to move on.
    Ice had great ideas, but i imagine it has been a nightmare to maintain the interface and code for the author; while it would have get an heavy simplification if it has used graphical behaviour trees and perhaps it would still be supported.

    Emerald is not really modular, it is premade AI with lot of common behaviors and things you can tweak, while Eliot looks more like Node Canvas a behavior tree system to make your own very custom AI.

    You should choose depending on what AI you expect.
    It's like Third Person Cover shooter that has twekable premade behaviors, you are limited to it's premade behavors.While Invector new FSM AI let you make your own custom behaviors.
    One is premade you have less work, the other needs some more work but you have full creativity to make custom ai.

    For very common AI like many action games Emerald will be enough. But to be able to create your own specific behaviors Eliot (or other behavior tree plugins as i don't have Eliot plugin ) is the way to go.
     
    Last edited: Dec 23, 2018
  15. AndyNeoman

    AndyNeoman

    Joined:
    Sep 28, 2014
    Posts:
    870
    With it being a scripting asset then its not really broken and when api calls have changed it's pretty easy to update. There is still nothing around that comes close to ICE, I don't plan on leaving it until there is something as good to use. If anything I seriously considering getting stuck into it and extending it myself.
     
    jonfinlay, dsilverthorn and C_p_H like this.
  16. AndyNeoman

    AndyNeoman

    Joined:
    Sep 28, 2014
    Posts:
    870
    Thanks for that. Hopefully should be the trick I need to finish the integration with Love/Hate.
     
  17. dsilverthorn

    dsilverthorn

    Joined:
    May 14, 2017
    Posts:
    313
    When an asset dies it doesn’t mean your project is finished.
    When Unity does another frequent update or complete overhaul, it doesn’t mean you use it and sometimes start over. When I’ve tried that, it has set me back so much due to bugs and incompatible assets that also need updating, it has meant starting basically from scratch.

    Sometimes, as small time developers, we have to use the tools we have and save up for a change that will overhaul our entire project.

    I wish I had the money and time to just drop every asset that is not supported, but I don’t have enough of either.

    If only the asset developers would have the decency to not let their assets die until my project is finish. :D
     
    StevenPicard and SickaGamer like this.
  18. dsilverthorn

    dsilverthorn

    Joined:
    May 14, 2017
    Posts:
    313
    Merry Christmas everyone!
    View attachment 349942
    I had fun putting this card together and thought I would share it with everyone. :)

    Snow and haze by Weather Maker
    Landscape by Landscape Builder and World Creator 1
    Clouds by Fog Volume 3
    Trees by Forest Vision
    Placement by Vegetation Studio
     
    nirvanajie, C_p_H and Duffer123 like this.
  19. C_p_H

    C_p_H

    Joined:
    Nov 24, 2014
    Posts:
    146
    If y’all find that behavioral tree alternatives for NPCs are driving you crazy then also consider a tabbed interface NPC AI such as ORK & Makinom, the learning curve is on par with ICE but I think you’ come love its powerful and very capable features.
     
  20. jonfinlay

    jonfinlay

    Joined:
    Aug 25, 2015
    Posts:
    535
  21. dsilverthorn

    dsilverthorn

    Joined:
    May 14, 2017
    Posts:
    313
    Same here.
    I downloaded when it went free, but have not tried it.
     
  22. Tethys

    Tethys

    Joined:
    Jul 2, 2012
    Posts:
    662
    I too and now looking for alternatives to ICE. I have a new project where I can use Navmesh for AI units so I'm not stuck using ICE. I'm considering Opsive Behavior Tress and Movement pack for NPC's and enemies. Anyone else have a good or bad or limited experience with his product? I am using his new reworked Ultimate character Controller asset so would be convenient to use the two products together.
     
  23. StevenPicard

    StevenPicard

    Joined:
    Mar 7, 2016
    Posts:
    641
    For others looking for AI alternatives, I can say that so far I am extremely impressed with Eliot AI. I'd give it a shot.
     
    AndyNeoman and dsilverthorn like this.
  24. Gregorik

    Gregorik

    Joined:
    Dec 11, 2014
    Posts:
    334
    Behavior Designer can do anything that ICE could, and a lot more. Also, the recent 1.6 update is pretty big. Honestly, I've ditched both ICE and Emerald for BD recently.
    There are folks here who claim that "nothing comes close to ICE", but I'm sure they never gave BD a chance. I don't really blame them since it's almost 3x more expensive than ICE when you also buy BD's essential packs.
     
    Last edited: Jan 2, 2019
    dsilverthorn and Tethys like this.
  25. Tethys

    Tethys

    Joined:
    Jul 2, 2012
    Posts:
    662
    Awesome man, thanks for the feedback! Yeah, it looks really good - I only hesitate because its a new system to learn and I'm hoping there are some out of the box examples. I learn best from looking at functional examples and pulling it apart and rebuilding.
     
  26. AndyNeoman

    AndyNeoman

    Joined:
    Sep 28, 2014
    Posts:
    870
    I don't think behaviour designers ability to do it all is in question, just the time it takes to implement behaviours and the learning curve make it less than optimal for some. I'd love some more info on it though from some one who moved from ICE to it. How do you deal with animator controllers? Now that I use other systems that link into AI like Love/hate, Quest Machine I am considering moving to BD in the future. Is there a scripting API and how did you find it's learning curve.
     
  27. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,786
    BD's scripting API is actually simpler than ICE's. For the most part, you'll just re-use one fairly simple template to write different custom tasks (nodes in your behavior tree). So you just need to familiarize yourself with that one template.

    The initial learning curve is steeper than ICE, though. With ICE, you just drop the component on a GameObject and it immediately does things because the behavior is mostly hard-coded. With BD, you need to define the behavior tree, which means you need to learn how behavior trees work. But since they're so popular there are many good tutorials on the net. Check BD's addon packs, too, such as the Movement Pack and Formations Pack. They take care of many fundamental actions such as detecting things in the world and moving around.
     
  28. Tethys

    Tethys

    Joined:
    Jul 2, 2012
    Posts:
    662
    Last edited: Feb 7, 2019
    dsilverthorn likes this.
  29. Tethys

    Tethys

    Joined:
    Jul 2, 2012
    Posts:
    662
    Anyone know offhand if and what the Event is for OnDeath? Having a hard time finding it. I know I can store the float for healthinpercent but its more overhead to constantly check that than listen for the OnDeath event which I imagine is somewhere. Anywho, thanks in advance if anyone knows it. I found a bug in the DEAD behavior. I want to use the event to fire a custom event I have created, which does work. However, no matter what option you set for when to fire the event in ICE, it ignores all of it and always uses the remove delay set in the DEAD essentials tab. This isn't working for me because I need to get values off of the ICE creature BEFORE its removed, WHILE the object has been spawned. Of course it only spawns the object AFTER the removal of the body heh. S

    **UPDATE** My solution for now is simply to only check health when the ice entity is damaged, then fire off whatever I need manually when we reach 0% health. Using the new UCC and just integrating damage and health monitors manually at this point.
     
    Last edited: Feb 15, 2019
    jonfinlay likes this.
  30. Funkymotha

    Funkymotha

    Joined:
    Feb 25, 2016
    Posts:
    24
    Do you have a link? I can't seem to find it.
     
  31. Tethys

    Tethys

    Joined:
    Jul 2, 2012
    Posts:
    662
    Hello folks. Using ICE in a new project and remembering some of those old issues. Has anyone EVER gotten the Footsteps functionality under Environment on the Character to work? Using it in a non-procedural environment this time and I still cannot get the steps to work in any fashion. I have the texture loaded that I'm using for the mesh ground with footstep sounds and effects hooked up but I get nothing. I wonder if there is a super secret toggle somewhere else that needs to be set in order for this function to work. Any advice is much appreciated.

    **UPDATE** I found it! And now I can use the function in Astral Terra lol. It's so simple yet silly considering how many things I tried. I noticed, finally, that the only difference between my character and the ICE characters whos steps work, is the Curve. When setting up new steps, the Curve is left null for some reason. All you have to do is click and set and boom, footsteps now work lol. Live and learn. I cannot however get the Effect to work still. Even when put on interval. I've tried with DETACH on and off, mounted and unmounted.
     
    Last edited: Feb 19, 2019
    dsilverthorn and jonfinlay like this.
  32. jonfinlay

    jonfinlay

    Joined:
    Aug 25, 2015
    Posts:
    535
    It’s a few pages back, but I personally had problems with it and so just stuck with 2017. Ice works flawlessly in that, and so do other deprecated assets so I didn’t feel the need to upgrade, plus the latest updates have made 2017 a very secure editor and hasn’t crashed on me once.
     
  33. Gregorik

    Gregorik

    Joined:
    Dec 11, 2014
    Posts:
    334
    Hi, is there anyone who is chummy with Pit enough to talk to him about releasing the source code?.. Not trying to beat a dead horse here. But perhaps he's in a different place since he chose to deprecate the asset.

    I've been using Eliot AI extensively (which is constantly updated and getting 5* reviews), and I have to say that ICE was better and more ambitious.
     
    Flurgle, TonanBora, jonfinlay and 2 others like this.
  34. Exctazy

    Exctazy

    Joined:
    Oct 24, 2017
    Posts:
    1
    Hello everyone, i need some help to setup the death of my enemies. I mean, i've already set up "Walk", "Run", "Idle", "Attack" behavior and everything work. The problem is that when the enemy should be dead, he continue to attack the player. I've put a corpse prefab ect... I have no idea why do he continue to act like he is not dead.. Thanks.

    Edit : Okay i have a Custom monster health script that manages everything related to the health of the enemy. And in fact, it is not linked to ICE script. So when my enemy is at 0 health, for the ICE Script the enemy still has 100 durability. How can i make the durability of the ICE Script linked to my custom health script ?
     
    dsilverthorn likes this.
  35. C_p_H

    C_p_H

    Joined:
    Nov 24, 2014
    Posts:
    146
    I’ve been able to keep ICE_CC compatible with the latest Unity release using the latest VisualStudio(2019.1 at the time of this writing).
     
    dsilverthorn likes this.
  36. SickaGamer

    SickaGamer

    Joined:
    Jan 15, 2018
    Posts:
    790
    "fork" over your copy!
     
    dsilverthorn likes this.
  37. C_p_H

    C_p_H

    Joined:
    Nov 24, 2014
    Posts:
    146
    o_O I could if Pit would sign me onto his Software Redistribution License. Good sarcasm by the way!

    :confused: Your comment did make me realize that I should have been commenting out every revision made to the ICE C# scripts up til now but unfortunately I stopped doing it because I never intended on rolling back any of the Unity obsolete script calls. I'm a non-coder whom just utilizes Visual Studio and Unity script update recommendations to plug-in the new calls and for scripts I had no clue how to fix I'd simply use VS's Suppress warnings feature.

    ICE_CC is still a master piece IMHO and I still haven't gotten around to use or test all of its features due to time and project constraints. I've rage quit it several times over the years but I keep coming back to it whenever I encounter a barricade or limitation with other AI's. When nothing else works I seemingly get lucky discovering why something doesn't work after clicking through ICE_CC's 100's of attributes then I simply go back to the tool I was using or use ICE for that. Time will tell if I ever will complete a master piece of my own;) but it sure is frustratingly fun trying.
     
    jonfinlay likes this.
  38. SickaGamer

    SickaGamer

    Joined:
    Jan 15, 2018
    Posts:
    790
    I bought it and then a month later Pitt left ... i have been rocking Emerald AI for everything.
     
    mattis89 likes this.
  39. jonfinlay

    jonfinlay

    Joined:
    Aug 25, 2015
    Posts:
    535
    Hi, was it just a matter of commenting out a few lines? I don't use Visual Studio. I looked around on the asset store but to say nothing else comes barely close to Ice is an understatement. Even Eliot only works on 2D planes, and the safari demo was less than impressive.

    If it's the audio which I believe it is, which lines need to be commented out? I deleted the network file without any consequences. Any help is greatly appreciated.
     
    dsilverthorn likes this.
  40. jonfinlay

    jonfinlay

    Joined:
    Aug 25, 2015
    Posts:
    535
    Sorry couldn't edit that last post but meant to say I use notepad ++ instead
     
  41. zenGarden

    zenGarden

    Joined:
    Mar 30, 2013
    Posts:
    4,538
    Some could re make Ice Creatures, a plugin inspired by it, with simplified code that would be more evolutive and more easy to change when needed, with better UI so less tiny buttons.
    There is lot of people that would like something similar and as versatile, but more clear and more easy to use.

    That was one big issue about Ice, it was not possible to use it beyond very basic ai without some good tutorials explaining how to use it.
     
  42. Harekelas

    Harekelas

    Joined:
    Feb 3, 2015
    Posts:
    743
    I took some of ICE's ideas and made my own state machine based AI system along-side with unity job system. It's now quite good for me, but it's not easy to use for non-coders. What ICE did with all the logic rules and interactions should be done with a node graph, and stored as scriptable objects. It's a great amount of work to make something able to create complex AI logic without coding.
     
  43. jonfinlay

    jonfinlay

    Joined:
    Aug 25, 2015
    Posts:
    535
    Maybe that's true with humanoids who fire projectiles and pick things up, etc, but the animal ai was advanced. I once got two packs of hyenas to battle it out, each retreating and attacking at random. The result looked good.

    Anyway for those looking to get it working on 2019 the same fix as before works:

    Delete the network file that throws up the error.
    Then open up ice_objects_audio.cs and comment out all lines referring to:

    new AudioClip()

    Just did a quick test and it seems to work, haven't tried building it yet though.
     
    drcfrx and dsilverthorn like this.
  44. C_p_H

    C_p_H

    Joined:
    Nov 24, 2014
    Posts:
    146
    Wow took me longer than expected to get back to yah but here's what I did for 'AudioClip()' updates:
    Clips.Add( null ); //Just open the script, and replace "new AudioClip()" with "null" and you should be golden. :)The issue is, that in 2018, they removed AudioClip's default constructor, which is what Pit is trying to call with the "new AudioClip()" function call. TonanBora

    I've made several other revisions (uncommented) a while ago also, you can compare with your ice_objects_audio script:
    Code (CSharp):
    1. // ##############################################################################
    2. //
    3. // ice_objects_audio.cs | ICE.World.Objects.AudioDataObject | AudioObject | AudioSourceObject
    4. // Version 1.4.0
    5. //
    6. // Copyrights © Pit Vetterick, ICE Technologies Consulting LTD. All Rights Reserved.
    7. // http://www.icecreaturecontrol.com
    8. // mailto:support@icecreaturecontrol.com
    9. //
    10. // Unity Asset Store End User License Agreement (EULA)
    11. // http://unity3d.com/legal/as_terms
    12. //
    13. // ##############################################################################
    14.  
    15. using UnityEngine;
    16. using UnityEngine.Audio;
    17. using System.Xml;
    18. using System.Xml.Serialization;
    19. using System.Collections;
    20. using System.Collections.Generic;
    21.  
    22. using ICE.World;
    23. using ICE.World.Objects;
    24.  
    25. namespace ICE.World.Objects
    26. {
    27.     [System.Serializable]
    28.     public class FootstepAudioPlayerObject : ICEOwnerObject
    29.     {
    30.         public FootstepAudioPlayerObject(){}
    31.         public FootstepAudioPlayerObject( ICEWorldBehaviour _component  ) : base( _component ) {}
    32.         public FootstepAudioPlayerObject( FootstepAudioPlayerObject _audio ) : base( _audio ) { Copy( _audio ); }
    33.  
    34.         private AudioSource m_AudioSource = null;
    35.         public AudioSource Source{
    36.             get{ return m_AudioSource = ( m_AudioSource == null && Owner != null && Application.isPlaying ? Owner.AddComponent<AudioSource>() : m_AudioSource );}
    37.         }
    38.  
    39.         private FootstepAudioDataObject m_AudioData = null;
    40.         public FootstepAudioDataObject AudioData{
    41.             get{ return m_AudioData;}
    42.         }
    43.  
    44.         public void SetData( FootstepAudioDataObject _data )
    45.         {
    46.             m_AudioData = _data;
    47.             Prepare();
    48.         }
    49.  
    50.  
    51.         private float m_IntervalTimer = 0;
    52.         public void Update( float _speed )
    53.         {
    54.             if( Source == null || m_AudioData == null || m_AudioData.Clips.Count == 0 )
    55.                 return;
    56.        
    57.             m_IntervalTimer += Time.deltaTime;
    58.             float _interval = m_AudioData.Interval.Evaluate( _speed );
    59.  
    60.             float EPSILON = 0;
    61.             if ( _interval > 0 && m_IntervalTimer > _interval )
    62.             {
    63.                 PlayOneShot();
    64.                 m_IntervalTimer = 0;
    65.             }
    66.             else if(System.Math.Abs(_interval) < EPSILON && Source != null )
    67.             {
    68.                 Source.Stop();
    69.             }
    70.         }
    71.  
    72.         /// <summary>
    73.         /// Plays the footstep sound.
    74.         /// </summary>
    75.         private void PlayOneShot()
    76.         {
    77.             if( Source == null || m_AudioData == null || m_AudioData.Clips.Count == 0 )
    78.                 return;
    79.  
    80.             if( ! Source.isActiveAndEnabled )
    81.                 return;
    82.        
    83.             Source.clip = m_AudioData.Clips[ Random.Range( 0, m_AudioData.Clips.Count ) ];
    84.             Source.PlayOneShot( Source.clip );
    85.         }
    86.  
    87.         private void Prepare()
    88.         {
    89.             if( Source == null || m_AudioData == null )
    90.                 return;
    91.  
    92.             Source.volume = m_AudioData.Volume;
    93.             Source.pitch = Random.Range( m_AudioData.MinPitch, m_AudioData.MaxPitch ) * Time.timeScale;
    94.             Source.rolloffMode = m_AudioData.RolloffMode;
    95.             Source.minDistance = m_AudioData.MinDistance;
    96.             Source.maxDistance = m_AudioData.MaxDistance;
    97.             Source.spatialBlend = 1.0f;    
    98.             Source.loop = false;
    99.  
    100.             if( m_AudioData.MixerGroup != null )
    101.                 Source.outputAudioMixerGroup = m_AudioData.MixerGroup;
    102.         }
    103.  
    104.     }
    105.    
    106.     [System.Serializable]
    107.     public class FootstepAudioDataObject : ICEDataObject
    108.     {
    109.         public FootstepAudioDataObject(){}
    110.         public FootstepAudioDataObject( FootstepAudioDataObject _audio ) : base( _audio ) { Copy( _audio ); }
    111.  
    112.         public void Copy( FootstepAudioDataObject _audio )
    113.         {
    114.             if( _audio == null )
    115.                 return;
    116.        
    117.             Interval = _audio.Interval;
    118.  
    119.             Enabled = _audio.Enabled;
    120.             Foldout = _audio.Foldout;
    121.             MaxDistance = _audio.MaxDistance;
    122.             MinDistance =_audio.MinDistance;
    123.             DistanceMaximum = _audio.DistanceMaximum;
    124.             MaxPitch = _audio.MaxPitch;
    125.             MinPitch = _audio.MinPitch;
    126.             PitchMaximum = _audio.PitchMaximum;
    127.             RolloffMode = _audio.RolloffMode;
    128.             Volume = _audio.Volume;
    129.             MixerGroup = _audio.MixerGroup;
    130.  
    131.             Clips.Clear();
    132.             foreach( AudioClip _clip in _audio.Clips )
    133.                 Clips.Add( _clip );
    134.         }
    135.  
    136.         [XmlIgnore]
    137.         public List<AudioClip> Clips{
    138.             get{ return m_Clips = ( m_Clips == null ? new List<AudioClip>(): m_Clips );}
    139.         }
    140.  
    141.         [SerializeField]
    142.         protected List<AudioClip> m_Clips = new List<AudioClip>();
    143.  
    144.         public AnimationCurve Interval = new AnimationCurve();
    145.  
    146.         public float Volume = 0.5f;
    147.         public float MinPitch = 1.0f;
    148.         public float MaxPitch = 1.5f;
    149.         public float PitchMaximum = 10;
    150.         public float MinDistance = 2;
    151.         public float MaxDistance = 7;
    152.         public float DistanceMaximum = 7;
    153.         public AudioRolloffMode RolloffMode = AudioRolloffMode.Logarithmic;
    154.  
    155.         [XmlIgnore]
    156.         public AudioMixerGroup MixerGroup = null;
    157.     }
    158.  
    159.  
    160.     [System.Serializable]
    161.     public class FootstepAudioObject : FootstepAudioDataObject
    162.     {
    163.         public FootstepAudioObject(){}
    164.         public FootstepAudioObject( FootstepAudioObject _audio ) : base( _audio as FootstepAudioObject ){}
    165.  
    166.         private AudioClip m_Selected = null;
    167.         [XmlIgnore]
    168.         public AudioClip Selected{
    169.             get{return m_Selected = ( m_Selected == null ? GetNextClip() : m_Selected ); }
    170.         }
    171.  
    172.         public void AddClip( AudioClip _clip )
    173.         {
    174.             if( _clip != null )
    175.                 Clips.Add( _clip );
    176.         }
    177.  
    178.         public void AddClip()
    179.         {
    180.             m_Clips.Add( null );  //Just open the script, and replace "new AudioClip()" with "null" and you should be golden. :) The issue is, that in 2018, they removed AudioClip's default constructor, which is what Pit is trying to call with the "new AudioClip()" function call.  TonanBora
    181.  
    182.         }
    183.  
    184.         public void DeleteClip( int _index )
    185.         {
    186.             if( _index >= 0 && _index < m_Clips.Count )
    187.                 m_Clips.RemoveAt( _index );
    188.         }
    189.  
    190.         public AudioClip GetNextClip()
    191.         {
    192.             if( m_Clips.Count == 0 )
    193.                 return null;
    194.  
    195.             reroll:
    196.             AudioClip _clip = m_Clips[Random.Range(0,m_Clips.Count)];
    197.  
    198.             if( _clip != null )
    199.             {
    200.                 if ( m_Clips.Count > 1 && _clip == m_Selected )
    201.                     goto reroll;
    202.  
    203.                 m_Selected = _clip;
    204.             }
    205.  
    206.             return m_Selected;
    207.         }
    208.     }
    209.    
    210.     [System.Serializable]
    211.     public class AudioDataObject : ICEImpulsTimerObject
    212.     {
    213.         public AudioDataObject(){}
    214.         public AudioDataObject( ICEWorldBehaviour _component ) : base( _component ){}
    215.         public AudioDataObject( AudioDataObject _audio ) : base( _audio as ICEImpulsTimerObject ) { Copy( _audio ); }
    216.  
    217.         public void Copy( AudioObject _audio )
    218.         {
    219.             base.Copy( _audio );
    220.  
    221.             SetImpulseData( _audio );
    222.  
    223.             Enabled = _audio.Enabled;
    224.             Foldout = _audio.Foldout;
    225.             Loop = _audio.Loop;
    226.             Break = _audio.Break;
    227.             StopAtEnd = _audio.StopAtEnd;
    228.             MaxDistance = _audio.MaxDistance;
    229.             MinDistance =_audio.MinDistance;
    230.             DistanceMaximum = _audio.DistanceMaximum;
    231.             MaxPitch = _audio.MaxPitch;
    232.             MinPitch = _audio.MinPitch;
    233.             PitchMaximum = _audio.PitchMaximum;
    234.             RolloffMode = _audio.RolloffMode;
    235.             Volume = _audio.Volume;
    236.             MixerGroup = _audio.MixerGroup;
    237.  
    238.             Clips.Clear();
    239.             foreach( AudioClip _clip in _audio.Clips )
    240.                 Clips.Add( _clip );
    241.         }
    242.  
    243.         [XmlIgnore]
    244.         public List<AudioClip> Clips{
    245.             get{ return m_Clips = ( m_Clips == null ? new List<AudioClip>(): m_Clips );}
    246.         }
    247.  
    248.         [SerializeField]
    249.         protected List<AudioClip> m_Clips = new List<AudioClip>();
    250.  
    251.         public float Volume = 0.5f;
    252.         public float MinPitch = 1.0f;
    253.         public float MaxPitch = 1.5f;
    254.         public float PitchMaximum = 10;
    255.         public float MinDistance = 2;
    256.         public float MaxDistance = 7;
    257.         public float DistanceMaximum = 7;
    258.         public bool Loop = false;
    259.         public bool Break = false;
    260.         public bool StopAtEnd = true;
    261.         public AudioRolloffMode RolloffMode = AudioRolloffMode.Logarithmic;
    262.  
    263.         [XmlIgnore]
    264.         public AudioMixerGroup MixerGroup = null;
    265.     }
    266.  
    267.     [System.Serializable]
    268.     public class AudioObject : AudioDataObject
    269.     {
    270.         public AudioObject(){}
    271.         public AudioObject( ICEWorldBehaviour _component ) : base( _component ){}
    272.         public AudioObject( AudioObject _audio ) : base( _audio as AudioDataObject ){}
    273.  
    274.         private AudioClip m_Selected = null;
    275.         [XmlIgnore]
    276.         public AudioClip Selected{
    277.             get{return m_Selected = ( m_Selected == null ? GetNextClip() : m_Selected ); }
    278.         }
    279.        
    280.         public void AddClip( AudioClip _clip )
    281.         {
    282.             if( _clip != null )
    283.                 Clips.Add( _clip );
    284.         }
    285.  
    286.         public void AddClip()
    287.         {
    288.             m_Clips.Add( null );  //Just open the script, and replace "new AudioClip()" with "null" and you should be golden. :)The issue is, that in 2018, they removed AudioClip's default constructor, which is what Pit is trying to call with the "new AudioClip()" function call.  TonanBora
    289.  
    290.         }
    291.  
    292.         public void DeleteClip( int _index )
    293.         {
    294.             if( _index >= 0 && _index < m_Clips.Count )
    295.                 m_Clips.RemoveAt( _index );
    296.         }
    297.  
    298.         public AudioClip GetNextClip()
    299.         {
    300.             if( m_Clips.Count == 0 )
    301.                 return null;
    302.  
    303.             int _counter = 0;
    304.             reroll:
    305.             AudioClip _clip = m_Clips[Random.Range(0,m_Clips.Count)];
    306.        
    307.             if( _clip != null )
    308.             {
    309.                 _counter++;
    310.                 if( m_Clips.Count > 1 && _clip == m_Selected && _counter < 5 )
    311.                     goto reroll;
    312.  
    313.                 m_Selected = _clip;
    314.             }
    315.  
    316.             return m_Selected;
    317.         }
    318.     }
    319.  
    320.     [System.Serializable]
    321.     public class AudioPlayerObject : ICEImpulsTimerObject
    322.     {
    323.         public AudioPlayerObject(){}
    324.         public AudioPlayerObject(ICEWorldBehaviour _component) : base(_component) => Init(_component);
    325.  
    326.         private AudioSource m_AudioSource = null;
    327.         public AudioSource Source{
    328.             get{ return m_AudioSource = ( m_AudioSource == null && Owner != null && Application.isPlaying ? Owner.AddComponent<AudioSource>() : m_AudioSource );}
    329.         }
    330.  
    331.         public AudioClip CurrentClip{
    332.             get{ return ( Source != null ? Source.clip:null ); }
    333.         }
    334.  
    335.         public override void Init( ICEWorldBehaviour _component )
    336.         {
    337.             base.Init( _component );
    338.        
    339.             if( Source != null )
    340.             {
    341.                 Source.rolloffMode = AudioRolloffMode.Logarithmic;
    342.                 Source.volume = 0.5f;
    343.                 Source.pitch = 1f;
    344.                 Source.minDistance = 10f;
    345.                 Source.maxDistance = 100f;
    346.                 Source.spatialBlend = 1f;
    347.             }
    348.         }
    349.  
    350.         private AudioObject m_AudioData = null;
    351.  
    352.         private void Prepare( AudioObject _data )
    353.         {
    354.             if( Source == null || ! _data.Enabled || ! _data.Selected  )
    355.                 return;
    356.  
    357.             Source.clip = _data.Selected;            
    358.             Source.volume = _data.Volume;
    359.             Source.pitch = Random.Range( _data.MinPitch, _data.MaxPitch) * Time.timeScale;
    360.             Source.rolloffMode = _data.RolloffMode;
    361.             Source.minDistance = _data.MinDistance;
    362.             Source.maxDistance = _data.MaxDistance;
    363.             Source.spatialBlend = 1.0f;    
    364.             Source.loop = _data.Loop;
    365.  
    366.             if( _data.MixerGroup != null )
    367.                 Source.outputAudioMixerGroup = _data.MixerGroup;
    368.         }
    369.  
    370.         public void PlayLoop( AudioObject _data )
    371.         {
    372.             if( Source == null )
    373.                 return;
    374.  
    375.             if( _data != null && _data.Enabled && _data.GetNextClip() != null )
    376.             {
    377.                 if( Source.isPlaying )
    378.                 {
    379.                     if( _data.Break )
    380.                         Source.Stop();
    381.                     else
    382.                         return;
    383.                 }
    384.  
    385.                 Prepare( _data );
    386.                 Source.Play();
    387.             }
    388.             else if ( m_AudioData == null || m_AudioData.StopAtEnd )
    389.                 Stop();
    390.         }
    391.  
    392.         public void PlayOneShot( AudioObject _data )
    393.         {
    394.             if( Source == null )
    395.                 return;
    396.  
    397.             if( _data != null && _data.Enabled && _data.GetNextClip() != null )
    398.             {
    399.                 if( Source.isPlaying )
    400.                 {
    401.                     if( _data.Break )
    402.                         Source.Stop();
    403.                     else
    404.                         return;
    405.                 }
    406.  
    407.                 Prepare( _data );            
    408.                 Source.PlayOneShot( _data.Selected );
    409.             }
    410.             else if ( m_AudioData == null || m_AudioData.StopAtEnd )
    411.                 Stop();
    412.         }
    413.  
    414.         public void Play( AudioObject _data )
    415.         {
    416.             if( Source == null )
    417.                 return;
    418.  
    419.             if( _data != null && _data.Enabled && _data.GetNextClip() != null )
    420.             {
    421.                 if( m_AudioData != _data || Source.clip == null || Source.clip.name != _data.Selected.name )
    422.                 {
    423.                     m_AudioData = _data;
    424.                     SetImpulseData( m_AudioData );
    425.                     base.Start();
    426.  
    427.                     if( DebugLogIsEnabled ) PrintDebugLog( this, "Play - " + m_AudioData.Selected.name );
    428.                 }
    429.             }
    430.             else if ( m_AudioData == null || m_AudioData.StopAtEnd )
    431.                 Stop();
    432.         }
    433.  
    434.         /// <summary>
    435.         /// Stop the audio playback and the impulse timer
    436.         /// </summary>
    437.         public override void Stop()
    438.         {
    439.             base.Stop();
    440.  
    441.             m_AudioData = null;
    442.             if( Source != null )
    443.             {
    444.                 Source.Stop();
    445.                 Source.clip = null;
    446.             }
    447.         }
    448.  
    449.         /// <summary>
    450.         /// Runs the action method according to the given impulse settings
    451.         /// </summary>
    452.         protected override void Action()
    453.         {
    454.             if( m_AudioData == null || ! m_AudioData.Enabled || m_AudioData.Selected == null )
    455.                 return;
    456.        
    457.             if( m_AudioData.Loop )
    458.                 PlayLoop( m_AudioData );
    459.             else
    460.                 PlayOneShot( m_AudioData );
    461.         }
    462.     }
    463.    
    464.     [System.Serializable]
    465.     public class DirectAudioDataObject : ICEOwnerObject
    466.     {
    467.         public DirectAudioDataObject(){}
    468.         public DirectAudioDataObject( ICEWorldBehaviour _component  ) : base( _component ) { Init( _component ); }
    469.         public DirectAudioDataObject( ICEWorldBehaviour _component, DirectAudioDataObject _audio ) : base( _component ) { Copy( _audio ); }
    470.         public DirectAudioDataObject( DirectAudioDataObject _audio ) { Copy( _audio ); }
    471.  
    472.         [SerializeField]
    473.         private List<AudioClip> m_Clips = null;
    474.  
    475.         [XmlIgnore]
    476.         public List<AudioClip> Clips{
    477.             get{ return m_Clips = ( m_Clips == null ? new List<AudioClip>() : m_Clips );}
    478.         }
    479.  
    480.         public float Volume = 0.5f;
    481.         public float MinPitch = 1.0f;
    482.         public float MaxPitch = 1.5f;
    483.         public float PitchMaximum = 10;
    484.         public float MinDistance = 2;
    485.         public float MaxDistance = 7;
    486.         public float DistanceMaximum = 7;
    487.         public bool Loop = false;
    488.         public bool Break = false;
    489.         public AudioRolloffMode RolloffMode = AudioRolloffMode.Logarithmic;
    490.  
    491.         public AudioMixerGroup MixerGroup = null;
    492.  
    493.         public void Copy( DirectAudioDataObject _audio )
    494.         {
    495.             if( _audio == null )
    496.                 return;
    497.  
    498.             Enabled = _audio.Enabled;
    499.             Foldout = _audio.Foldout;
    500.             Loop = _audio.Loop;
    501.             Break = _audio.Break;
    502.             MaxDistance = _audio.MaxDistance;
    503.             MinDistance =_audio.MinDistance;
    504.             DistanceMaximum = _audio.DistanceMaximum;
    505.             MaxPitch = _audio.MaxPitch;
    506.             MinPitch = _audio.MinPitch;
    507.             PitchMaximum = _audio.PitchMaximum;
    508.             RolloffMode = _audio.RolloffMode;
    509.             Volume = _audio.Volume;
    510.             MixerGroup = _audio.MixerGroup;
    511.  
    512.             Clips.Clear();
    513.             foreach( AudioClip _clip in _audio.Clips )
    514.                 Clips.Add( _clip );
    515.         }
    516.     }
    517.  
    518.     [System.Serializable]
    519.     public class DirectAudioObject : DirectAudioDataObject
    520.     {
    521.         public DirectAudioObject(){}
    522.         public DirectAudioObject( ICEWorldBehaviour _component  ) : base( _component ) { Init( _component ); }
    523.         public DirectAudioObject( ICEWorldBehaviour _component, DirectAudioDataObject _audio ) : base( _component, _audio ) {}
    524.         public DirectAudioObject( DirectAudioDataObject _audio ) : base( _audio )  {}
    525.  
    526.  
    527.         private AudioClip m_Selected = null;
    528.         [XmlIgnore]
    529.         public AudioClip Selected{
    530.             get{return m_Selected = ( m_Selected == null ? GetNextClip() : m_Selected ); }
    531.         }
    532.  
    533.         public void AddClip( AudioClip _clip )
    534.         {
    535.             if( _clip != null )
    536.                 Clips.Add( _clip );
    537.         }
    538.    
    539.         public void AddClip()
    540.         {
    541.             Clips.Add( null );  //Just open the script, and replace "new AudioClip()" with "null" and you should be golden. :)The issue is, that in 2018, they removed AudioClip's default constructor, which is what Pit is trying to call with the "new AudioClip()" function call.  TonanBora
    542.  
    543.         }
    544.  
    545.         public void DeleteClip( int _index )
    546.         {
    547.             if( _index >= 0 && _index < Clips.Count )
    548.                 Clips.RemoveAt( _index );
    549.         }
    550.  
    551.         public AudioClip GetNextClip()
    552.         {
    553.             if( Clips.Count == 0 )
    554.                 return null;
    555.  
    556.             reroll:
    557.             AudioClip _clip = Clips[Random.Range(0,Clips.Count)];
    558.  
    559.             if( _clip != null )
    560.             {
    561.                 if ( Clips.Count > 1 && _clip == m_Selected )
    562.                     goto reroll;
    563.  
    564.                 m_Selected = _clip;
    565.             }
    566.  
    567.             return m_Selected;
    568.         }
    569.     }
    570.  
    571.     [System.Serializable]
    572.     public class DirectAudioPlayerObject : DirectAudioObject
    573.     {
    574.         public DirectAudioPlayerObject(){}
    575.         public DirectAudioPlayerObject(ICEWorldBehaviour _component) : base(_component) => Init(_component);
    576.         public DirectAudioPlayerObject(ICEWorldBehaviour _component, DirectAudioDataObject _audio) : base(_component, _audio) => Init(_component);
    577.         public DirectAudioPlayerObject( DirectAudioDataObject _audio ) : base( _audio )  {}
    578.  
    579.         private AudioSource m_AudioSource = null;
    580.         public AudioSource Source{
    581.             get{ return m_AudioSource = ( m_AudioSource == null && Owner != null && Application.isPlaying ? Owner.AddComponent<AudioSource>() : m_AudioSource );}
    582.         }
    583.  
    584.  
    585.  
    586.         public override void Init( ICEWorldBehaviour _component )
    587.         {
    588.             base.Init( _component );
    589.  
    590.             Prepare();
    591.         }
    592.  
    593.         public AudioClip CurrentClip{
    594.             get{ return ( Source != null ? Source.clip:null ); }
    595.         }
    596.  
    597.         public void Play( ICEWorldBehaviour _component )
    598.         {
    599.             base.Init( _component );
    600.             Play();
    601.         }
    602.  
    603.         public void Play()
    604.         {
    605.             if( Owner == null || ! Owner.activeInHierarchy || Source == null || ! Source.enabled )
    606.                 return;
    607.  
    608.             if( Enabled && GetNextClip() != null )
    609.             {
    610.                 if( Source.isPlaying )
    611.                 {
    612.                     // if the source is playing a single shot or the selected sound is already running and break is false then we will return,
    613.                     // otherwise we will stop the current sound
    614.                     if( ( ! Loop || ( Source.clip != null && Source.clip.name == Selected.name ) ) && ! Break )
    615.                         return;
    616.  
    617.                     Stop();
    618.                 }
    619.  
    620.                 if( Prepare() )
    621.                 {
    622.                     if( Loop )
    623.                         Source.Play();
    624.                     else
    625.                         Source.PlayOneShot( Selected );
    626.  
    627.                     if( DebugLogIsEnabled ) PrintDebugLog( this, "Play - " + Selected.name );
    628.                 }
    629.             }
    630.             else
    631.                 Stop();
    632.         }
    633.  
    634.         public void Stop()
    635.         {
    636.             if( Source == null )
    637.                 return;
    638.  
    639.             Source.Stop();
    640.             Source.clip = null;
    641.         }
    642.  
    643.         private bool Prepare()
    644.         {
    645.             if( Owner == null || ! Owner.activeInHierarchy || Source == null || ! Source.enabled )
    646.                 return false;
    647.  
    648.             if( Selected != null )
    649.             {
    650.                 Source.playOnAwake = false;
    651.                 Source.clip = Selected;            
    652.                 Source.volume = Volume;
    653.                 Source.pitch = Random.Range( MinPitch, MaxPitch) * Time.timeScale;
    654.                 Source.rolloffMode = RolloffMode;
    655.                 Source.minDistance = MinDistance;
    656.                 Source.maxDistance = MaxDistance;
    657.                 Source.spatialBlend = 1.0f;    
    658.                 Source.loop = Loop;
    659.  
    660.                 if( MixerGroup != null )
    661.                     Source.outputAudioMixerGroup = MixerGroup;
    662.    
    663.                 return true;
    664.             }
    665.             else
    666.             {
    667.                 Source.clip = null;
    668.                 Source.rolloffMode = AudioRolloffMode.Logarithmic;
    669.                 Source.volume = 0.5f;
    670.                 Source.pitch = 1f;
    671.                 Source.minDistance = 10f;
    672.                 Source.maxDistance = 100f;
    673.                 Source.spatialBlend = 1f;
    674.                 Source.loop = false;
    675.                 return false;
    676.             }
    677.         }
    678.     }
    679.  
    680.  
    681. }
    682.  
     
    Last edited: May 4, 2019
    dsilverthorn and jonfinlay like this.
  45. zenGarden

    zenGarden

    Joined:
    Mar 30, 2013
    Posts:
    4,538
    Well it is like factions with behavior, using some parameters it's not that hard to make some behavior with some random variations depending on situation.
    The plugin had many issues, i worked on some bugs, but there was always some issues for example like pooling or culling, so i just moved to better Ai plugin when the plugin was still very popular, another ai plugin with less options but working as expected for some simple AI, with better documentaion and more tutorials.


    I agree, it would be better to make some node based editable ai, with small ai modules you could connect.
    For example some detect module, another named melee attack, this mixed with some general parameters for behaviours and sort of faction.

    Something could be FSM or BT with many pre made actions and other functions ready to use and combine.
    There is NodeCanvas, Eliot or Invector FSM, but those lack pre made packages for different type of game AI.
    Most non coders are not able t ocreate theor own FSM or BT actions.
    For example they could have pre made ai package to make some fps game , another package specific for tps cover games, a package for melee games, another package for creatures.
    I think this is what expect most people that don't code.
     
    Last edited: May 4, 2019
  46. jonfinlay

    jonfinlay

    Joined:
    Aug 25, 2015
    Posts:
    535
    Thank you very much! Much appreciated :)
     
  47. Jacky_Boy

    Jacky_Boy

    Joined:
    Dec 8, 2013
    Posts:
    93
    Just checking in here after a year or so..can't remember how long. How are my old comrades doing? @Tethys @zenGarden @Gregorik et al I hope you are all well. I was sad to hear ICE got deprecated but not surprised. I saw this coming when Pit had his accident though; that's why I dropped it from my project and decided to code AI on my own. A year later all I can say it was worth the grind.
    Soon I will post some new updates to my game (using GOAP AI). Being able to change things on the fly and watch my AI learn and even outsmart me at times is so funny to witness. For those who are on the fence, go learn to code your AI. Start small, even if your NPCs can't tell the difference between a wall and the player that's a start. It's just not an easy thing to deal with investing your time learning a developer's asset and have them drop it and leave you hanging. Nothing against Pit I'm sure more important life matters came up.
    I just wanted to cheer you guys up a bit(those who need cheering up anyways). I have a family, full time job and a farm and I make time to code (coming from a science background I had no idea how to even start). I was working as a Scientist and got bored (all day in the lab I was just thinking about coding lol). Thanks partially to ICE and Pit I got the courage to go out there and learn AI coding because I got desperate to finish my game and tired of waiting for "the next update." When my wife started ridiculing me about "finishing the game" I knew I needed to be proactive. I just channeled my desperation and jumped into the cold C# and A.I water. I hope this encourages those who are thinking of jumping in but feel intimidated. Coding itself isn't that difficult, it's more about application. Take care guys
     
  48. Tethys

    Tethys

    Joined:
    Jul 2, 2012
    Posts:
    662
    I finally pulled the trigger and moved over to Opsives Behaviour Trees and UCC. Liking it so far.
     
  49. dsilverthorn

    dsilverthorn

    Joined:
    May 14, 2017
    Posts:
    313
    Keep us up to date on how that goes:)
    I looked at that pretty hard, but didn’t want to spend the money and am sticking with ICE at least until this project is done.
     
  50. Jacky_Boy

    Jacky_Boy

    Joined:
    Dec 8, 2013
    Posts:
    93
    I used Opsive's Behavior Designer for a while as well. I don't have any complaints about it except every time there's an update it was a pain (if you happened to update the source code) because they went to the extreme to protect everything with wrappers etc. You still need a good understanding of programming concepts to utilize the nodes though, but they help out by giving example trees with projects. I definitely recommend that asset if you want flexible AI and prefer not to learn coding. Once you get familiar with BD you can do similar things like ICE, maybe more. Good luck @Tethys
     
    Tethys and dsilverthorn like this.