Practical use of Unity3d engine.
Task #3: Objects selection and highlight in Unity3d
Contents
- Task #3: Objects selection and highlight in Unity3d.
- 1. Object selection
- 2. Object highlight
- Remarks
Task #3: Objects selection and highlight in Unity3d.
This article will show solution for the task: application should implement object selection by left mouse button down. Also application should highlight selected object. This article is base on the second one (http://denis-potapenko.blogspot.com/2013/03/task-2-rendering-hotspots-in-unity3d.html). So, I suggest reading the second article first. Figure B shows result we want to achieve:
Figure В. – Result scene
Object selection
At first, create class variable, which will store the selected object.
// selected GameObject private GameObject mSelectedObject;
Also, let’s create property for this object.
////// Gets or sets selected GameObject /// public GameObject SelectedObject { get { return mSelectedObject; } set { ... // assign new game object mSelectedObject = value; ... } }
Full implementation of this property will be described below.
And now, create method, which implementation is object selection. We need to determine what object is located under the mouse. Object selection pipeline is:
- Convert mouse position from screen space to three-dimensional space (A);
- Build ray, directed from mouse position to “camera forward” way (B);
- Find intersection of ray and any object in the scene;
- Find the first object that occurred on intersection;
Convert mouse position to ray that spreads to “camera forward” (Combine A and B) using «ScreenPointToRay» method.
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Now, let’s find ray intersection with any object in scene. To implement this call function «Physics.Raycast».
RaycastHit hit; if (Physics.Raycast(ray, out hit, Constants.cMaxRayCastDistance))
I should notice, that each object we want to get intersection should have «Collider» component. Colliders mainly used in physics, particularly to determine object intersection. To assign «Collider» to GameObject you need to select the object in the scene and choose menu item «Component / Physics / Box Collider». In future articles we will have more detailed description of this component.
So, if intersection exist, function «Physics.Raycast» returns «true» and sets «hit» variable. Now, let’s determine intersected GameObject.
// get game object GameObject rayCastedGO = hit.collider.gameObject;
And finally, set this object as selected.
// select object this.SelectedObject = rayCastedGO;
And now, we need to call function “SelectObjectByMousePos” in «Update» one. But we will call it only when left mouse button is pressed.
// process object selection if (Input.GetMouseButtonDown(0)) { SelectObjectByMousePos(); }
And now, let’s take a look to «SelectedObject» function implementation.
Object highlight
At first, I’ll tell a bit of theory. Object highlight we can do by a lot of ways. I will describe a way that we can achieve without any add-ons to Unity3d engine. But after that, I will describe you a better way of highlight implementation, but it will require doing some special actions.
So highlight implementation is divided to such parts:
- Create two materials: the first one is simple material, and the second material is used for highlight;
- Pass these materials to script;
- When object is selected set its material to highlighted;
- To object that was selected before, set simple material;
Now, let’s take a look to implementation. In Unity3d editor create folder with materials and name it «Materials». In this folder create two materials: simple “SimpleMat” and highlighted “HighlightedMat”. Result folder tree is shown on figure 2.1.
Figure 2.1 – Files and folders structure with created materials
I want to notice that “Diffuse” shader is set to both materials. Materials are configured identically, except that the material «HighlightedMat» has diffuse color set to red. Material settings of «HighlightedMat» are shown on figure 2.2.
Figure 2.2 – Settings of «HighlightedMat» material
Now, create two public class variables in “AppRoot” class, which will contain materials data.
// materials for highlight public Material SimpleMat; public Material HighlightedMat;
Set value to this variables. We can do it directly in the editor. Process of assigning values to materials is shown on figure 2.3.
Figure 2.3 – Process of assigning materials to the script "AppRoot"
So, finally let’s have a look to implementation of the setter of the property “SelectedObject”.
Get «old» selected object.
// get old game object GameObject goOld = mSelectedObject;
Set new selected object.
// assign new game object mSelectedObject = value;
If selected object is not changed, just leave this function.
// if this object is the same - just not process this if (goOld == mSelectedObject) { return; }Set material to old selected object.
// set material to non-selected object if (goOld != null) { goOld.renderer.material = SimpleMat; }
Set material to selected object.
// set material to selected object if (mSelectedObject != null) { mSelectedObject.renderer.material = HighlightedMat; }
As a result, we have got a scene, in which user by means of left mouse button can select objects and that object will be highlighted to red color.
Remarks
As I mentioned, I don’t think that described above way is the best way to highlight the object. I consider that the more efficient and flexible way to highlight the object is to use shader with «Emissive» component. This component is multiplied to result color by special way, so the object gets only “coloring” of red color but not the full red color. You can do such shader yourself, and in further articles I will tell you how to do it. From existing set of Unity3d shaders I found one that can fit to highlight purpose in some situations. It’s named «Reflective/Diffuse». You can use this shader and its field “Reflection Color” instead of “Emissive”.
Results of development you can see here:
https://dl.dropbox.com/u/20023505/Articles/Unity3d/Lesson3/WebPlayer/WebPlayer.html
As always for free you can download source codes from here:
https://dl.dropbox.com/u/20023505/Articles/Unity3d/Lesson3/Sources/Sources.zip
https://github.com/den-potapenko/Unity3dArticles/tree/master/Lesson3