Sorry if I this question has already been posted, I looked but did not find any thread relative.
So what I need to do is selecting an object (or clone / instance of object) just by clicking on it with mouse - let’s say with kind of “highlighting” on it and being able to move / rotate it or whatever change by clicking NOT on it but on GUI element or using keys. Then I must be able to :
select another object
or
unselect all
Guess I should manage the second part of the script (transform actions) but I have no idea about selecting / unselecting the object itself / highlighting while it’s selected and “recording” the fact it’s selected so that when I use gui buttons or keys this object rotates or moves, etc.
i would have one selection manager which keeps track of the selected object(s) (for example keeps a reference of it). and when you do operations it applies these to the object. and when you select another one the reference is changed.
selection can be done with the mouseover event.
for highlighting there is a package for purchase here: Buy Plugins & Code from CodeCanyon
but you can use simpler aproaches like drawing a frame around it or simply alter material color.
thanx,
Yes I think altering material color will do the stuff. For selection I rather thought about mousedown than mouseover but nevermind, guess code structure would be the same anyway.
The point is the “reference”. What variable / code element should be used to get / record this ? Unfortunately this is way over my code knowledge. I’m okay for writing and attaching “direct” scripts on objects or creating links between two of them (for example a button that will make an object move or material change) but have no idea about this switching selection stuff.
Any more about this selection manager / referencing tip ?
simply use the transform for the gameobject itself, or if everything relevant is handeled in a certain component (script) retrieve it with getcomponent and store this. you are completely free. but if you need to access different components (like material + script) the first aproach is probably the better.
what you describe in your example is basically a selection. simply store a reference to the “selected” object, do some special drawing/highlighting, and route all user actions (movement, commands) to it. and additionally handle the change of selections properly (like deselect) or make advanced selections (rectangle select, additive select).
have colliders on all of your scene objects, then you can use OnMouseEnter() OnMouseOver() and OnMouseExit() functions, and so you can select your objects. (you can use onmouseenter to change it’s renderer.material.color to another value, and onmouseexit to change it back to the previous value, and inside onmouseover you can check for clicks and store that object in a var in the GUI control script)
The thing with the GUI (since GUI is over all your scene objects will be easy to do) is that in onmouseover if you clicked that obj you will store it as a refference inside the GUI control script, so you will be able to make simple buttons, for example
Place this script on each object you want to be able to select. (and make sure they all have colliders)
public class Selecting : MonoBehaviour{
private Color lastColor;
private Transform GUI_object_refference;
void Start(){
//this is the empty gameobject on which you place your gui script
GUI_object_refference = GameObject.Find("GUI_empty_game_object");
}
void OnMouseEnter(){
//store the color of the material, and change it to red
lastColor = transform.material.color;
transform.renderer.material.color = Color.red;
}
void OnMouseExit(){
//restore the color of the material
transform.renderer.material.color = lastColor;
}
void OnMouseOver(){
if(Input.GetMouseButtonDown("Fire1"){
//we set the reference of the GUI script if we press the left mouse button on the object
GUI_object_refference.GetComponent<GUI_Script>().SetRefference = gameObject;
}
}
}
And this script on an empty GameObject in the scene, named “GUI_empty_game_object” (without the commas), name it GUI_Script and write the next part of code inside it:
public class GUI_script : MonoBehaviour{
//the refference variable
private GameObject reference;
//setter for the refference
public GameObject SetReference{
set { reference = value; }
}
void OnGUI(){
if(GUI.Button(new Rect(100, 100, 100, 50), "ROTATE->")){
if(reference){
reference.transform.eulerAngles += new Vector3(0, 1, 0);
}
else{
Debug.Log("There is no reference!");
}
}
//do more buttons like this with different functions
}
}
NOTE: I did not test this and this code is in C#, have fun tweaking it and making it work, if it doesn’t already
oh thank you so much ar0nax.
I was just trying to code something from what you and exiguous advised me, but it was not working
(only one object was always affected by script) so I was just to post my crappy code to ask what was wrong.
Okay I’m gonna seriously study your last post and come back if still have issues.
thanx again
OK, this point solved. The actual issue was not “{” but a “)” that was missing.
Though, I now get another error message : The type or namespace name `MonoBehaviour’ could not be found. Are you missing a using directive or an assembly reference?
Selecting.cs(18,17): error CS0029: Cannot implicitly convert type UnityEngine.GameObject' to UnityEngine.Transform’ Selecting.cs(26,39): error CS1061: Type UnityEngine.Transform' does not contain a definition for material’ and no extension method material' of type UnityEngine.Transform’ could be found (are you missing a using directive or an assembly reference?) Selecting.cs(46,26): error CS1502: The best overloaded method match for UnityEngine.Input.GetMouseButtonDown(int)' has some invalid arguments* *Selecting.cs(46,26): error CS1503: Argument #1’ cannot convert string' expression to type int’ Selecting.cs(50,74): error CS1061: Type GUI_Script' does not contain a definition for SetRefference’ and no extension method SetRefference' of type GUI_Script’ could be found (are you missing a using directive or an assembly reference?)
And yes I did check that script names and class names are exactly the same + saved scripts as .cs and not .js
So sorry for that… and with C# there is litteraly nothing I can do or understand.
I’m just trying to see if I can translate this in javascript but my knowledge is so low there…
edit : ok solved one at least the very last error line
This was due to a different spelling betwen both the 2 codes (SetRefference vs SetReference)
seems if(Input.GetMouseButtonDown(“Fire1”)) caused trouble.
I replaced it by if(Input.GetMouseButtonDown(0)), according to what the manual seems to say (about javascript though).
Now still “only” 2 error lines :
Selecting.cs(17,17): error CS0029: Cannot implicitly convert type UnityEngine.GameObject' to UnityEngine.Transform’ Selecting.cs(25,39): error CS1061: Type UnityEngine.Transform' does not contain a definition for material’ and no extension method material' of type UnityEngine.Transform’ could be found (are you missing a using directive or an assembly reference?)
You click on red cubes (nothing happens visibly with Mouse Over as I deleted all material that did not work I don’t know why) but the “recording” of the reference works.
Then click on X, Y or Z button (3 rotation axis).
As you see it makes the selected cube rotate 90 ° (setted a color per face so that it’s understandable).
BUT the very strange thing is that X button only switches between 0 and 90 degrees (on X axis of course) while Y and Z buttons correctly go from 0, to 90, then 180, then 270 and back to 0 degrees.
I don’t understand why. Code is exactly the same for each.
oh, I see you just posted some stuff about materials. Thank you so much.
You’re saving me days of work/searching for this stuff (which I friendly do myself, no money involved…)
this should be good hint to consult the documentation to look what transform contains and what not. and if you dont find a material in transform have look there where material is contained (hint it begins with ren and ends with derer). a little work of yourself can be expected?
i think the other errors are related. but in most cases the casue of the error is relative clear so you should be able to fix it yourself instead of bugging us with your compiler errors. see the given code as hint in pseudocode, not as perfectly working solution.
sorry mate I did something wrong there, it should’ve been Material go in transform.renderer.GetComponentsInChildren(typeof(Material))
But that will not help, since you wanna rotate the cubes. the thing you can do is render another Cube, with a transparent material, which is enabled only in the OnMouseOver(){} , so it will hover over your selected cube.
the thing with material.color is only for visible notification of the cube you are selecting and such.
make sure you look for Gimble Lock on youtube (since that can occur when working with EulerAngles and 90 degrees angles)
But that’s exactly what I did. I looked at the doc and fixed some of errors - including the one you quote about “UnityEngine.Transform”. And posted my result here to avoid you guys having to reply about it again and again.
I do try to bug people here as less as possible but you also know that Unity doc only speaks javascript and gives no example / hint of C# syntax. Lucky you are if have good developpement skills but mind that for low level dev people (like me) the doc does’nt say on every page “hehe when you write a “:” in javascript you will use a “=” in C#” or such things. I did not even know that “function” becomes “void” here, and did not even understand how a variable should be declared in this language.
So yes, console errors here give a relatively clear idea about where the issues seem to be but still, very simple compiling errors can take hours to fix due to lack of basics. Be sure I do my best to fix it myself anyway.