How to enable a script from another object? - unity3d

I'm trying to play another script on another object when I press a GUI texture which I already have.
I tried GameObject.Find(theobject).GetComponent(thescript).enabled = true but it didn't work. I didn't get any errors. It's just when I press the GUI texture it doesn't do anything(by the way I have the function OnMouseDown() on the GUI texture)
Can anyone help me? Any help would be much appreciated. Thanks in advance!
Edit: The script for the button is:
function OnMouseDown () {
GameObject.Find("TheObject").GetComponent(thescriptwithoutthespeachmarks).enabled = true
}

Try this in your Update() function:
if(GUITexture.Contains(Input.MousePosition)){
if(Input.GetMouseButtonDown(0)){
GameObject.Find("TheObject").GetComponent(thescriptwithoutthespeachmarks).enabled = true;
}
}

Try something like this
if(Input.GetMouseButtonDown(0)){
GameObject.Find("Objectname").GetComponent<Script>.enabled = true;
}

Related

Unity | instantiate only works once

For some reason whenever I Instantiate, I can only instantiate once per build/run/game. I've tried to see if it was that I could only use different prefabs, but that isn't it. Please help, I've been trying to find an answer but no one seems to have the same problem. Thanks for reading this.
heres the project (assets and project settings) if you wanna mess around with it yourself
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CreatePipe : MonoBehaviour
{
public GameObject Pipe;
public bool yes = false;
// Start is called before the first frame update
void Start()
{
StartCoroutine("initializationn");
Debug.Log("started");
}
// Update is called once per frame
void Update()
{
// if (yes){
// inst();
// yes = false;
// }
}
public IEnumerator initializationn()
{
Debug.Log("started");
inst();
// yes = true;
yield return new WaitForSeconds(3);
inst();
// yes = true;
yield return new WaitForSeconds(3);
inst();
// yes = true;
yield return new WaitForSeconds(3);
// while (true){
// inst()
// yield return new WaitForSeconds(3);
// }
}
public void inst(){
Debug.Log("in");
var g = Instantiate(Pipe, new Vector3(7f, Random.Range(-6.5f,0f), 0f), Quaternion.identity);
g.SetActive(true);
g.name = "Pipe";
}
}
The reason only one pipe exist at at time is that the script "PipeStuff" you attached to the Prefab "Pipe", makes it a singleton. So every time you create a duplicate instance you are deleting that object since a "PipeStuff" already exist.
Suggestions:
Your script is absolutely fine there is no problem with it but perhaps you are destroying that gameObject which is intantiating those pipe prefabs thats why its not working as you intend it to, any ways check if it is so because there seems to be no other problem with your script and also you can do it in one more way by using invokeRepeating function too like:
InvokeRepeating( nameof(inst), 0, 3 );
it will call this function repeatadely after every 3 seconds and the first parameter which is 0, is used for delay at the start so if you want to Invoke that function after some seconds you can do so as well and when you are done you can destroy or disable that gameObject too, its just a basic way of doing so otherwise there are tons of ways to do so anyways...
Hope it helps... Happy Coding :)

How can I avoid the flickering of gradient panel in winforms?

I have designed a dashboard like winform and when I try to resize the winform it flickers too much.
I have already tried SuspendLayout and enabled DoubleBufferring but still, the issue persists. Please check the following GIF.
WinForm flickring While Resizing GIF
EDIT
Here is the code for Gradient Panel:
this.bunifuGradientPanel1.BackColor = System.Drawing.Color.Transparent;
this.bunifuGradientPanel1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("bunifuGradientPanel1.BackgroundImage")));
this.bunifuGradientPanel1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.bunifuGradientPanel1.Controls.Add(this.panel1);
this.bunifuGradientPanel1.Controls.Add(this.panel4);
this.bunifuGradientPanel1.Controls.Add(this.panel3);
this.bunifuGradientPanel1.Controls.Add(this.panel5);
this.bunifuGradientPanel1.Controls.Add(this.panel6);
this.bunifuGradientPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.bunifuGradientPanel1.GradientBottomLeft = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(0)))));
this.bunifuGradientPanel1.GradientBottomRight = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(0)))), ((int)(((byte)(192)))));
this.bunifuGradientPanel1.GradientTopLeft = System.Drawing.Color.Purple;
this.bunifuGradientPanel1.GradientTopRight = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(128)))));
this.bunifuGradientPanel1.Location = new System.Drawing.Point(0, 0);
this.bunifuGradientPanel1.Name = "bunifuGradientPanel1";
this.bunifuGradientPanel1.Quality = 10;
this.bunifuGradientPanel1.Size = new System.Drawing.Size(1020, 680);
this.bunifuGradientPanel1.TabIndex = 0;
Thank you for your help in advance.
Finally solved this issue!
Here is the correct answer just in case anyone may face this problem in the future:
First, create the following function inside your Form.cs:
//Double Buffering Function
public static void SetDoubleBuffering(System.Windows.Forms.Control control, bool value)
{
System.Reflection.PropertyInfo controlProperty = typeof(System.Windows.Forms.Control)
.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
controlProperty.SetValue(control, value, null);
}
Then simply call the function in your Form1_Load function and pass the name of the control (panel in my case 'bunifuGradientPanel1') and you're ready to go:
private void Form1_Load(object sender, EventArgs e)
{
// Enabling Double Buffering for BunifuGradientPanel
SetDoubleBuffering(bunifuGradientPanel1, true);
}
Hope this helps anyone facing the flickering issue while working with Panels in Windows Forms c#.
Thanks to Fluxbytes.com for creating the function above and posting it on their forum.

Do touch on point where ray hits unity

I searched the whole internet, but couldn't find anything useful. I want to "do" a touch input on the position where a ray hits an object, and only if it hits something. I hope you understand what I mean, and I know that its not common to do it with a raycast, but I need it this way for the htc vive. Thanks in advance.
or easier said, how can I touch on the screen from my script, means without really touching the screen?
You can use camera.ScreenToWorldPoint (new Vector3 (position that you want to check clicking)) in your code.
//you can change the start position in your code.
var startPos =
camera.ScreenToWorldPoint(new Vector3(2,2, 10));
then you can use this function for detecting clicking without real clicking.
public void CalculateEndPositions(Vector3 start)
{
//forward
var rayForward = new Ray(start, Vector3.up);
Debug.DrawRay(start,Vector3.up, Color.green);
RaycastHit rayForwardInfo;
if (Physics.Raycast(rayForward, out rayForwardInfo))
{
Debug.Log("Collider Name = " + rayForwardInfo.collider.name);
}
}
I hope this code is usefull for you.

Scripting GUI buttons to trigger an event of changing materials

Apologies if there's a similar question, however, I have probably seen it and it has not fixed my problem.
I am trying to write a JS script for unity in order to achieve an event to be triggered once clicked.
I have searched online on UnityAnswers website and others, the closest I can get is based on these questions
http://answers.unity3d.com/questions/368303/changing-shaders-of-a-gameobject-via-script-1.html
and this one
http://answers.unity3d.com/questions/319875/change-objects-material-using-gui-buttons-via-scri.html
and also looked at this one
http://docs.unity3d.com/ScriptReference/Material-shader.html
So, my code is this so far
var button2_tex : Texture;
var button3_tex : Texture;
var button4_tex : Texture;
var seat_mat1 : Material;
var seat_mat2 : Material;
var veneer1 : Texture;
var veneer2 : Texture;
var rend : Renderer;
var _mouseDown = false;
function Start() {
seat_mat1 = Resources.Load( "seat_mat1" );
seat_mat2 = Resources.Load( "seat_mat2" );
}
function Update(){
if(Input.GetMouseButtonDown(0)){
_mouseDown = true;
}
}
function OnGUI() {
GUI.Box (Rect (10,10,100,200), "Menu");
if (_mouseDown){
if (GUI.Button (Rect (20,40,40,20), button1_tex)){
if(seat_mat1){
rend.material = seat_mat2;
Debug.Log("This button was clicked!");
}
else{
rend.material = seat_mat1;
}
}
}
Please note some variables I haven't used yet, as am still testing bunch of other codes to get it working..
the code snippet I am trying to fix starts with "function OnGUI()" but I maybe wrong and could use some fresh insight.
this is a screenshot of the resulting script. The button on the left side is supposedly to change the colour of the material from seat_mat1 to seat_mat2 by the event of mouse clicking on the button.
I have attached the previous script to the 3D object in unity and had made a folder names "Resources" for the materials to be visible and referenced through the script.
My problem is that upon clicking the GUI button, nothing happens, and it maybe something very simple and I am just missing it .. apologies for being inexperienced in JS much or unity.
Thanks in advance.
EDIT:
So after playing a bit more with the code. I added a Debug.Log() after this line
GetComponent.<Renderer>().material = seat_mat2;
Debug.Log("This button was clicked!");
and seems to be this error that I am getting every time the button is pressed
"MissingComponentException: There is no 'Renderer' attached to the "scene_export3" game object, but a script is trying to access it.
You probably need to add a Renderer to the game object "scene_export3". Or your script needs to check if the component is attached before using it.
materialChanger.OnGUI () (at Assets/materialChanger.js:44)"
So with simple understanding, it seems that the renderer is not attached somehow?
Your code is working fine But still i think once you have loaded The materials in start function you do not need to load them every time. And one thing more is to make sure you have applied the script to the gameobject you want to change the material of. If you just want to change the color not want to change complete material use color property of material and your OnGUI function should look like this.
function OnGUI() {
GUI.Box (Rect (10,10,100,200), "Menu");
if (_mouseDown){
if (GUI.Button (Rect (20,40,40,20), button1_tex)){
if(GetComponent.<Renderer>().material == seat_mat1)
GetComponent.<Renderer>().material.color = seat_mat2.color;
else
GetComponent.<Renderer>().material.color = seat_mat1.color;
}
}
}
But if you do not use color poperty it will work fine just make sure you have applied script to game boject you want to change material i your case may be to your seat1.
Thanks Nain for your guidance, with your help I was able to come up with a partial solution, where I know I can fix from there.
The solution is as follows.
The code:
function OnGUI() {
GUI.Box (Rect (10,10,100,200), "Menu");
if (_mouseDown){
if (GUI.Button (Rect (20,40,40,20), button1_tex)){
var rendArray : Renderer[];
rendArray = GetComponentsInChildren.<Renderer>(true);
for(var rend : Renderer in rendArray){
if(rend.sharedMaterial == seat_mat1){
rend.sharedMaterial = seat_mat2;
Debug.Log("This button was clicked!");
}
else{
rend.sharedMaterial = seat_mat1;
}
}
}
}
}
After saving the script in MonoDevelop, open Unity where you create an empty game object and add all the objects with specific material e.g. seat_mat1 under it as children.
Then click on the empty object, rename it if you like, and add a "Mesh Renderer" component from "Add Component > Mesh > Mesh Renderer".
After that drag the script to the empty object and in the inspector you can find an option which you can choose a renderer called "rend". Choose the empty object as the Mesh Renderer.
Upon testing the outcome, I have managed to change materials of some objects together to seat_mat2, but unrelated materials changed themselves to seat_mat1 and once the button is clicked again, they alternate between seat_mat1 and seat_mat2
and even though it is not perfectly done, I am answering this question as anything else is fixable (I hope).
Thank you again Nain for your help :)

Missing Field Exception Unity3d Script

When I compile my game in debug mode in Unity3D it instantly pauses a quick glance at the console reveals the following error:
MissingFieldException: UnityEngine.Light.Enable
Here is the script it is very simply meant to make the point light flicker when the randomiser is below 0.7.
var FlashingLight : Light;
FlashingLight.enabled = false;
function FixedUpdate (){
var RandomNumber = Random.value;
if(RandomNumber<=.7){
FlashingLight.enable = true;
}
else FlashingLight.enabled=false;
}
Any help would be appreciated, thanks.
The field is called enabled, not enable.