- Home /
Camera & Sphere Collider
I'm trying to get a sphere collider working with my camera and the terrain without success. So far I've tried attaching a sphere collider + rigidbody, collider, toggling IsTrigger in both cases, etc... the problem is that when the cameras collider hits the terrain it never seems to trigger a OnCollisionEntry or OnTriggerEntry (I'm overriding both to try and catch the event).
I have even just tossed debug output to see that the collider is moving with the camera, etc... all seems well, I'm not sure what the issue is here.
Any ideas how to make a camera collider work with terrain?
Edit: Added Camera Control Script Code.
enum Axis {MouseXandY, MouseX, MouseY} var Axis : Axis = Axis.MouseXandY;
var sensitivityX = 15.0; var sensitivityY = 15.0;
var minimumX = -360.0; var maximumX = 360.0;
var minimumY = -60.0; var maximumY = 60.0;
var rotationX = 0.0; var rotationY = 0.0;
var lookSpeed = 2.0;
function OnTriggerEnter (other : Collider) { print( "OTE" ); }
function OnCollisionEnter(collision : Collision) { print( "OCE" ); }
function Update () { // allow for WSAD control of the camera
var x = Input.GetAxis( "Horizontal" ) Time.deltaTime 10.0; var z = Input.GetAxis( "Vertical" ) Time.deltaTime 10.0; transform.Translate ( x, 0, z );
// handle mouse look, only mouse look when right mouse button is used
if( Input.GetMouseButton( 1 ) )
{
// Read the mouse input axis
rotationX += Input.GetAxis( "Mouse X" ) * sensitivityX;
rotationY += Input.GetAxis( "Mouse Y" ) * sensitivityY;
// Call our Adjust to 360 degrees and clamp function
Adjust360andClamp();
transform.localRotation = Quaternion.AngleAxis( rotationX, Vector3.up );
transform.localRotation *= Quaternion.AngleAxis( rotationY, Vector3.left );
}
}
function Adjust360andClamp () { // Don't let our X go beyond 360 degrees + or - if (rotationX < -360) { rotationX += 360; } else if (rotationX > 360) { rotationX -= 360; }
// Don't let our Y go beyond 360 degrees + or -
if (rotationY < -45)
{
rotationY = -45;
}
else if (rotationY > 30)
{
rotationY = 30;
}
// Clamp our angles to the min and max set in the Inspector
rotationX = Mathf.Clamp (rotationX, minimumX, maximumX);
rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
}
Answer by skovacs1 · Jun 28, 2010 at 04:24 PM
Not sure if this question is still active, but I thought I'd try my hand at an answer. I'm relatively new to Unity, so I'm no authority on this, but I also found the collision docs somewhat ambiguous on this subject.
I can't divine the exact problem from only the details provided above so I will provide an alternate solution to using the built-in physics. I recommend you still learn the physics stuff if only for your own benefit, rather than simply taking my rough solution below by itself.
Some stuff that might help with the physics stuff
See the manual. The collision matrix should be informative.
And note the line, "Be aware that in order for two Triggers to send out trigger events when they collide, one of them must include a Rigidbody as well. For a Trigger to collide with a normal Collider, one of them must have a Rigidbody attached."
Also, when your camera has a rigidbody, is IsKinematic checked?
One solution that'll do in a pinch
Do a simple ray/line cast against only the things you care to collide with (not the camera's collider if you have one). With this solution, your camera needn't have a collider or rigidbody if you don't want them.
You should pragma strict your unityscript to cut the overhead of dynamic typing.
This is quick and untested code, but something like:
var hitInfo : RaycastHit; var layersToCollide : int = 1<<9; //Collide with layer 9 var buffer : float = 10; //Find a value that works for you
function Update () { // allow for WSAD control of the camera
var x : float = Input.GetAxis( "Horizontal" ) Time.deltaTime 10.0; var z : float = Input.GetAxis( "Vertical" ) Time.deltaTime 10.0;
var destination : Vector3 = Vector3(x,0,y) + transform.position;
if (Physics.Linecast (transform.position, destination, hitInfo, layersToCollide)) {
//If it helps, you may want to debug with Debug.DrawLine(transform.position, hitInfo.point);
//Just a quick example, but you may want to do some correction like:
var distance : float = hitInfo.distance - buffer;
var correction : Vector3 = Vector3.Normalize(x,0,y) * distance;
destination = transform.position + correction;
///Whatever else you wanted to do on collision
}
transform.position = destination;
///Other stuff
}
Great detail in your Answer! Upvote just for the accuracy ;)
Answer by james flowerdew · Sep 09, 2010 at 12:15 PM
This may be a very simple albiet weird answer to your problem... try using a charcter controller and try to "move" it to the target position instead of directly forcing it to a location with "translate". You could use a rigidBody and move a constraint, but this can be tricky, and you might get Roll and spring-back reactions. The manual says that character controllers are very efficient, so using them like this shouldn't be too harmful. I don't think that directly moving any colliders to intersect (whether they have rigid bodies or not), will necessarily register a collision and there is likely your first problem thus far.
Answer by StephanK · Apr 16, 2010 at 07:49 AM
Could you post your code? First thing that comes to mind is that the functions are called OnCollisionEnter() and OnTriggerEnter not entry. Another problem could be the way you move the camera, as for example transform.Translate won't trigger the physics (and therefore collisions).
I'm pretty sure I have the method names right, probably type-o on my part but i'll post code when I get home. Translate not triggering collisions is most likely my issue, is there a way to manually check for collisions for a given object (or its collider) and any surrounding colliders?
Any thoughts on that code spree, well, civil ones at any rate ;)?
Answer by spinaljack · May 01, 2010 at 09:11 AM
Have you tried using OnTriggerStay? You do need a non-kinematic rigidbody on one of the objects, either the camera or the wall (probably better on the camera) You can also try using the isVisible value to make the camera check if the player is visible and then move closer if he isn't.
Answer by Maclypse · Jul 04, 2010 at 10:32 AM
Not knowing the reason for using a collider on the camera, assuming the colliding camera is a solution to the problem of the camera dropping under the terrain, I'd avoid the issue altogether. Collider, or even a raycast is overkill.
If it's just a matter of keeping it above the terrain, I'd just check the height of the terrain (Terrain.SampleHeight) directly; whenever the camera got too close I'd override the user input from my script and force the camera to translate to SampleHeight+1.
Your answer