0

I am working on a 3D game wherein which if the bird goes through a pipe successfully it scores a point or else it is dead.I am able to implement this very much.

Also I am spawning the pipe (which is a pre-fab)through a script. The position of the spawned pipe is in a random position in front of the bird.The code for that is as follows.This code is written in the GameControl script which takes care of the state of the game.

public class GameControl : MonoBehaviour
{
 public GameObject pipe;
 public static GameControl instance;
          ..........
          ..........
          ..........
      void Update()
        {
          ..........
          ..........
          ..........
          spawnXposition = CurrentXpositionOfBird + Random.Range(-1, 1);
          spawnYposition = CurrentYpositionOfBird + Random.Range(-1, 1);
          spawnZposition = CurrentZpositionOfBird + Random.Range(50, 100);
          SpawnPipe(spawnXposition, spawnYposition, spawnZposition);
        }
          ..........
          ..........
          ..........

   public void SpawnPipe(float x, float y, float z)
    {
        pipe.transform.position = new Vector3(x, y, z);
        CurrentZpositionOfScoringCollider = pipe.transform.position.z + 2.62f;
      
    }
}

Where SpawnPipe function is taking care of the part which is to create the pipe.I have attached pipe prefab to the pipe GameObject in the inspector.

Now here is the problem.When I spawn the pipe I don't want it to touch any part of the terrain. If it ever touches I want to respawn until I get the pipe in such a location that it is not touching the terrain. For that in the pipe prefab I have attached a script and in the OnCollisionEnter function I have destroyed the pipe. Here is the code below:

 private void OnCollisionEnter(Collision collision)
    {
       
        Destroy(GameControl.instance.pipe);
    }

The logic above is if the spawned pipe touches with the terrain, destroy it.In that case when the spawned pipe is destroyed the update function runs again to spawn a new pipe.As long as it is not colliding with the terrain,it will be spawned again and again.

But I am still able to see the pipe touching in fact ,nicely merging with the terrain. For terrain I have it is added a mesh collider and have made it a rigid body with isKinematic checked. It works perfectly when the bird hits the terrain and I am able to do display the game over message

For the pipe I have added 3 box colliders ,one at the bottom of the pipe and the other two at the sides of the pipe.When it collides with the bird,it is succesfully displaying Game Over message. But the coillision between the pipe and terrain is not getting detected .I dont know where I am going wrong.Please help. I am pretty new to Unity as well

<<<----------------------EDIT----------------------->

The link for the FBX model of the terrain

https://docs.google.com/uc?export=download&id=1kFUtPpQnopa7489i-iQwC2qEiQECbWCu

Chethan CV
  • 547
  • 1
  • 7
  • 23
  • Hit test terrain and spawn above ? – aybe Feb 25 '21 at 10:35
  • @aybe could you elaborate a bit more please – Chethan CV Feb 25 '21 at 11:09
  • @ChethanCV why don't you use [Collider.ClosestPoint](https://docs.unity3d.com/ScriptReference/Collider.ClosestPoint.html). Instead of using precious CPU power, for wastely instantiating. Use ClosestPoint and check if next point + pipe length/height etc is in the inside of terrain. This method is much precise and faster. – SeLeCtRa Feb 25 '21 at 11:20
  • @SeLeCtRa so what you means to say is that when I compute the next X,Y,Z point ,you use Vector3 closestPoint = collider.ClosestPoint(X,Y,Z); and get the closestPoint +height and check whether that lies inside the terrain or not? The point is how do you check whether the closestPoint is inside the terrain or not? I googled this but I am getting inside polygon or triangle kind of links not terrain. Also I got some to read some TerrainData.bounds unity documentation,which doesnt make any sense to me atleast....I have put the terrain FBX file in the edit section of the question – Chethan CV Feb 25 '21 at 14:14
  • Create 2 `Transform t0, t1`. Use them to identify the bounds of your plane (you can make them children of the plane Transform). Now suppose you spawn your object in a position `p`, `if(t0.position.x < p.x && p.x < t1.position.x && t0.position.y < p.y && p.y < t1.position.y && t0.position.z < p.z && p.z < t1.position.z)`, it means you are inside the plane collision area and you should try another position. – Daniel Feb 25 '21 at 14:30

0 Answers0