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

Scripting a Monster

Discussion in 'Scripting' started by Mattathis, Apr 3, 2012.

  1. Mattathis

    Mattathis

    Joined:
    Apr 3, 2012
    Posts:
    8
    Hey people,

    This is my first time posting so I hope it will all make sense!

    I'm making a puzzle in which the controller has to go past a monster. The idea is that when you get to close the monster attacks you and you have to start over. To defeat the monster you have to destroy two objects (plants) and the monster will run away.

    My plan was to put three cubes in front of the beast: monsterattack#1, monsterattack#2 and monsterflees.
    The two first cubes are connected to each one of the plants. So when you destroy plant one, you also destroy the first cube. Destroy plant two and you destroy cube 2.

    So this is what you should get:
    If you don't destroy any plants you walk into cube 1 and the monster attacks you.
    If you destroy one of the two plants one of the two first cubes will still be there so the monster will still attack you.
    Destroy both plants and walk into the third cube, which makes the monster run away so you can move on.

    I hope that made any sense, if not feel free to ask!

    My problems:
    I want to script that when I'm close to plant 1 and press 'e' only that one gets destroyed (and the cube 1 as well). Same with the other plant.
    If someone could help me with that I would be soooooo happy, haha.

    The beast has three animations, standing, walking and running. The idea was that when I touch the first or second cube the monster walks to me, so he has to have a animation were it moves to me and it has to have his walking cycle.

    And at last when you touch the third cube the monster runs into the forest, using his running cycle.



    I'm a student and this is my second time scripting so I'm a newbie, if you could help with any of the things above then that would be great!

    Hope to hear from someone soon.
     
  2. Tobias J.

    Tobias J.

    Joined:
    Feb 21, 2012
    Posts:
    423
    Do you know how to instantiate and destroy GameObjects?

    Do you know how to get a handle on script B from script A?

    Do you know how to detect collisions?

    If so, you have all the necessary knowledge to make this work.

    If not, do as much as you can, post your code and let us know what specific problem you have.

    Oh, and welcome! :)
     
  3. Mattathis

    Mattathis

    Joined:
    Apr 3, 2012
    Posts:
    8
    Well my teaching gave us a demo from a game he made and I took some scripts out of that.

    I have a Trigger Script:


    using UnityEngine;
    using System.Collections;
    using System.Collections.Generic;

    // Object that gets activated and then changes something
    public class Trigger : MonoBehaviour {

    public List<Actor> actors = new List<Actor>();
    public List<int> actModes = new List<int>();

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }

    // Trigger all actors
    public void trigger(List<int> modes)
    {
    for (int i = 0; i < actors.Count i < modes.Count; i++)
    {
    actors.Act(modes);
    }
    }
    }



    A Press Button Script:


    using UnityEngine;
    using System.Collections;

    // Button script. Does nothing, but PressCheck.cs can find objects with these scripts. Is a trigger, meaning it can trigger stuff
    public class PressButton : Trigger {

    public int numPresses = -1;

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
    }


    And a simple destroy Script:

    Destroy (gameObject);







    In my first try I made a script that destroyed everything with that script on it, no matter what distance, so that didn't work.
    I know how to make an animation script for the monster and how to attach it to it without having to delete the stand animation.

    So the first thing I need is that I walk to the plant, my cursor is pointed to it and when I press 'e' it destroys the plant and the cube.
    But I have little knowledge about the scripts I got.

    Haha hope this helps you understand a bit more!
     
  4. Tobias J.

    Tobias J.

    Joined:
    Feb 21, 2012
    Posts:
    423
    Try this. Put it on the object that is to be destroyed.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4. class Test : MonoBehaviour
    5. {
    6.     private bool canDestruct = false;
    7.  
    8.     void OnMouseEnter()
    9.     {
    10.         canDestruct = true;
    11.     }
    12.  
    13.     void OnMouseExit()
    14.     {
    15.         canDestruct = false;
    16.     }
    17.  
    18.     void Update()
    19.     {
    20.         if (canDestruct  Input.GetKeyUp(KeyCode.E))
    21.             Destroy(gameObject);
    22.     }
    23. }
    24.  
    Disclaimer: untested code.
     
  5. Mattathis

    Mattathis

    Joined:
    Apr 3, 2012
    Posts:
    8
    Copied that in a Javascript and got 5 errors,

    Cleaned it up and got 2 left that I don't know how to fix:

    using ; UnityEngine;



    class Test : MonoBehaviour;



    private canDestruct = false;



    void OnMouseEnter()

    {

    canDestruct = true;

    }



    void OnMouseExit()

    {

    canDestruct = false;

    }



    void Update()

    {

    if (canDestruct Input.GetKeyUp(KeyCode.E))

    Destroy(gameObject);

    }





    Both are unexpected tokens.

    Really appreciate the help!:)
     
  6. DayyanSisson

    DayyanSisson

    Joined:
    Aug 4, 2011
    Posts:
    623
    Yeah, that's because the script was written in C#, not JavaScript. Just copy and paste that into a C# script file.
     
  7. Mattathis

    Mattathis

    Joined:
    Apr 3, 2012
    Posts:
    8
    Ah I see,

    Well no errors this time but nothing happens either.
    Put the C# script on the plant, standing as close as possible with cursor on it and pressing E has no effect:(
     
  8. Tobias J.

    Tobias J.

    Joined:
    Feb 21, 2012
    Posts:
    423
    hm. Well, I haven't worked with keyboard input as of yet, but perhaps you're pressing Shift+e, which might not work?

    Sorry I can't be of more help here.
     
  9. by0log1c

    by0log1c

    Joined:
    Jan 30, 2011
    Posts:
    40
    Well I read your initial post and felt inspired so I gave it a shot. I end up with 200 lines of clean, commented but untested code that cover the basic monster AI and the player attack. I've written it in JS so you can better understand what's going on.

    Use them as-is if they work, or inspire yourself/learn some stuff from them. I've threw them in a PasteBin for a month. Both scripts are crude, simple, untested and possibly useless, but it could help you get started with the flow or whatever :rolleyes:.

    Enough babbling, here be code:

    MonsterScript.js that handle the monster behaviour and wait for call to Fight() or Flee().
    PlayerAttackScript.js that detect collision with plants, find a target, handle attacks and update the monster behaviour.
     
  10. Mattathis

    Mattathis

    Joined:
    Apr 3, 2012
    Posts:
    8
    I tried it out, the script looks great. I got my three animations in (Stand, Run and Walk)
    And the beast now plays the Stand animation while looking at me the whole time.
    In the script I can put in my two plants but I can't find their actions in the script.
    I don't really understand how to call the fight mode, I need it to call fight mode when I get close and the plants are still there and the flee mode when I destroyed both plants.

    Could you explain this a bit so I am ably to change it myself?
     
  11. Mattathis

    Mattathis

    Joined:
    Apr 3, 2012
    Posts:
    8
    @Tobias J.
    Too bad it isn't working but thank you so much for helping, I learned some things from your script and got an idea how to approach it so thanks!
     
  12. by0log1c

    by0log1c

    Joined:
    Jan 30, 2011
    Posts:
    40
    Alright, I'll explain a little how I expect the scripts to work.

    SETUP
    • Add MonsterScript to the monster.
    • Link the player to MonsterScript.
    • Add a SphereCollider to the player. Make it a trigger.
    • Add your own movement script to the player.
    • Add PlayerAttackScript to the player.
    • Link the monster and every plant to PlayerAttackScript.

    USAGE
    • MonsterScript is autonomous. It will execute the last action you ask him to.
    • PlayerAttackScript will mark the last plant to enter its trigger at the current target.
    • Attacking will destroy the plant GameObject, no animation, no effect, nothing except...
    • ...that every plant destroyed cause PlayerAttackScript to call UpdateMonster().
    • UpdateMonster() checks the whole array to see if it finds a remaining plant object.
    • If there is one left, PlayerAttackScript calls Fight() on the monster.
    • If there are none left, PlayerAttackScript calls Flee() on the monster.

    At every frame, MonsterScript will end up in one of the 4 methods Idle(), Chase(), Attack() or Flee(), consider them an Update() for specific behaviour.

    As for 'calling Fight() or Flee()', PlayerAttackScript actually does it for you. Line #36 retrieves and cache the monster's MonsterScript so we can call its public functions, which PlayerAttackScript also does in the UpdateMonster() function.

    To have the monster attack when you get close to the plant, rather than when you destroy one, just move the monsterScript.Fight() line into the OnTriggerEnter().
     
  13. Mattathis

    Mattathis

    Joined:
    Apr 3, 2012
    Posts:
    8
    I feel like my brain is exploding haha

    The only thing that works is that the monster keeps looking at me while locked in place.
    I put the sphere on my first person controller and made it a trigger.
    I changed the animation named from the monster script into the named of my three animations.
    But I can't destroy the plants, do they need a destroy script as well?
    I walk towards them, press 'e' and nothing happens.

    So basically I did everything you said but nothing works though I kind of get how it should work.

    Sorry if I'm coming over a bit slow, I'm new hah

    Really appreciate the help though!
     
  14. by0log1c

    by0log1c

    Joined:
    Jan 30, 2011
    Posts:
    40
    For debugging purpose, make the variable collidingPlant from PlayerAttackScript public instead of private, it'll allow you to see the player's current target. I've made it private so you don't set it manually, the variable should fill itself when you get close to a plant. I've made a few little changes on the PasteBins, you might want to grab them again.

    -does your player have a large sphere collider set as trigger?
    -does your plants have collider as collider on them?
    -are your plants linked in the PlayerAttackScript inspector?
    -does collidingPlant fill itself when a plant enter the collider?

    If collidingPlant stays empty when a plant enters the player's sphere collider, the problem's there. You can test the attack and flee by manually dragging a plant into collidingPlant in the inspector and then attacking. The plant should be destroyed and the monster awoken until you've destroyed all plants then the monster should flee.

    If you're still having trouble, add some Debug.Log("my debug text") in most functions to see what works and what doesn't.
     
    Last edited: Apr 5, 2012
  15. Mattathis

    Mattathis

    Joined:
    Apr 3, 2012
    Posts:
    8
    I just made it public. And when I come close to the plant it does show in the collidingPlant
    But when I put one of the plants in it, I can destroy the with 'e'. But of coarse it doesn't matter where I am at that moment since the sphere has nothing to do with it if I manually put the plant in.
    Another problem is that the beast attacks me, no matter what range I put in. So when I destroy one plant, it immediately comes after me.
    The different animations do work which makes me really happy!

    And to answer your questions:
    Yes, my player has a large sphere collider set as trigger.
    My plants have colliders.
    The plants are linked in both scripts.
    No, the collidingPlant doesn't fill itself.

    I'm grateful for your help and feel like we're almost there! Haha
     
  16. by0log1c

    by0log1c

    Joined:
    Jan 30, 2011
    Posts:
    40
    Its not clear if the collision works or not, I'll guess not. About the monster constantly attacking you, I believe its the normal behaviour. The attackRange does not determine the range at which the monster chase you but rather the range at which it'll stop chasing you and start attacking. It'll start chasing you as soon as you destroy the first plant, PlayerAttackScript calls Attack() then UpdateMonster() which should call Fight() on the monster.

    I cannot do much more as the scripts are fairly simple, commented and I've given you tips on how they work and how to debug them. At this point you're better equipped than me as I'm just guessing stuff.