- Home /
Item Interaction Script Working Half The Time? (Build Included)
Hi guys. Hoping somebody can help me, because this problem is driving me a little nuts. I've been using Unity for a few months just in general prototyping for Uni, and I'm slowly getting the hang of programming (not really :P).
So I've written up an item interaction script based on a youtube video tutorial (shown here), It's pretty simple. First person, raycasting item interaction. The problem I'm having is I get it all working in the engine, and then on build (web or exe) half the items with the exact same script on them, stop working. It makes no sense to me, since the same script is on multiple objects, and if they aren't working - shouldn't it effect all of the items?
To briefly explain before I code dump, the game consists of moving about the environment changing items from one material to another. It all works, when it works, otherwise it does nothing. I've tried a lot of different things but I just can't figure out the cause of the problem. This is for a uni project and I need to get it fixed asap, so if you guys could quickly look through it and see if anything stands out?
Also, I've recently reformatted my computer, and installed Unity fresh. Anybody think it's Unity and not the script/project itself? If so, how could I fix it. I have no way to test it on another machine at the moment.
It's a little long, but the script is very basic, so hopefully it isn't too much of an ask to look through it? The raycast script is checking to see if the interaction script is on the item, if it is, it boots up OnLookEnter. From there you can see the rest of the effects that ripple out by following the vars. Even on the basic version that the youtube dude illustrated, the problem was occurring. I thought maybe it was the event system, since I've never used it before, but more experienced eyes would know far better.
Raycast Script:
//LK - Raycast var.
public RaycastHit hit;
//LK - So we can change how far away you are when it activates.
public int distance;
//LK - Basic Raycast.
void Update ()
{
Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2,Screen.height/2,0));
if (Physics.Raycast(ray, out hit,distance))
{
if(hit.collider.gameObject.GetComponent<Interact>()!=null)
{
hit.collider.gameObject.GetComponent<Interact>().OnLookEnter ();
}
if(hit.collider.gameObject.GetComponent<EmptyBin>()!=null)
{
hit.collider.gameObject.GetComponent<EmptyBin>().OnLookEnter ();
}
}
}
Item Interaction Script:
using UnityEngine;
using System.Collections;
public class Interact : MonoBehaviour {
//LK - Object State
//LK - 0 = Dirty
//LK - 1 = Dirty & Selected.
//LK - 2 = Clean
//LK - 3 = Clean & Slected.
//LK - 4 = Throw Away? <- Set Initial Object State to 4 for disposable objects.
//LK - 5 = Throw Away & Selected
//LK - 6 = Hide <- Set Initial Object State to 6 for Hidden Objects
//LK - 7 = Hidden & Selected.
public int ObjectState = 0;
//LK - Material Library For Item
public Material highlightMat;
public Material dirtyMat;
public Material cleanMat;
//LK - Text Field
public string OnDefault;
public string OnHover;
public string OnClick;
public string OnHoverDispose;
public string OnHoverHidden;
//LK - Turns true when object is being looked at
private bool selected = false;
private bool BinFull = false;
//LK - Timer
private int time = 0;
//LK - Additional vars used only for drawing solar bar
private int maxtime;
private float timerlength;
public int AmountToWait;
//LK - Plug in for Custom GUI Skin.
public GUISkin customSkin;
//LK - Start State
void Start ()
{
timerlength = AmountToWait;
maxtime = AmountToWait;
}
//LK - Update.
void Update()
{
TexCheck();
TheTime(0);
selected = false;
if (time <0)
{
time = 0;
}
if (BinBarScript.BinSize >=100)
{
BinFull=true;
}
if (BinBarScript.BinSize <=99)
{
BinFull=false;
}
}
public void OnLookEnter()
{
if (ObjectState==0)
{
ObjectState=1;
selected=true;
}
if (ObjectState==2)
{
ObjectState=3;
selected=true;
}
if (ObjectState==4)
{
ObjectState=5;
selected=true;
}
if (ObjectState==6)
{
ObjectState=7;
selected=true;
}
}
//LK- This occurs in our GUI function.
void OnGUI()
{
Event e = Event.current;
if (e.isKey && e.character == 'e' && selected)
{
if (ObjectState < 3)
{
time++;
if (time >= AmountToWait)
{
ObjectState=3;
time=0;
}
}
if (ObjectState == 5)
{
if (BinBarScript.BinSize < 90)
{
time++;
if (time >= AmountToWait)
{
time=0;
Destroy(this.gameObject);
BinBarScript.BinSize +=20;
}
}
if (BinBarScript.BinSize > 90)
{
BinFull = true;
}
}
if (ObjectState == 7)
{
time++;
if (time >= AmountToWait)
{
time=0;
Destroy(this.gameObject);
}
}
}
if (ObjectState==0)
{
GUI.skin = customSkin;
GUI.Label (new Rect (Screen.width/2+20,Screen.height/2-25,150,100), ""+OnDefault+"");
}
if (ObjectState==1)
{
GUI.skin = customSkin;
GUI.Label (new Rect (Screen.width/2+20,Screen.height/2-25,150,100), ""+OnHover+"");
}
if (ObjectState==3)
{
GUI.skin = customSkin;
GUI.Label (new Rect (Screen.width/2+20,Screen.height/2-25,150,100), ""+OnClick+"");
}
if (ObjectState==5)
{
GUI.skin = customSkin;
GUI.Label (new Rect (Screen.width/2+20,Screen.height/2-25,150,100), ""+OnHoverDispose+"");
}
if (ObjectState==7)
{
GUI.skin = customSkin;
GUI.Label (new Rect (Screen.width/2+20,Screen.height/2-25,150,100), ""+OnHoverHidden+"");
}
if (BinFull==true)
{
GUI.skin = customSkin;
GUI.Label (new Rect (Screen.width/2+365,Screen.height/2+215,150,100), "Bin Full");
}
//LK - Timer
if (time>=1 && selected)
{
GUI.skin = customSkin;
GUI.Box (new Rect(Screen.width/2+20,Screen.height/2-5,timerlength,15),"");
}
}
void TexCheck()
{
if (ObjectState==0)
{
renderer.material = dirtyMat;
}
if (ObjectState==1)
{
renderer.material = highlightMat;
Waiter();
ObjectState=0;
}
if (ObjectState==2)
{
renderer.material = cleanMat;
}
if (ObjectState==3)
{
//renderer.material = highlightMat;
Waiter();
ObjectState=2;
}
if (ObjectState==4)
{
renderer.material = dirtyMat;
}
if (ObjectState==5)
{
renderer.material = highlightMat;
Waiter();
ObjectState=4;
}
if (ObjectState==6)
{
renderer.material = dirtyMat;
}
if (ObjectState==7)
{
renderer.material = highlightMat;
Waiter();
ObjectState=6;
}
}
public IEnumerator Waiter()
{
yield return new WaitForSeconds(2.0F);
}
void TheTime(int adj)
{
time += adj;
timerlength = (AmountToWait) * (time / (float)maxtime);
}
}
I'd be happy to give more info if needed, or format things a certain way. Whatever helps, I just need to figure out what's happening here. I've scoured the forums and answers and can't seem to find similar behavior.
Here is a link to a webplayer version. All of the cube objects are using the above code, and as you can see, only some of them work. What's strange, is the item will still highlight, so the code is working to a point on ALL items, yet for some reason only some show the GUI text, and only some allow for a key press.
Answer by phodges · Oct 28, 2012 at 09:10 AM
There are so many things that could be said about this script, I'll try and stay focussed on your one issue:
You are using a raycast to set selection states and perpetually clearing that selection within update, which is unnecessarily confusing.
Think about adding an OnLookExit method that your raycast script can use when it changes focus from one object to another (or no object)
You rely on TexCheck pushing objects back down into state 2 in order to make progress, so order of execution becomes important here.
Your Waiter function is not doing what you think it does: take another look at how couroutines work.
You might find it useful to sketch out the intended behaviour of all of the objects (think about a state machine) and also to divide up responsibilities between objects.
EDIT: questioner asked for an example on how to signal changing focus from one object to another:
Hi, thanks for the reply. As you can no doubt tell, I am not a strong scripter, but I am trying to get the concept down the only way, for the moment, I know how. Your suggestions all seem relevant (though I don't know enough about script to know why) so do you believe the reasons you stated are causing the error?
As I'm basically scripting by grabbing sections of code that works and stitching them together, efficiency isn't taken into account for me. It just needs to work.
On to the points: I can see what you mean about the selection states being cleared through update. Do you have a suggestion as to how I can do it another way, whilst achieving the same result?
Could you briefly go into how I would add the OnLookExit function to the above script? When I first started scripting this concept, I was going to use tags and colliders, but the youtube video seemed to illustrate a better way of doing it. Unfortunately it's resulting in this strange error.
Would the order of execution (which I'm assu$$anonymous$$g means where the sections of script are placed in the context of the overall script) be causing half the objects to not work, even though the script is doing the same thing on all the items?
I'll look into the Waiter function. I need it to work like WairForSeconds in Java, but I've had a little trouble wrapping my head around it.
Edit: Also, in terms of intended behavior, all the objects behave in the one way, they highlight when they get looked at, if you press E the timer starts and when you finish it they either change material or delete completely. I don't need vastly different object interactions, just really the one. The problem is, as I was saying, the script works - just for some reason it stops working on some of the primitives when I build out (and afterward in engine as well). Even though the primitives might be exactly the same. Check out the build I posted to get a better idea of what I mean, if you're interested in following up.
I can certainly give you an idea of how you might implement OnLookExit: follow the link I just posted to github.
Ah, thank you very much. I'll have to go close another question that I literally JUST posted. Your code is excellent, I'll start digesting it now.
Edit: Just tried the basic gist of the script and I understand now how to implement everything else I need to implement (except for maybe the timer). Thanks again for taking the time to upload the example script.
Your answer
![](https://koobas.hobune.stream/wayback/20220613083000im_/https://answers.unity.com/themes/thub/images/avi.jpg)