Bullet Move Along Contour of Land

I am trying to make a top down shooter game, in this game there is a terrain with small hills.

The bullets are shot strait out from the player.
I want to have bullets that follow the contour of the land. Actually I would like the bullets to have very similar behavior to that of a character controller and move along the terrain and to move up and down slopes and certain ones that are too great wouldnt be aloud like in chracter controller slope limit.

I would like the bullets to be able to even move up certain low slope stairs of buildings.

The problem is I am wondering if this is best accomplished with a character controller or some other form like a rigidbody or something?

If I do use a character controller, would haveing hundreds of bullets slow the game down or are character controllers not that taxing?

Would there be a way to detect with the character controller when the slope is too great so that I could destroy the bullet? Like hitting a wall.

Any advise or help is greatly appreciated!
Thanks for your time.

Anyone? Suggestions? Maybe I am missing the obvious. Please help :slight_smile:

Well I tried with a rigidbody with freeze rotation and gravity, I use this in the instantiation to make it go forward: bullet1.rigidbody.AddForce(transform.forward * 600)
but it slows down right away, maybe there is another way to move it forward at a constant speed when using gravity?

I tried using the character controller and when I have about 40 of them I notice it starts slowing down the game alot, down to a halt. I guess this is out of the question seeing as how I will need lots of bullets on screen.

Maybe something with my code though slowing them down, this is on the character controller:

private var myTransform : Transform;
var gv = 500.0;
private var controller : CharacterController;

function Start () {
	controller = GetComponent(CharacterController);
    myTransform = transform; //this right here makes it run faster, the game. it makes it so you dont always look up the transform
}

function Update () {
}

function FixedUpdate () {
	moveDirection = Vector3(0, 0, 1);
	moveDirection = myTransform.TransformDirection(moveDirection) * 20.0;//speed here
	
	moveDirection.y -= gv * Time.deltaTime;
	grounded = (controller.Move(moveDirection * Time.deltaTime)  CollisionFlags.Below) != 0;
}

It also has a box collider set to trigger to test if it hits something, maybe this is where I went wrong?

So I thought of a way I might be able to do this, using my regular projectiles that work fine for just shooting strait out and moving strait out maybe what I can do is raycast a ray strait down to the ground from the projectile, get the distance, and then adjust the height of the projectile based on that.

Ill give it a try hope it works!

Maybe someone else can shed some light on this topic for I have no idea if I am going about this the right way or perhaps there is a very simple solution.

If it is a top down shooter why do they need to follow the land?

Because I want to have terrain in my game and for characters to be able to move up and down stairs and hills/land, its a 3d environment, its not your average shooter, its actually a phantasy based one, so there is fireballs and what not that magically follow the contour of the land. Think of the game Avencast, that is similar to what I am trying to get, their projectiles shoot strait out from the character and move along the land and up/down stairs.

If you have an actual 3d terrain, you might just always draw the bullet at a specific height above the terrain.

As to the question of if it is a top-down shooter, why have it follow land…it might not be directly top down, but maybe at an angle, isometric? If this is the case, then it would definitely be a cool effect to fire something and have it blaze over the landscape towards its target.

But yeah…straight top down…wouldn’t be as cool eh?

[Edit] Ok…I see your response.
In that case…hmmm, not sure. I’d have to think about it some more.

Depending on how extensive your environments are…you might simply make a grid that stores this height information for your landscape/environment.

You could have each grid set 50 units apart…or 100…or whatever gives you the precision you want.
When your fireball (or whatever) needs to move across the landscape, it would travel along the grid points…interpolating between them for smoothness.

Not sure if that fits your needs or not, though.

Only downside is…it wouldn’t support very dynamic environments, where the terrain could change, etc.

With a lot of bullets this might not work very well, but I have done something like this before.

For each bullet, every frame move it up 1000 or some arbitrary high number, then Raycast down to the terrain and move it to that point + the distance you want it above the ground.

Ok I am haveing a little trouble scripting what you suggested Akoblyarek.

My code so far is this:

function OnPreRender () {    

}

function Update () {
	transform.position.y = 1000;
	var hit: RaycastHit;
	var dwn = transform.TransformDirection (Vector3(0, -1, 0));
	
	if (Physics.Raycast(transform.position,dwn, hit)) {
		if (hit.transform.CompareTag("Terrain")){
			var hitpoint = hit.point;
			transform.position = hit.point + Vector3(0,10,0);
				
		}
	}
}

When I put it in the onprerender function it does nothing and when its in update, the bullet just disapears right after I shoot it.

@jc_lvingtn

Will this work with non terrain objects where I need something like stair cases?

Woot got it to work:

function OnPreRender () {    
transform.position.y = 1000;
}

function Update () {
	var hit: RaycastHit;
	var dwn = transform.TransformDirection (Vector3(0, -1, 0));
	
	if (Physics.Raycast(transform.position,dwn, hit)) {
		if (hit.transform.CompareTag("Terrain")){
			var hitpoint = hit.point;
			transform.position = hit.point + Vector3(0,1,0);
			print ("hit");
				
		}
	}
}

I’m glad it is working for you :smile:

I didn’t have to deal with collisions when I did this, I hope they don’t make things difficult.

collisions still work just fine :slight_smile:

Great to hear. I will remember that if I need to do it again.

Cheers.