Hi everyone, I’m trying to make a system that will detect all objects being hit by a ray and store them in an array, then I take that array and duplicate it into another, then I compare the arrays and if the object is no longer in the array I restore it’s alpha attribute. This is a camera fader script.
Unfortunately the script can not pick up on the fact it’s no longer being hit and I don’t know why. If there is a better way to do this, I’m all ears. Thanks for your time.
using UnityEngine;
using System.Collections;
using System.Linq;
using System.Collections.Generic;
public class CameraFader : MonoBehaviour
{
public GameObject target;
public float fadeAmount = 0.2f;
private LayerMask layerMask;
private RaycastHit[] previousHits;
private RaycastHit[] hits;
void Start()
{
target = GameObject.FindGameObjectWithTag ("CamTarget");
if(target == null)
{
Debug.LogError("No camera target detected, please correct this issue and restart");
}
}
void Update()
{
layerMask = 1 << 8;
if(previousHits != null)
{
foreach(RaycastHit h in previousHits)
{
if(hits.Contains(h))
{
Debug.Log ("exists");
}else
{
Debug.Log ("doesn't exist");
h.collider.renderer.material.color = new Color(h.collider.renderer.material.color.r, h.collider.renderer.material.color.g, h.collider.renderer.material.color.b, 1.0f);
}
}
}
Vector3 direction = (new Vector3(target.transform.position.x, target.transform.position.y - 1f, target.transform.position.z)) - transform.position;
Ray ray = new Ray(transform.position, direction);
hits = Physics.RaycastAll(ray, 10f, layerMask);
foreach(RaycastHit h in hits)
{
h.collider.renderer.material.color = new Color(h.collider.renderer.material.color.r, h.collider.renderer.material.color.g, h.collider.renderer.material.color.b, fadeAmount);
}
previousHits = hits;
}
}
The problem with your code is, that you assume two hits hitting the same object are equal to each other, that’s why you think you can use Contains like that.
Also, hits and previousHits are always the same at the start of the Update Method
I would recommend to use a generic Set (as you only need to store each faded GameObject once) and it also has nice set operations you can use (which I end up not using in my code).
This is untested code, so prepare for syntax errors, but you should get the idea:
using System.Collections.Generic;
...
private HashSet<GameObject> faded = new HashSet<GameObject>(); // currently faded GOs
private HashSet<GameObject> hitsGO = new HashSet<GameObject>(); // currently faded GOs
void Update()
{
...
Ray ray = new Ray(transform.position, direction);
hits = Physics.RaycastAll(ray, 10f, layerMask);
hitsGO.Clear();
foreach(RaycastHit h in hits) hitsGO.Add(h.collider.gameObject); // put GOs in a set
// fade only new items out
foreach(GameObject g in hitsGO) if (!faded.Contains(g))
{
Color c = g.renderer.material.color;
c.a = fadeAmount;
g.renderer.material.color = c;
faded.Add(g);
}
// fade in GOs not hit again ...
foreach(GameObject g in faded) if (!hitsGO.Contains(g))
{
Color c = g.renderer.material.color;
c.a = 1.0f;
g.renderer.material.color = c;
}
// ... and remove them from the faded list
faded.RemoveWhere(g => !hitsGO.Contains(g));
}
My first guess would be that you need to create an object array that stores the specific object references for each RaycastHit.
I’m not entirely sure how it works your approach could be correct. But I think RaycastHit determines nothing more than if the RaycastHit anything and the transform position of where it hit. I don’t think it has any way to compare hits in an array like that.
I think you’ll need to use gameObject arrays which you can get the gameObject references from each RaycastHit.
So for example if you wanted to store the RayCastHit positions you would go:
rayVector = rayHit.point;
For the object:
rayHitObject = rayHit.collider.gameObject;
Name:
stringRayName = rayHitObject.name;
Etc.
I believe as long as you have unique object references stored within those arrays it should work, but you may also need some additional logic maybe a bool to determine which objects need to fade out, etc.
That’s my best guess I really don’t do much array action but I do a lot of stuff based on RaycastHits so hopefully this somehow helpful.
You should post if you figure it out! That kind of thing would be really helpful in my game right now I’m using colliders to just stop the camera from going through certain things, but if I had a way to fade out objects in addition to the collisions that would be ideal.