- Home /
[VRTK] CameraRig object keeps blocking Linecasts regardless of layermasking
So I've been making a game using VRTK and I've run into a strange problem while attempting to set up some basic AI target aquisition. The script I'm using for detection:
using UnityEngine;
using System.Collections;
namespace G5
{
public class Enemy_Detection : MonoBehaviour
{
private Enemy_Master enemyMaster;
private Transform myTransform;
public Transform head;
public LayerMask playerLayer;
public LayerMask sightLayer;
public float checkRate = .1f;
private float nextCheck;
public float detectRadius = 80;
private RaycastHit hit;
public string[] playerTag;
public float hearingRadius;
public float fov = 75;
public Collider[] colliders;
void OnEnable()
{
SetInitialReferences();
enemyMaster.EventEnemyDie += DisableThis;
}
void OnDisable()
{
enemyMaster.EventEnemyDie -= DisableThis;
}
void Update()
{
CaryOutDetection();
}
void SetInitialReferences()
{
enemyMaster = GetComponent<Enemy_Master>();
myTransform = transform;
fov = Mathf.Cos (fov * Mathf.Deg2Rad);
if(head == null)
{
head = myTransform;
}
}
void CaryOutDetection()
{
if(Time.time > nextCheck)
{
nextCheck = Time.time + checkRate;
colliders = Physics.OverlapSphere(myTransform.position, detectRadius, playerLayer, QueryTriggerInteraction.Ignore);
if(colliders.Length > 0)
{
foreach(Collider potentialTargetCollider in colliders)
{
foreach(string tag in playerTag)
{
if(potentialTargetCollider.CompareTag(tag))
{
if(CanPotentialTargetBeSeen(potentialTargetCollider.transform))
{
break;
}
}
}
}
}
else
{
enemyMaster.CallEventEnemyLostTarget();
}
}
}
bool CanPotentialTargetBeSeen(Transform potentialTarget)
{
CapsuleCollider offsetCol = potentialTarget.GetComponent<CapsuleCollider> ();
Vector3 offset = potentialTarget.position + offsetCol.center;
if(Physics.Linecast(head.position, offset, out hit, sightLayer))
{
Debug.Log (hit.transform.gameObject.name);
Debug.DrawLine (head.position, offset);
if((hit.transform.gameObject == potentialTarget.gameObject && (Vector3.Dot(head.forward, (potentialTarget.position - head.position).normalized)) >= fov) ||
Vector3.Distance(head.position, potentialTarget.position) < hearingRadius)
{
enemyMaster.CallEventEnemySetNavTarget(potentialTarget);
return true;
}
else
{
enemyMaster.CallEventEnemyLostTarget();
return false;
}
}
else
{
enemyMaster.CallEventEnemyLostTarget();
return false;
}
}
void DisableThis()
{
this.enabled = false;
}
}
}
sends out a spherecast to find the auto-generated collider container that represents the player and then performs a linecast to make sure that line of sight to the player is clear of obstacles. It works fine, the line cast is sent directly to the center of the player collider as it moves around the playarea. The problem is that the detection fails because it cant get past the camera rig.
The camera rig is on the default ignore raycast layer, and i have this layer set to be ignored by the layer mask. The camera rig has no collider but it does have a rigidbody because I am using VRTK locomotion scripts that require it to have one. No matter what the CameraRig blocks the linecast. I've tried changing its layer to something else also being blocked by the detection scripts layermask. The only thing that allows the detection to see past the CameraRig is removing the rigidbody from the CameraRig, which of course breaks the locomotion scripts. The linecast will not ignore the CameraRig no matter what layer it is on or what the linecasts layermask is set to.
So...does anyone have any idea what could be causing this? I'm assuming it has something to do with one or more of the VRTK scripts somehow over-riding my attempts to do a basic linecast, but I have no idea where to even start here.
Or failing that, does anyone have a suggestion for how to carry out a line of sight check for the player collider without using the linecast?
Answer by joewode · Mar 23, 2018 at 07:37 PM
So I was messing with this again this morning and figured out what the problem was. I was wrong about this being an issue caused by VRTK, it also has nothing to do with layermasking; the logic in my script was just wrong.
It seems when linecasting or raycasting (which i switched too) will return the top level object in a hierarchy with a rigidbody attached if you hit a collider on a child object and then use hit.gameObject to figure out what you hit. So my linecast wasn't being blocked at all it was simply being asked for the wrong thing. Using hit.collider to compare the colliders instead resolved the issue.
Whoops! thanks for reading I guess.