Hello everyone,
I am totally new to programming, just started this semester in University. Since the last few hours I banged my head on this situation:
I’ve created a first person controller script on a capsule, and two scripts for the main camera: One that does the raycast and another for the camera movement with the mouse. So far so good 
Now I am trying to add this:
If the ray meets an objet that is tagged “Collectable” AND “E-Key” is pressed the objects’ Light component should be activated.
Now while I’m able to put this into words here, i have not found a way to put this into functions in script. I do suppose this needs two scripts. One for the game objects with the Light and an addition for the raycast-script.
Would be happy for ideas! I am not looking for a script to be done from you, just perhaps a hint on what can help. I looked at several videos & scripts so far, but for example they only explain how to destroy an object on click (with ray on it), but not how it’s possible to access & change a gameobject component.
Oh gosh I’d be so happy for some help 
Here’s a method I used on a project to do what you’re describing. This assumes you’re using a first-person camera, as the raycast extends into the center of the screen. This isn’t the best implementation, and I’ll be reworking it soon, but it does what you want.
private void CheckForInteractables()
{
ButtonController hoverButtonController = null;
//Debug.DrawRay( Camera.main.transform.position, Camera.main.transform.forward, Color.red, 0.1f );
var hits = Physics.RaycastAll( Camera.main.transform.position, Camera.main.transform.forward, GameConstants.Settings.InteractableMaxDistance )
.OrderBy( h => h.distance )
.Where( h => h.collider.gameObject.tag == GameConstants.Tags.Interactable );
if ( hits.Any() ) {
var firstHit = hits.First();
var isVisible = Camera.main.transform.position.CanSee( firstHit.collider, ( GameObject gObj ) => { return false; }, allowTransparency: false );
if ( isVisible ) {
hoverButtonController = firstHit.collider.gameObject.GetComponent<ButtonController>();
if ( hoverButtonController == null ) {
// The controller might be on the parent.
if ( firstHit.collider.gameObject.transform.parent != null ) {
hoverButtonController = firstHit.collider.gameObject.transform.parent.GetComponent<ButtonController>();
}
}
if ( _currentInteractable != null ) {
_currentInteractable.IsHovered = true;
}
}
}
if ( hoverButtonController == null ) {
if ( _currentInteractable != null ) {
_currentInteractable.IsHovered = false;
_currentInteractable = null;
}
}
else {
_currentInteractable = hoverButtonController;
_currentInteractable.IsHovered = true;
}
if ( _currentInteractable ) {
if ( InputUtils.GetInputDown( _gameController.KeyBindings.Bindings[GameKey.Activate] ) ) {
_currentInteractable.Clicked();
}
}
}
To sum this up:
- I do a RayCast from the main camera going forward a certain distance, to see if I “hit” any gameobjects with a tag “Interactable”. (Note: This could also be done using layers instead of tags for more efficiency)
- If I hit an Interactable object, I then ensure that it’s actually visible to the player, and not in range but blocked by something else. (This step could probably be skipped using better layer masks on the Raycast.)
- If the interactable object is truly visible, I get the ButtonController component from it, which is just a class I put on my interactable buttons.
- I keep track of the current interactable object in _currentInteractable. When there is one, I set its IsHover to true, which lights up the object. When there is no interactable object, I set _currentInteractable’s IsHover to false, and then null it out.
- If there is a _currentInteractable, and the player presses a certain key, I call a Clicked event on my _currentInteractable.
So, limitation of this code are that only one object is interactable at a time. And as I said, this works fine, but could be cleaner and faster using better layer masking on the raycast, instead of the tag-based approach and the subsequent CanSee call.
Hey there, to be honest the script I have trouble understanding. Maybe it help if I show you my current status. I made is possible to access a specific objects light component (here Cube1). But what if I have Cube1, Cube2,… and I give them all the Tag called “Lightable”. How would I need to adjust the script so it isn`t only working on a specific object but rather objects that have the given Tag? I believe the if-part needs to be “if (whatIhit.collider.gameObject.tag == “Collectible”)” but other than that, I am a bit lost.
(script on the main camera, so first person)
public class RayCasting : MonoBehaviour
{
public float distanceToSee;
RaycastHit whatIhit;
private GameObject Cube1;
private Light myLightComponent;
void Start()
{
Cube1 = GameObject.Find("Cube1");
myLightComponent = GameObject.Find("Cube1").GetComponent<Light>();
}
// Update is called once per frame
void Update()
{
Debug.DrawRay(this.transform.position, this.transform.forward * distanceToSee, Color.magenta);
if (Physics.Raycast(this.transform.position, this.transform.forward, out whatIhit, distanceToSee))
{
if (Input.GetKeyDown (KeyCode.E))
{
Debug.Log("I picked up a " + whatIhit.collider.gameObject.name);
if (whatIhit.collider.gameObject.name == "Cube1")
{
// auf die Light component zugreifen und zwischen enable & disable switchen
myLightComponent.enabled = !myLightComponent.enabled;
}
}
}
}
}
I think you’re pretty close. Right now you have
if (whatIhit.collider.gameObject.[URL='http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=name']name[/URL] == "Cube1")
when it sounds like you want:
if (whatIhit.collider.gameObject.CompareTag("Collectible"))
After that, I’m not sure whether your “myLightComponent” is a standard Unity “Light” (like a Point Light), or a custom component you’ve added to the object. Either way, you’d do something like this after you find your hit:
var myLight = whatIhit.collider.gameObject.GetComponentInChildren(typeof(Light));
myLight.enabled = true;
// Or....if it's a LightComponent class you made:
var myLightComponent = whatIhit.collider.gameObject.GetComponent<LightComponent>();
myLightComponent.lightUp(); // Or whatever method on your Light Component makes it glow.
As a side note, you could also consider lighting up the object (or having some effect) merely if the Raycast hit is successful. Kind of like a “mouse hover” event on an object, so the player knows it’s something they can interact with.