x


Runtime scaling allows me to go through walls...

Hi. I'm working on a project right now and the main ability of the player is being able to grow and shrink whenever. I have no issue doing this BUT... if I grow while next to a wall my guy will go through the wall. I've tried using a raycast but I have objects in my game that have trigger colliders on them and the raycast detects the trigger. I also tried making the raycast ignore the trigger but it's attached to an object I want the player to collide with. So, if i make the raycast ignore that layer it will ignore the mesh I want the player to interact with... Please help. Thanks.

more ▼

asked Sep 22 '10 at 06:47 PM

Dr. Watson gravatar image

Dr. Watson
91 6 6 14

(comments are locked)
10|3000 characters needed characters left

1 answer: sort oldest

Your situation is such that you have some object (player or whatever) that can be scaled at runtime. When next to objects, this causes penetration as scaling will properly resize the collider of this object, but will not generate collisions. The only way I know of to resolve this is to perform a raycast and offset.

You seem to be confused about raycasts or when you're doing them. You have objects with triggers colliders and objects with regular colliders, but that really doesn't mean anything to your problem, so consider them all as colliders just the same. To restate your problem in simpler terms, you have a number of objects with colliders and you only want to raycast against some of them. This can be done either with layers or on an object by object case.

I'm sure somewhere in the 90+ questions tagged raycast, there's an answer to this, but I don't blame you for not finding it.

To raycast only against certain layers, you would supply a layermask. Different raycasts can use different layermasks. Different objects (even children and parents) can be on different layers. If you simply place the things you don't want to cast against in certain raycasts on different layers than those you wish to cast against in those raycasts, you'll be fine.

Say for example, I have a walls with colliders on Layer 9 (collision geo) and sound trigger colliders on Layer 10 (sound zones) and desks with colliders on layer 11 (interactive collision geo) and interactive zones for the desks on Layer 12 (interaction zones). If I want to shoot a gun , but not go through the walls or desks, I could raycast to those objects I wouldn't want to pass through, but not the interactive zones. So I would create a layer mask.

var mask : int = (1 << 9) + (1 << 11); //only layers 9 and 11
var range : float = 60;
var hit : RaycastHit;
var someDirection : Vector3;
if(Physics.Raycast (transform.position, someDirection, hit, range, layerMask)) {
    //do something
}

//somewhere else
//raycast against everything
if(Physics.Raycast(transform.position, someOtherDirection, hit)) {
    //do something
}

If this is not quite what you want, you may consider raycasting to the objects of importance individually, but this is a bit more expensive. You'll likely want to tag your objects for this purpose and at the very least only cast against objects within a set radius.

var newSize = 10; //get the diameter of the size you'll be scaling to somehow
var hit : RaycastHit;
var radius = newSize / 2;
var sqrRadius = radius * radius;
var surfaces = GameObject.FindGameObjectsWithTag ("Collision Surface");
for(surface : GameObject in surfaces) {
    var surfaceVector : Vector3 = surface.transform.position - transform.position;
    if(surfaceVector.sqrMagnitude < sqrRadius &&
       surface.collider.Raycast(new Ray(transform.position, surfaceVector), hit, radius))
        //offset the character
}

One thing to consider is that any offset you apply will upset the results from your raycasts because you will have just moved and you would then need to cast again to ensure that your offset didn't put you through a different object. This is where you would need to design your world and player abilities to prevent problems where you have a character being scaled into the walls on opposite sides.

Something like:

function checkWalls(size : float) : Vector3 {
    var hit : RaycastHit;
    var radius = newSize / 2;
    var sqrRadius = radius * radius;
    var surfaces = GameObject.FindGameObjectsWithTag ("Collision Surface");
    for(surface : GameObject in surfaces) {
        var surfaceVector : Vector3 = surface.transform.position - transform.position;
        if(surfaceVector.sqrMagnitude < sqrRadius &&
           surface.collider.Raycast(new Ray(transform.position, surfaceVector),
                                    hit, radius))
            return -surfaceVector.normalized * (radius - hit.distance);
    }
    return Vector3.zero;
}

var maxScaleRebouds = 3;

function Update() {
    //some stuff to tell you you're scaling...
    var offset = checkWalls(newSize);
    int i = 0;
    for(; i < maxScaleRebounds && offset != Vector3.zero; i++) {
        transform.position += offset; //This may change depending how you're moving
        offset = checkWalls(newSize);
    }
    if(i == maxScaleRebouds && offset != Vector3.zero)
        Debug.Warning("Max scale rebound reached and still inside a surface. Fix it!");
}

Remember only to do your scaling raycasting when you're scaling up (and maybe down, depending on your use case).

more ▼

answered Sep 22 '10 at 08:02 PM

skovacs1 gravatar image

skovacs1
10k 11 25 91

I can give you a better example of what's going on if you go to http://www.wyldstallynsgames.com then in Development Journal watch update 2 you will see what I'm trying to achieve. I got that you can set the ignore layers but I ran into a problem with my vacuums because when you get in the suction area(trigger collider that's attached to the parent of all aspects of the vacuum) it moves you based on the vacuum's position/direction. So if I put the vacuum's layer to ignore raycasts, which has the trigger collider and the mesh I still want the player to interact with, won't the raycast ignore the mesh?

Sep 22 '10 at 08:16 PM Dr. Watson

Thanks for the beefy response XD

Sep 22 '10 at 08:17 PM Dr. Watson

I never said anything about the ignore raycast layer. I said to use a layer mask or to raycast selectively. In my layer mask example, the vacuums would be like my Layer 12 against which I do not raycast in that example, but could easily raycast against in subsequent raycasts by using a mask that included that layer or without using a mask at all. A layer mask only affects the raycast to which you pass it. The raycast for the scaling would ignore the triggers because of the mask while any other raycast without the mask would not.

Sep 23 '10 at 01:57 PM skovacs1

Ok thanks I'll see if that will do the trick!

Sep 23 '10 at 03:32 PM Dr. Watson
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x2482
x1525
x81

asked: Sep 22 '10 at 06:47 PM

Seen: 1079 times

Last Updated: Sep 22 '10 at 06:47 PM