- Home /
Interact with objects based on distance.
I know there seem to be plenty of answers out there for this, but literally none of them work in this case (Especially not that hour long tutorial on youtube that everyone links to, that makes it worse). So I have a script (that I attach to the objects I want to interact with) that is supposed to make it so when the player is within a certain range of the objects they can use them. That part works fine. The objects themselves are of differing sizes, however, so making some way to tell if the player is "facing" them is damn near impossible for me to figure out.
Here is the code as it is now (some of it was following the hour long "opening and closing doors" tutorial on youtube, which doesn't help and gives me wildly inaccurate detection):
var player : GameObject;
var opened : boolean;
var not_opened_color : Color;
var opened_color : Color;
var model : GameObject;
var interact_distance : float = 5.0;
var can_interact : boolean;
var PI : float = 22/7;
var angle : float;
var current_angle : float;
function Start () {
player = GameObject.FindGameObjectWithTag("MainCamera");
not_opened_color = Color.green;
opened_color = Color.red;
}
function Update () {
angle = Vector3.Angle(transform.position - player.transform.position,(transform.position + (player.transform.right * transform.localScale.magnitude)) - player.transform.position);
current_angle = Vector3.Angle(transform.position,player.transform.forward);
if(Vector3.Distance(transform.position,player.transform.position) <= interact_distance && opened == false)
{
if(current_angle < angle)
{
can_interact = true;
if(Input.GetKeyUp(KeyCode.E))
{
Debug.Log("Interacting");
opened = true;
}
}
else if(current_angle >= angle)
{
can_interact = false;
Debug.Log("Facing Away");
}
}
else if(Vector3.Distance(transform.position,player.transform.position) > interact_distance || opened == true || current_angle < angle)
{
can_interact = false;
player.GetComponent(InteractorScript).can_interact = false;
player.GetComponent(InteractorScript).current_object = null;
}
if(opened == true)
{
model.renderer.material.color = opened_color;
}
else
{
model.renderer.material.color = not_opened_color;
}
}
}
function OnGUI () {
if(can_interact == true)
{
GUI.Box(new Rect(Screen.width / 2 - Screen.width / 32, Screen.height / 2 - Screen.height / 64, Screen.width / 16, Screen.height / 32),"[E]Open");
}
}
Here's how I deter$$anonymous$$e if I'm facing something (in this case, a bad guy). See if you can adaopt this:
Vector3 dir = (mobTransform.position - myTransform.position).normalized;
float direction = Vector3.Dot(dir, myTransform.forward);
if(direction > .6f) {
(you can swap $$anonymous$$obTransform for your object) I think I got this from an excellent discussion on Unity Gems.
Looks like some of your code got cut off :P But I'll try it
EDIT: yeah that doesn't work. it works on a 1-axis rotation, but it lets me also interact with the objects whether or not I'm looking too high or too low.
Do you also want to know if the object is in the Viewport?
Have you tried using raycasting? That should work. Yeah, I think that's just the thing you're looking for. Here's a link to the scripting reference. It describes just what you want it to do.
http://docs.unity3d.com/Documentation/ScriptReference/Physics.Raycast.html
@getyour411 If the object is in the viewport I don't think that matters, but I managed to get a LOT better accuracy by raising the float value from 0.6f to 0.95f :P now my only problem is it's interacting with multiple objects if they're too close to each other but that's a different problem altogether.
@Hyperion See, I WANTED to use raycast, I just don't understand how it works no matter how many times I read that page.
Answer by Hyperion · Sep 03, 2013 at 12:44 AM
Okay, since this question needs an answer, here it is. As I said earlier, your plight would probably be best solved by raycasting. Plus you wanted to check the tag. Therefore:
//You'd need to add an extra variable, like so:
var hitInfo: RaycastHit;
if(Physics.Raycast(from,to,hitinfo,1)){
if (hitInfo.collider.tag=="yourTag"){
//do something
}
}
And here's that link: http://answers.unity3d.com/questions/10480/getting-the-objects-name-from-raycasthit.html