Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
1
Question by Michel Verheughe · Dec 23, 2012 at 07:25 PM · gameobjectraycasthit

Several objects sharing a script

This is a fundamental question that I don't understand: How do I make several objects to share a script? I need to create several instruments in industrial process, each with a script handling temperature, pressure, etc. But one must be able to use several copies of the same instrument such as a valve, but at different places, with different input and output.

The first thing I do is a user's interface. The First Person moves and when the mouse is over an interactive part of an instrument (such as a switch or button) it is highlighted and accept a mouse input to turn it on, off, etc.

The basic codes are:

 function Update () {
     var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
     var hit : RaycastHit;
     if (collider.Raycast (ray, hit, 2.0)) { // if hit!
         hit.collider.gameObject.renderer.material.color = Color.red; //highlight it red.
     }
 }

Well, it works for the first object but not for a duplicated one. I am sure I am doing a fundamental mistake about Object Oriented Programming but I don't know what. Thanks in advance,

Michel

Comment
Add comment · Show 1
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 Michel Verheughe · Dec 24, 2012 at 09:25 AM 0
Share

Thank you Eric and Aldo. Using On$$anonymous$$ouse was my first attempt. But then, I was told on this forum that I should rather us RayCast.

$$anonymous$$y problem is this: my colleagues say that I must learn Object Oriented Program$$anonymous$$g. I think I can but I can't grasp it in Unity. Say, I would like to make a class of object that is the user interface. I design it to be a RayCast that shows a red overlay to indicate that the UI is active.

Each time I need a UI, I make an instance of it and if e.g. in one case I want it to highlight to yellow, I modify it. But the day I decide that UI is On$$anonymous$$ouse and not RayCast, I can modify the UI class and ... lo and behold, everything is modified!

Now, how do I do that with Unity3D and JavaScripting?

Thanks in advance. Your help is much appreciated and a wonderful Season Holiday from Norway where Santa lives! ;-)

$$anonymous$$ichel

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by aldonaletto · Dec 23, 2012 at 09:31 PM

I would use OnMouse events in the object script: this is an easier solution in your case, because these events can modify the variables in the selected object without altering the other instances. But nothing is perfect: only the left mouse button is recognized in OnMouseDown/Up events, and you can't limit the range in OnMouseEnter/Exit events. Anyway, the code in each object could be something like this:

 var buttonOn = false; // current button state
 private var selected = false; // tells whether the button is under the mouse pointer
 private var oldColor: Color; // saves the old color for deselection
 
 function OnMouseEnter(){ // mouse pointer entered object:
   oldColor = renderer.material.color; // save old color...
   renderer.material.color = Color.red; // set selected color...
   selected = true; // and set variable selected to true
 }
 
 function OnMouseExit(){ // mouse pointer has left the object:
   renderer.material.color = oldColor; // restore original color
   selected = false; // clear variable selected
 }
 
 function OnMouseDown(){ // object clicked:
   buttonOn = !buttonOn;  // toggle button state
 }

The boolean variable selected isn't being used in this example, but may be useful in some other cases. If you want to detect right mouse button clicks, for instance, read the right button inside Update - but only when the object is selected:

 function Update(){
   if (selected && Input.GetMouseButtonDown(1)){
     // right mouse button pressed over this object
   }
 }

EDITED: As @Eric5h5 mentioned, OnMouse events don't have a range limiting parameter, thus far objects may be unintentionally selected. But combining your original code with the logic above is somewhat easy, and may solve this problem (attach this script to the object prefab):

   var buttonOn = false; // current button state
   private var selected = false; // tells whether the button is under the mouse pointer
   private var oldColor: Color; // saves the old color for deselection
 
   function Update () {
     var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
     var hit : RaycastHit;
     if (collider.Raycast(ray, hit, 2.0)) { // mouse is over this object and inside range:
       if (!selected){ // this is the equivalent of OnMouseEnter
         oldColor = renderer.material.color; // save old color...
         renderer.material.color = Color.red; // set selected color...
         selected = true; // and set variable selected to true
       }
     } else { // mouse not over this object or out of range:
       if (selected){ // this is the equivalent of OnMouseExit
         renderer.material.color = oldColor; // restore original color
         selected = false; // clear variable selected
       }
     }
     if (selected){ // if this object is selected, check buttons here:
       if (Input.GetMouseButtonDown(0)){
         // left mouse button pressed over this object
         buttonOn = !buttonOn; // toggle button state
       }
       if (Input.GetMouseButtonDown(1)){
         // right mouse button pressed over this object
       }
       // even key events "over" this object may be detected:
       if (Input.GetKeyDown("space")){
         // space pressed "over" this object
       }
     }
   }

Notice that the variables buttonOn, selected and oldColor are member variables, thus they exist and retain their values while the script exists. On the other hand, the variables ray and hit are temporary: they're created when entering the function Update and destroyed upon return.
That's how you may have several instances of the same script running independently of each other: each one has its own variables and stack internally allocated in a private space - if you click one of these objects, for instance, its buttonOn variable is toggled, but the buttonOn variables in the other instances aren't modified.

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 Eric5h5 · Dec 23, 2012 at 09:53 PM 0
Share

The problem is that there is no depth parameter when using On$$anonymous$$ouse events, and presumably the point of using 2.0 as the distance in Raycast is to prevent selection of more distant objects.

avatar image aldonaletto · Dec 24, 2012 at 12:10 AM 0
Share

Yes, that's the limitation of On$$anonymous$$ouse events. I edited my answer and combined the collider.Raycast code with the logic above.

avatar image
0

Answer by Eric5h5 · Dec 23, 2012 at 08:42 PM

It's correct and will work. If it doesn't, then the object either doesn't have a collider or is too far away. You can shorten the code a bit:

 hit.collider.renderer.material.color = Color.red;

If you look at the docs for Collider, you can see that renderer is an inherited variable.

Comment
Add comment · Show 3 · 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 Michel Verheughe · Dec 23, 2012 at 09:04 PM 0
Share

Thank you for your answer, Eric, indeed it works but only when I have one object attached to that script. If I have two, the behaviour is ... erratic.

In any case, what I really don't understand is how I make a function that can be called from many different places. I have no experience in OOP, only a long experience in Flash ActionScript 2 where I use routines at the root to handle often repeated tasks.

What would be the way, with Unity3D to make a user interface that can be called from various scripts?

avatar image Eric5h5 · Dec 23, 2012 at 09:54 PM 0
Share

I don't know what you mean. The correct practice is to put the code you posted into a script, and then attach that script to any object that you want to be affected.

avatar image aldonaletto · Dec 23, 2012 at 10:01 PM 0
Share

In Unity, each object in scene has its own script instance - this way, a variable in some object keeps its value independently of the others in other objects. I don't know how exactly this is implemented, but suppose that each script instance stores its variables and stack in a private memory area allocated when the instance is created.
A variable declared outside any function is a member variable: it exists during the script life, and is independent of its twin sisters in other script instances. If you need an equivalent to the old style "global" variable, however, declare it as static: it's allocated and initialized only once when the program starts, and exists during the whole program life. Like old style global variables, they are unique: their values are the same for all script instances.

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

11 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Ray Casting - Trigger function 1 Answer

Raycast and RaycastHit failure 2 Answers

Play ParticleSystem on RayCastHit Object 1 Answer

using Contains(gameObject) to find and destroy a gameObject from a list 2 Answers

[SOLVED] Open GUI with RaycastHit on Gameobject? 0 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