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 Quangmeoo · Mar 22, 2017 at 07:22 AM · colliderinput

Avoid retyping code?

Hi, I am having a question.

Let's say i have 2 gameObject. They have Collider2D (isTrigger on) so that when player enter the collider, and press 'e' they gameObject would call a function (which I name interact() ).

Most of the script would be the same, the only different is interact() function.

What should I do to avoid retyping code?

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

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by Mr-Men · Mar 22, 2017 at 09:42 AM

@Quangmeoo

There are a few ways to achieve this. I'd consider using inheritance:

Make a base script, inheriting from MonoBehaviour, with all the common methods coded in it and an abstract Interact() method. Then create a script for each gameObject, inheriting from your base script, and override the interact() method.

Comment
Add comment · Show 2 · Share
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
avatar image Quangmeoo · Mar 22, 2017 at 10:13 AM 0
Share

oh thank you, it works fine now although I have to attach both of them to the same gameobject. I thought it would be impossible since I am not truely familiar with Component structure of Unity. OOP is weird here :)

avatar image Bunny83 Quangmeoo · Mar 22, 2017 at 10:18 AM 0
Share

Please use the "Add Comment" button when you want to post a comment. "Answers" should answer the question. I converted your answer into a comment.

avatar image
1

Answer by Bunny83 · Mar 22, 2017 at 10:17 AM

Inheritance is one way (as Mr-Men said), using SendMessage is another. SendMessage uses Unity's messaging system and is more suited for component based design. So you simply create two scripts. The first one has an OnTriggerStay2D method where you can check if a certain key is pressed while the player is inside that trigger. If so you simply send a message to "Interact". Another script can simply implement an "Interact" method which will be called automatically.

 public class TriggerActivator : MonoBehaviour
 {
     public KeyCode key = KeyCode.E;
     public string activationTag = "Player";
     void OnTriggerStay2D(Collider2D aOther)
     {
         if (aOther.gameObject.CompareTag(activationTag) && Input.GetKeyDown(key))
             SendMessage("OnInteract",aOther.gameObject, SendMessageOptions.DontRequireReceiver);
     }
 }

This script, when attached to an object in the scene will send an "OnInteract" message to other scripts on the same object. So if you attach another script like this:

 public class AmmoContainer : MonoBehaviour
 {
     public void OnInteract(GameObject aOther)
     {
         Debug.Log("object '"+aOther.name+"' has interacted with this AmmoContainer at " + transform.position);
     }
 }

Usually the passed gameobject will be the player object since by default we check for the tag "Player".


Another way is to reverse the logic which is often the better way. So you would have the TriggerActivator on the player object and have it send a message to objects the player collides with. For this you would have to change the class slightly and of course attach it to the player instead of the actual object:

 public class TriggerActivator : MonoBehaviour
 {
     public KeyCode key = KeyCode.E;
     void OnTriggerStay2D(Collider2D aOther)
     {
         if (Input.GetKeyDown(key))
             aOther.gameObject.SendMessage("OnInteract",gameObject, SendMessageOptions.DontRequireReceiver);
     }
 }

This has the advantage that you only need one instance of the TriggerActivator on the player. Every time you press the button "e" it will simply send a message to all objects that are current touching / overlapping with the player.


Instead of "messages" you could also use interfaces. Using interfaces has the advantage that you can't misspell the "message name". However it would require to use GetComponent on the target object to aquire that interface.

Example:

 public interface IInteractable
 {
     void Interact(GameObject aOther);
 }
 
 public class TriggerActivator : MonoBehaviour
 {
     public KeyCode key = KeyCode.E;
     void OnTriggerStay2D(Collider2D aOther)
     {
         if (Input.GetKeyDown(key))
         {
             var interactable = aOther.GetComponent<IInteratable>();
             if (interactable != null)
                 interactable.Interact(gameObject);
         }
     }
 }

A script on the other object can now implement that interface:

 public class AmmoContainer : MonoBehaviour, IInteractable
 {
     public void Interact(GameObject aOther)
     {
         Debug.Log("object '"+aOther.name+"' has interacted with this AmmoContainer at " + transform.position);
     }
 }

This will automatically call the Interact method on any class that implements that interface.

Comment
Add comment · Share
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

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

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Help In Making a SphereCast for 3D Tire! Working RayCast Script included! 0 Answers

Interacting with a button by colliding with it 1 Answer

Protected/private, KeyCode, Colliders and Large map Questions 2 Answers

How to change first person controller input when passing through a collider? 1 Answer

OnMouseDown and iPhone 1 Answer


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