- Home /
OnTriggerStay() Not Detected In Child Class
I have 2 scripts, Grabable.cs and GrabableOrb.cs. The GrabableOrb class inherits from Grabable. Grabable has an OnTriggerStay() routine and GrabableOrb does not have its own, so the inheritance just lets it use Grabable's OnTriggerStay().
In my game, there is a cube that rolls around and "grabs" an orb when the cube is both colliding with it and user is pressing the mouse button. I accomplish this by making the orb a child of the cube. When the user releases the mouse button the orb goes back to being not the cube's child (is there a word for that?) and doesn't follow the cube's rotation any more.
My problem is when the cube releases the orb, it can't grab it again, until it rolls away from and back to the orb - once the orb is released, OnTriggerStay() is no longer detected.
But! I have another object GenericGrabable which just uses Grabable.cs. The cube can grab the object, release it, and grab it again - OnTriggerStay() is detected without a problem.
So, the engine stops calling the child class' OnTriggerStay(), but the engine continues calling the parent class' OnTriggerStay(). The OnTriggerStay() method is only implemented in the parent class.
Any ideas how I can make the child class behave the same way?
Thanks!
public class Grabable : MonoBehaviour {
private bool isGrabbed;
private FixedJoint grabJoint;
protected PlayerCubeManager playerCubeManager;
void Start ()
{
playerCubeManager = PlayerCubeManager.GetSingleInstance();
}
void LateUpdate ()
{
if(isGrabbed && Input.GetMouseButtonUp(0) )
{
GetReleased();
}
}
void OnTriggerStay(Collider target)
{
if(target.gameObject.name != Constants.PLAYERCUBE_NAME)
{
return;
}
LookGrabable();
//if the cube isn't grabbing anything or is grabbing this AND it's not moving AND the player is holding the grab button
if( (!playerCubeManager.GetIsGrabbing() || playerCubeManager.GetIsGrabbingThis(GetInstanceID()) ) &&
!playerCubeManager.GetIsMoving() &&
Input.GetMouseButton(0) )
{
if(!isGrabbed) //separated from other if to keep it logical in the dev's mind
{
GetGrabbed(target.gameObject);
}
}
}
void OnTriggerExit(Collider target)
{
if(target.gameObject.name != Constants.PLAYERCUBE_NAME)
{
return;
}
LookNotGrabable();
}
protected virtual void GetGrabbed(GameObject target)
{
transform.parent = target.transform; //become a child (i.e. transform depends on parent's transform)
isGrabbed = true;
playerCubeManager.SetIsGrabbing(true, GetInstanceID());
LookGrabbed();
}
protected virtual void GetReleased()
{
transform.parent = null;
isGrabbed = false;
playerCubeManager.SetIsGrabbing(false);
LookNotGrabbed();
}
protected virtual void LookGrabable () {}
protected virtual void LookNotGrabable () {}
protected virtual void LookGrabbed () {}
protected virtual void LookNotGrabbed () {}
}
using UnityEngine;
using System.Collections;
public class GrabableOrb : Grabable
{
private float intensityNotGrabable;
private float intensityGrabable;
private float intensityGrabbed;
// Use this for initialization
void Start ()
{
playerCubeManager = PlayerCubeManager.GetSingleInstance();
Light pointLight = GetComponent<Light>();
if(pointLight != null)
{
intensityNotGrabable = pointLight.intensity;
intensityGrabable = intensityNotGrabable * 2;
intensityGrabbed = intensityGrabable * 2;
}
}
// Update is called once per frame
void Update () {}
protected override void LookGrabable()
{
Light pointLight = GetComponent<Light>();
if(pointLight != null)
{
pointLight.intensity = intensityGrabable;
}
}
protected override void LookNotGrabable()
{
Light pointLight = GetComponent<Light>();
if(pointLight != null)
{
pointLight.intensity = intensityNotGrabable;
}
}
protected override void LookGrabbed()
{
Light pointLight = GetComponent<Light>();
if(pointLight != null)
{
pointLight.intensity = intensityGrabbed;
}
}
protected override void LookNotGrabbed()
{
Light pointLight = GetComponent<Light>();
if(pointLight != null)
{
pointLight.intensity = intensityGrabable; //i.e. still grabable, but not grabbed
}
}
}
I don't think that this is an inheritance problem. Put the method in the child class and put a debug log to seen if this is really the problem. Smells like some problem with collider/rigidbody, if this is the case, take a look in http://unitygems.com/mistakes1/ , third topic.
And that's what I originally thought as well. But if I add the parent class as a component ins$$anonymous$$d of the child class, it works. If I use the child class, it doesn't detect the collision until I exit and reenter.
I discovered this by doing what you suggested, and then just putting a breakpoint immediately inside OnTriggerStay() and OnTriggerStay wasn't ever called until I exited and reentered. Unless, of course, I was using the parent class.