- Home /
View entire object when on intersection of wall
I am building a game where there are many walls surrounding the player. He is fighting and one of the weapons is a grenade that can land on walls and blow up when he presses a button. However, when these grenades hit the intersection of my wall, the player can only see half of the grenade or half the grenade is not attached to any wall.
How can make it so that the grenade is always touching the visible part of the wall and does not go through it or lay over of it AND if it does happen to go over, move the grenade so it looks like it is on the wall. I am trying to make something similar to the grenades you can throw in NOVA 2. Thanks for any help.
Here is the code that I already have. It is similar to the codes used on the machine gun that comes with unity.
function FireBig () {
var direction = transform.TransformDirection(Vector3.forward);
var hit : RaycastHit;
// Did we hit anything?
if (Physics.Raycast (transform.position, direction, hit, range)) {
// Apply a force to the rigidbody we hit
if (hit.rigidbody)
hit.rigidbody.AddForceAtPosition(force * direction, hit.point);
// Place the particle system for spawing out of place where we hit the surface!
// And spawn a couple of particles
if(hit.collider.CompareTag("Wall")){
if (BigGrenade){
BigGrenade.transform.position = hit.point;
BigGrenade.transform.rotation = Quaternion.FromToRotation(Vector3(-100,0,1) , hit.normal);
}
}
if(hit.collider.CompareTag("NotWall"))
{
if (hitParticles) {
hitParticles.transform.position = hit.point;
hitParticles.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
hitParticles.Emit();
}
} // Send a damage message to the hit object
hit.collider.SendMessageUpwards("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver);
}
bulletsLeft--;
// Register that we shot this frame,
// so that the LateUpdate function enabled the muzzleflash renderer for one frame
m_LastFrameShot = Time.frameCount;
enabled = true;
// Reload gun in reload Time
if (bulletsLeft == 0)
Reload();
}
How are you doing the 'hit', physics, script?? Can you post some code? I suspect you'd want to adjust the collision volumes on your walls and grenades
The colliders on your walls, expand their size (if it's a box, make the box sizes larger). If sphere, make larger radius. But I did assume you were lerp or slerping in (movement over time), which would detect the hit on the outer edges. Instant fire is harder.
Sorry, I think I missed in important part in asking the question. How would you make it so that if the grenade hit a wall intersection, it would automatically move enough in any direction to be seen fully. I know I could specify the exact coordinates on the wall I want the grenade to move to, but then I would need to do that on every wall and on every level.
Answer by Macdude2 · Feb 02, 2011 at 06:04 AM
This was what I was looking for...
function FireRed () {
var direction = transform.TransformDirection(Vector3.forward);
var hit : RaycastHit;
// Did we hit anything?
if (Physics.Raycast (transform.position, direction, hit, range)) {
// Apply a force to the rigidbody we hit
if (hit.rigidbody)
hit.rigidbody.AddForceAtPosition(force * direction, hit.point);
// Place the particle system for spawing out of place where we hit the surface!
// And spawn a couple of particles
if(hit.collider.CompareTag("Wall")){
wallSizeY = hit.transform.localScale.z;
wallSizeX = hit.transform.localScale.x;
maxdistX = wallSizeX *.5 - 1;
maxdistY = wallSizeY *.5 - 1.6; // distance from the center of the wall to 2 away from the outside
dist = Mathf.Abs(hit.point.y - hit.transform.position.y); //distance (y) from hit point to the center of wall
distX = Mathf.Abs(hit.point.x - hit.transform.position.x);
distZ = Mathf.Abs(hit.point.z - hit.transform.position.z);
print(distZ + " " + maxdistX);
if(dist > maxdistY){
if(hit.point.y < hit.transform.position.y){
newposition = hit.point.y + (dist - maxdistY);
}
if(hit.point.y > hit.transform.position.y){
newposition = hit.point.y - (dist - maxdistY);
}
}
if(hit.transform.rotation.y == 0){
if(distX > maxdistX){
if(hit.point.x < hit.transform.position.x){
newpositionX = hit.point.x + (distX - maxdistX);
}
if(hit.point.x > hit.transform.position.x){
newpositionX = hit.point.x - (distX - maxdistX);
}
}
}
if(hit.transform.rotation.y == -.5 || hit.transform.rotation.y == .5 ){
if(distZ > maxdistX){
if(hit.point.z < hit.transform.position.z){
newpositionZ = hit.point.z + (distZ - maxdistX);
}
if(hit.point.z > hit.transform.position.z){
newpositionZ = hit.point.z - (distZ - maxdistX);
}
}
}
if(dist < maxdistY){
newposition = hit.point.y;
}
if(distX < maxdistX){
newpositionX = hit.point.x;
}
if(distZ < maxdistX){
newpositionZ = hit.point.z;
}
if (RedPortal){
Red.transform.position.y = newposition;
Red.transform.position.x = newpositionX;
Red.transform.position.z = newpositionZ;
Red.transform.rotation = Quaternion.FromToRotation(Vector3(-100,0,1) , hit.normal);
}
}
if(hit.collider.CompareTag("NotWall"))
{
if (hitParticles) {
hitParticles.transform.position = hit.point;
hitParticles.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
hitParticles.Emit();
}
} // Send a damage message to the hit object
hit.collider.SendMessageUpwards("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver);
}
bulletsLeft--;
// Register that we shot this frame,
// so that the LateUpdate function enabled the muzzleflash renderer for one frame
m_LastFrameShot = Time.frameCount;
enabled = true;
// Reload gun in reload Time
if (bulletsLeft == 0)
Reload();
}
Answer by Bravini · Jan 30, 2011 at 04:21 PM
it seems to me you have to make the spawn point of your particles a bit far from the wall, checking direction and adding a distance on the inverse direction. Also be sure to make your particle system go "upwards" in a local rotation. This part should be easy for you to figure out. Also you need to add colliders to your particles so they don't go through the wall. Something like this (untested) should work :
var particles = particleEmitter.particles; for (var i = 0; i < particles.Length; i++) {
<p>particles[i].AddComponent ("SphereCollider");</p>
<p>}</p>
Answer by Bunny83 · Jan 27, 2011 at 09:50 AM
To pull the grenade out of the wall you need to adjust the hitpoint you get from the hit along the hitnormal.
if (BigGrenade){
BigGrenade.transform.position = hit.point + hit.normal*2;
[...]
}
Replace the "2" by the size of your grenade or put a public variable in your script so you can adjust it.
What confuses me a bit is your BigGrenade reference. It seems you just have a single grenade in your level. Does that mean you can place just one "sticky grenade" at a time?
Another thing: why do you use a instant hit script for a grenade launcher? Why not using a ballistic or at least a moving grenade. That way you can give your grenade a sphere collider with rigidbody and when it hits the wall (OnCollisionEnter()) you just freeze it inplace.
I did not see any difference when I added that script. Is there any way I could measure the distance from the hit point to the end of the wall so I can make sure that value is not less than the width of my grenade?
What distance? the hit point is ON the wall that means the distance between your hitpoint and the wall is 0. What i've done is to move the point away from the wall along the hitnormal (the vector points away from the wall). http://en.wikipedia.org/wiki/Normal_vector
Your answer
Follow this Question
Related Questions
Car Hit Wall And Continue 2 Answers
Disable car bounce Wall (Car Hit Wall) 0 Answers
rigidbody Hitting wall question ? 0 Answers
Making My Character Stop When It Hits A Wall 2 Answers
Object inside another object 2 Answers