Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Free Arm Studios · Oct 04, 2015 at 09:24 PM · 2dplayercomponenttutorialsroguelike

Modifying the 2D Roguelike Player Script to Expect Other Objects

I used the Unity 2D Roguelike tutorials to make my player interact with the environment, and I'm at a point where I'd like to have the player take in other T's than just a Wall (see the call of "AttemptMove" below). I'm not very familiar with the use of T components. I'd like the player to also be able to expect to be hindered by an enemy, a door, or a chest. Sorry if this sounds extremely newbie-ish.

This is the player script from the tutorial itself:

 using UnityEngine;
 using System.Collections;
 
 namespace Completed
 {
     //Player inherits from MovingObject, our base class for objects that can move, Enemy also inherits from this.
     public class Player : MovingObject
     {
         public float restartLevelDelay = 1f;        //Delay time in seconds to restart level.
         public int pointsPerFood = 10;              //Number of points to add to player food points when picking up a food object.
         public int pointsPerSoda = 20;              //Number of points to add to player food points when picking up a soda object.
         public int wallDamage = 1;                  //How much damage a player does to a wall when chopping it.
         
         
         private Animator animator;                  //Used to store a reference to the Player's animator component.
         private int food;                           //Used to store player food points total during level.
         
         
         //Start overrides the Start function of MovingObject
         protected override void Start ()
         {
             //Get a component reference to the Player's animator component
             animator = GetComponent<Animator>();
             
             //Get the current food point total stored in GameManager.instance between levels.
             food = GameManager.instance.playerFoodPoints;
             
             //Call the Start function of the MovingObject base class.
             base.Start ();
         }
         
         
         //This function is called when the behaviour becomes disabled or inactive.
         private void OnDisable ()
         {
             //When Player object is disabled, store the current local food total in the GameManager so it can be re-loaded in next level.
             GameManager.instance.playerFoodPoints = food;
         }
         
         
         private void Update ()
         {
             //If it's not the player's turn, exit the function.
             if(!GameManager.instance.playersTurn) return;
             
             int horizontal = 0;     //Used to store the horizontal move direction.
             int vertical = 0;       //Used to store the vertical move direction.
             
             
             //Get input from the input manager, round it to an integer and store in horizontal to set x axis move direction
             horizontal = (int) (Input.GetAxisRaw ("Horizontal"));
             
             //Get input from the input manager, round it to an integer and store in vertical to set y axis move direction
             vertical = (int) (Input.GetAxisRaw ("Vertical"));
             
             //Check if moving horizontally, if so set vertical to zero.
             if(horizontal != 0)
             {
                 vertical = 0;
             }
             
             //Check if we have a non-zero value for horizontal or vertical
             if(horizontal != 0 || vertical != 0)
             {
                 //Call AttemptMove passing in the generic parameter Wall, since that is what Player may interact with if they encounter one (by attacking it)
                 //Pass in horizontal and vertical as parameters to specify the direction to move Player in.
                 AttemptMove<Wall> (horizontal, vertical);
             }
         }
         
         //AttemptMove overrides the AttemptMove function in the base class MovingObject
         //AttemptMove takes a generic parameter T which for Player will be of the type Wall, it also takes integers for x and y direction to move in.
         protected override void AttemptMove <T> (int xDir, int yDir)
         {
             //Every time player moves, subtract from food points total.
             food--;
             
             //Call the AttemptMove method of the base class, passing in the component T (in this case Wall) and x and y direction to move.
             base.AttemptMove <T> (xDir, yDir);
             
             //Hit allows us to reference the result of the Linecast done in Move.
             RaycastHit2D hit;
             
             //If Move returns true, meaning Player was able to move into an empty space.
             if (Move (xDir, yDir, out hit)) 
             {
                 //Call RandomizeSfx of SoundManager to play the move sound, passing in two audio clips to choose from.
             }
             
             //Since the player has moved and lost food points, check if the game has ended.
             CheckIfGameOver ();
             
             //Set the playersTurn boolean of GameManager to false now that players turn is over.
             GameManager.instance.playersTurn = false;
         }
         
         
         //OnCantMove overrides the abstract function OnCantMove in MovingObject.
         //It takes a generic parameter T which in the case of Player is a Wall which the player can attack and destroy.
         protected override void OnCantMove <T> (T component)
         {
             //Set hitWall to equal the component passed in as a parameter.
             Wall hitWall = component as Wall;
             
             //Call the DamageWall function of the Wall we are hitting.
             hitWall.DamageWall (wallDamage);
             
             //Set the attack trigger of the player's animation controller in order to play the player's attack animation.
             animator.SetTrigger ("playerChop");
         }
         
         
         //OnTriggerEnter2D is sent when another object enters a trigger collider attached to this object (2D physics only).
         private void OnTriggerEnter2D (Collider2D other)
         {
             //Check if the tag of the trigger collided with is Exit.
             if(other.tag == "Exit")
             {
                 //Invoke the Restart function to start the next level with a delay of restartLevelDelay (default 1 second).
                 Invoke ("Restart", restartLevelDelay);
                 
                 //Disable the player object since level is over.
                 enabled = false;
             }
             
             //Check if the tag of the trigger collided with is Food.
             else if(other.tag == "Food")
             {
                 //Add pointsPerFood to the players current food total.
                 food += pointsPerFood;
                 
                 //Disable the food object the player collided with.
                 other.gameObject.SetActive (false);
             }
             
             //Check if the tag of the trigger collided with is Soda.
             else if(other.tag == "Soda")
             {
                 //Add pointsPerSoda to players food points total
                 food += pointsPerSoda;
                 
                 
                 //Disable the soda object the player collided with.
                 other.gameObject.SetActive (false);
             }
         }
         
         
         //Restart reloads the scene when called.
         private void Restart ()
         {
             //Load the last scene loaded, in this case Main, the only scene in the game.
             Application.LoadLevel (Application.loadedLevel);
         }
         
         
         //LoseFood is called when an enemy attacks the player.
         //It takes a parameter loss which specifies how many points to lose.
         public void LoseFood (int loss)
         {
             //Set the trigger for the player animator to transition to the playerHit animation.
             animator.SetTrigger ("playerHit");
             
             //Subtract lost food points from the players total.
             food -= loss;
             
             //Check to see if game has ended.
             CheckIfGameOver ();
         }
         
         
         //CheckIfGameOver checks if the player is out of food points and if so, ends the game.
         private void CheckIfGameOver ()
         {
             //Check if food point total is less than or equal to zero.
             if (food <= 0) 
             {
                 
                 //Call the GameOver function of GameManager.
                 GameManager.instance.GameOver ();
             }
         }
     }
 }

This is the MovingObject script it depends on:

 using UnityEngine;
 using System.Collections;
 
 namespace Completed
 {
     //The abstract keyword enables you to create classes and class members that are incomplete and must be implemented in a derived class.
     public abstract class MovingObject : MonoBehaviour
     {
         public float moveTime = 0.1f;           //Time it will take object to move, in seconds.
         public LayerMask blockingLayer;         //Layer on which collision will be checked.
         
         
         private BoxCollider2D boxCollider;      //The BoxCollider2D component attached to this object.
         private Rigidbody2D rb2D;               //The Rigidbody2D component attached to this object.
         private float inverseMoveTime;          //Used to make movement more efficient.
         
         
         //Protected, virtual functions can be overridden by inheriting classes.
         protected virtual void Start ()
         {
             //Get a component reference to this object's BoxCollider2D
             boxCollider = GetComponent <BoxCollider2D> ();
             
             //Get a component reference to this object's Rigidbody2D
             rb2D = GetComponent <Rigidbody2D> ();
             
             //By storing the reciprocal of the move time we can use it by multiplying instead of dividing, this is more efficient.
             inverseMoveTime = 1f / moveTime;
         }
         
         
         //Move returns true if it is able to move and false if not. 
         //Move takes parameters for x direction, y direction and a RaycastHit2D to check collision.
         protected bool Move (int xDir, int yDir, out RaycastHit2D hit)
         {
             //Store start position to move from, based on objects current transform position.
             Vector2 start = transform.position;
             
             // Calculate end position based on the direction parameters passed in when calling Move.
             Vector2 end = start + new Vector2 (xDir, yDir);
             
             //Disable the boxCollider so that linecast doesn't hit this object's own collider.
             boxCollider.enabled = false;
             
             //Cast a line from start point to end point checking collision on blockingLayer.
             hit = Physics2D.Linecast (start, end, blockingLayer);
             
             //Re-enable boxCollider after linecast
             boxCollider.enabled = true;
             
             //Check if anything was hit
             if(hit.transform == null)
             {
                 //If nothing was hit, start SmoothMovement co-routine passing in the Vector2 end as destination
                 StartCoroutine (SmoothMovement (end));
                 
                 //Return true to say that Move was successful
                 return true;
             }
             
             //If something was hit, return false, Move was unsuccesful.
             return false;
         }
         
         
         //Co-routine for moving units from one space to next, takes a parameter end to specify where to move to.
         protected IEnumerator SmoothMovement (Vector3 end)
         {
             //Calculate the remaining distance to move based on the square magnitude of the difference between current position and end parameter. 
             //Square magnitude is used instead of magnitude because it's computationally cheaper.
             float sqrRemainingDistance = (transform.position - end).sqrMagnitude;
             
             //While that distance is greater than a very small amount (Epsilon, almost zero):
             while(sqrRemainingDistance > float.Epsilon)
             {
                 //Find a new position proportionally closer to the end, based on the moveTime
                 Vector3 newPostion = Vector3.MoveTowards(rb2D.position, end, inverseMoveTime * Time.deltaTime);
                 
                 //Call MovePosition on attached Rigidbody2D and move it to the calculated position.
                 rb2D.MovePosition (newPostion);
                 
                 //Recalculate the remaining distance after moving.
                 sqrRemainingDistance = (transform.position - end).sqrMagnitude;
                 
                 //Return and loop until sqrRemainingDistance is close enough to zero to end the function
                 yield return null;
             }
         }
         
         
         //The virtual keyword means AttemptMove can be overridden by inheriting classes using the override keyword.
         //AttemptMove takes a generic parameter T to specify the type of component we expect our unit to interact with if blocked (Player for Enemies, Wall for Player).
         protected virtual void AttemptMove <T> (int xDir, int yDir)
             where T : Component
         {
             //Hit will store whatever our linecast hits when Move is called.
             RaycastHit2D hit;
             
             //Set canMove to true if Move was successful, false if failed.
             bool canMove = Move (xDir, yDir, out hit);
             
             //Check if nothing was hit by linecast
             if(hit.transform == null)
                 //If nothing was hit, return and don't execute further code.
                 return;
             
             //Get a component reference to the component of type T attached to the object that was hit
             T hitComponent = hit.transform.GetComponent <T> ();
             
             //If canMove is false and hitComponent is not equal to null, meaning MovingObject is blocked and has hit something it can interact with.
             if(!canMove && hitComponent != null)
                 
                 //Call the OnCantMove function and pass it hitComponent as a parameter.
                 OnCantMove (hitComponent);
         }
         
         
         //The abstract modifier indicates that the thing being modified has a missing or incomplete implementation.
         //OnCantMove will be overriden by functions in the inheriting classes.
         protected abstract void OnCantMove <T> (T component)
             where T : Component;
     }
 }
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

2D Animation does not start 1 Answer

Player movement boudaries in 2D 1 Answer

Changing player's moving direction 0 Answers

How can I make a collision sensitive teleporter for a 2D game #c 1 Answer

2D Movement Problems 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges