Detecting a single instance of a prefab - c#

I am developing a unity project.In that I have a prefab where there will be multiple instances of that prefab will be generated in the scene.I want to select one instance of that prefab and change the color of that of that prefab.
void Update(){
if (Input.GetMouseButtonDown(1))
{
wallPrehab.renderer.material.color = Color.red;
}
}
but this changes all the instances of the prefab.How can I change it to a single object.

Change the color of the object by locating the instance of the prefab, not the prefab itself. Use a Raycast to locate the gameobject. (Since you are responding to mouse click event i assume that you are selecting the object which you want to change the color)
private RaycastHit hit;
void Update(){
Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out hit);
if (Input.GetMouseButtonDown(1) && hit.collider){
hit.collider.gameObject.renderer.material.color = Color.red;
}
}
Dont forgrt to add a Collider to the prefab.

Because all your objects use the same material it won't be possible to change ones color without affecting others , one way is to create a copy of that material and change that ones color , this way they aren't using the same material the only thing that you need to do differrent in your code is to get the reference to the instance not the prefab this way if you change the material at runtime a new material will be created
Gameobject go = Instantiate(myPrefab);
go.renderer.material.color = Color.blue;

Related

#Unity3D - How to attach an object to another using a face of the last object as a target

I would like to know if it is possible to use the face of an object (for example let's name it Object 1) and use the face as a target to position another object (Object 2) side by side, using the face of Object 2 as the second target.
Let's say that I have three simple box-like objects and I want to make different compositions by adding to the first object, already present in the scene, another one and then the other in whatever order i want by pressing a specific key on the keyboard (let's say W key for the Object 2 and S key for the Object 3).
It doesn't need to be with this method that I thought, but it needs to be the same process.
It should take into consideration the size of the object and also the rotation.
One possible solution is to carfully make prefabs of your shapes in a way that would allow you to instantiate them so that they are aligned correctly.
The following overview shows your three shapes saved as prefabs. They have been constructed using an Empty GameObject (blue diamond) and attaching the 3d model (works for sprites as well) and placing another Empty GameObject (red diamond) that is rotated so that the green axis arrow points in the direction of the normal.
If you attach the following script to the red diamond Empty GameObject and put the prefabs in their slots, you will be able to instantiate shapes 2 and 3 by pressing S and W respectively.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Placement : MonoBehaviour
{
public GameObject shape1, shape2, shape3;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
Instantiate(shape3, transform.position, transform.rotation);
this.enabled = false;
}
if (Input.GetKeyDown(KeyCode.S))
{
Instantiate(shape2, transform.position, transform.rotation);
this.enabled = false;
}
}
}
Note that the script also disables itself upon a successful instantiation, so that it only spawns shapes at the very end.

How to change color of the instance of a prefab in runtime?

I have a problem to change of color of prefab object in runtime.
The problem is that the prefab is composed of a GameObject and inside it is the cube. Therefore, when you instance the object from runtime does not allow you to change the color. How can I identify that created object and change its color or any other property?
Here the image of the error:
This is my repository with the project (branch develop): https://github.com/emicalvacho/MapaMentalAR
Therefore, when you instance the object from runtime does not allow you to change the color
Yes .. simply store the reference when you instantiate. From your exception in the console you can see that you (accidently?) are trying to change the color of the prefab itself - not the just created instance.
var instance = Instantiate(prefab, position, rotation);
var objRenderer = instance.GetComponentInChildren<Renderer>(true);
objRenderer.material.color = Color.blue;
It seems that in your scripts you are referencing the prefab instead of the instantiated object.
Simply you cant.
Either you have seperate Prefabs with the different colors, or you change the material after you instanced it to the desired color.
After creating a game object at runtime you can not access it's properties directly
if you want to change color of cube that created runtime first of all you need to get a component named meshRenderer then you can pick the material of that meshRenderer ander getting a material you can change the color of it.
GameObject obj = Instantiate(cubePrefab, position, rotation));
obj.GetComponentInChildren<MeshRenderer>().material.color = Color.Red;

Unity prefab as an object in inspector asking for attaching object

I am initiating prefabs as objects and then trying to do something using these objects that have those prefabs. However, in the inspector, its asking to attach objects that are actually already attached via code.
Code
public float hitspeed=2f;
public GameObject target, mytarget;
public GameObject arrow,myarrow;
//Use this for initialization
void Start (){
myarrow = Instantiate(arrow, new Vector3(0.02f, -3.98f, 0), transform.rotation);
mytarget = Instantiate(target, new Vector3(-0.06435323f, 2.325303f, 0f), transform.rotation);
}
Inspector
Error
[06:34:34] UnassignedReferenceException: The variable arrow of knife has not been assigned. You probably need to assign the arrow variable of the knife script in the inspector.
[06:34:39] UnassignedReferenceException: The variable myarrow of knife has not been assigned. You probably need to assign the myarrow variable of the knife script in the inspector.
With your object selected so you can see the inspector shown in the image
Go to your Project window, find your prefab.
Drag it to the the inspector where it says "none."
You can also click the little target/circle next to "none" and choose from a list.
It is true that you seem to have assigned myarrow and mytarget, however, you have instantiated them using target and arrow. You have set target using the gui, but not arrow. You must also set arrow.
In general, and to quote from another answer:
[arrow and target have] to be a prefab that you've already created in the Editor and
dragged/dropped onto the Inspector window for this object.
Ensure you:
Created a prefab
Selected this object in the Editor, so the Inspector appears
Drag/dropped that prefab onto the "arrow"/"target" field in the Inspector

How can i add a renderer to gameobject in script?

GameObject cube = Cube.CreatePrimitive(Cube.CubePivotPoint.UPLEFT);
cube.GetComponent<Renderer>().material.color = Color.blue;
When i assign the color i'm getting exception on the line:
cube.GetComponent<Renderer>().material.color = Color.blue;
MissingComponentException: There is no 'Renderer' attached to the "CubeHolder" game object, but a script is trying to access it.
You probably need to add a Renderer to the game object "CubeHolder". Or your script needs to check if the component is attached before using it.
NOTE:
I am using the CUBE class from this answer to create a cube, not the Unity's GameObject.CreatePrimitive function.
When I wrote the CUBE class, I forgot to mention that the Cubes' renderer is now a child of another Object.
You don't need to add Renderer or MeshRenderer to the cube. It's is already there. The cube is simply a child object and the parent Object is named CubeHolder. You need to use GetComponentInChildren to get its Renderer.
cube.GetComponent<Renderer>().material.color = Color.blue;
should now be:
cube.GetComponentInChildren<Renderer>().material.color = Color.blue;

Gameobject instantiated in canvas shows up behind other canvas items

In my game, if it is the first time the player has ever played the game then I have an image that is displayed. I instantiate it in the canvas like so:
if (PlayerPrefs.GetInt("First Time", 1) == 1)
{
introEnabled = true;
//pause all activity
pause.pauseOrResume();
intro = Instantiate (Resources.Load ("intro"), transform.position, Quaternion.identity) as GameObject;
Canvas canvas = GameObject.Find("Canvas").GetComponent<Canvas>();
intro.transform.SetParent(canvas.transform, false);
//robot = Instantiate (Resources.Load ("robot"), transform.position, Quaternion.identity) as GameObject;
PlayerPrefs.SetInt("First Time", 0);
PlayerPrefs.Save();
}
I can see in the inspector when the game is running that when the object is created, it does show up in the canvas. I just have no idea why it won't show up on top of all of the other objects in the canvas.
The canvas rendering mode is set to "Screen space - Overlay" and it is set to 0 in the sort order. The game object being instantiated also has a sort order of 0 and it is in the default layer.
Nothing I have tried has worked. The z values make no difference and even putting the canvas and the instantiated object in the Default layer and setting the canvas to a sort order of 2 and the instantiated object to a sort order of 1 (so it is rendered first) does not make a difference.
What you want is to use transform.SetAsLastSibling() . The CanvasRenderer renders the GameObjects in order according to their sibling index's (position in the hierarchy), from top to bottom.
However, after examining your code further I noticed something and I should say that if you are trying to instantiate the intro screen, I would highly recommend to instantiate it with it's own Canvas, instead of parenting it to the existing one. Something that significant should have it's own dedicated Canvas.
Update: The problem here is that you are instantiating GameObjects with a transform and Sprite renderer. Canvas UI gets rendered last, over all mesh layers, so if you want your newly instantiated GameObjects to participate, they will need to have RectTransform and Image components instead.
Instead of Default layer change its layer to UI.
You code seems fine, it might be problem related to the gameobject where this script is attached (because you are passing transform.position in Instantiate). it might be positioning the Instantiated game object off the canvas. Try like this once it might work.
intro = Instantiate (Resources.Load ("intro")) as GameObject;
and after setting its parent(very important), set it's position like this
intro.transform.localPosition = new vector3(0,0,0);

Categories

Resources