Characters fall during handling ( RTS Game )

I’m trying to create a RTS like game.

But i’m having problens with my units, every time I try to move them through treacherous terrain, my units fall back.

I try to change every time the Y rotation but this don’t work too.

Have some way to solve this?

Thanks

Can you be a little more specific.
Describe the treacherous terrain.
Is it steep?
Does it have special properties?
Describe “fall back”.
What Y rotation are you changing?

Yes, is like a small hill.

No is a normal terrain.

When they try to move up on a Hill, the gravity push down, doing they falling to back.

I try to change the rotation with a Vector3, to try standing my units.

OK, so lets look at how your units are constructed. are they sphere’s or capsules?
What type of locomotion are you using?
Being an RTS, why are you using physics to move your units around? This could easily be done by using a grid system and vertical line intersects.
Does the unit know it can’t go up the hill? (dumb question but this is a pathing thing)
You are aware that Y is up, and if you rotate along the Y axis, you are turning them around, not pulling them up.

Look up LineCast and ScreenPointToRay. As your units move, they can always have a rotation of 0,facing,0 or use the normal information from a LineCast of their position to the ground. (Like vehicles. Far simpler then making wheels and rigid bodies for one.)

I use Box

I Apply acelleration to move them.

Something Like This:

function FixedUpdate() {
	switch (moveMode)  {
		case MoveModeType.STOP:
			anima = false;
			engineForce -= brakeForce * Time.deltaTime;
			if (engineForce < 0) {
				engineForce = 0;
			}
			// no pitchforce if we stop!
			pitchForce = 0.0;
			break;
		case MoveModeType.FORWARD:
			anima = true;
			engineForce += UnitManager.GetInstance().accelerationForce[TipoUnidade] * Time.deltaTime;
			if (engineForce > maxEngineForce) 
			{
				engineForce = maxEngineForce;
			}
			
			var pitchAngle = transform.localEulerAngles.x;
			if (pitchAngle > 180) {
				// vehicle's nose is up, value is below 360°. Normalize to -x degree.
				pitchAngle = -(360 - pitchAngle); // now normalized to (+/-)0-x degree
			}
			pitchForce = maxEngineForce * pitchAngle / 100.0;
			break;
	}

	transform.Translate(Vector3.forward * Time.deltaTime * (engineForce + pitchForce));
}

Because i find a Tutorial using this way, have some example?

Yes, i build the terrain and the grid this way, in the end of a level the player and the AI need to go up a hill.

I don’t know that :shock::shock:
But anyway my code doesn’t work, don’t rotate the unity. Maybe i do this in the wrong way.
I don’t know waht axis i need to rotate :smile:.

I don’t undestad this. Have Examples?

This is my game:
http://wolfnime.com/Projects/Triforce/Version 0.5.2.html

if you only watch the AI move, you will see some times they fall back.

Edit:
If i do something like this?

function Update()
{
  Unit.Transform.Rotate(Vector3.up);
}

pretty interesting. Are you using physics to move the blocks? If so, you may need to use the angle of ascent to add more force to a unit. Check out this code and see if it makes any sense. I put it on a vehicle I am driving and it basically shows me the angle - or + of the X axis. You can use the ABS of the result would be the force needed to propel them (extra force for going up, less for going down. You can Clamp the force if you dont want them to go up too steep a slope.

var x=transform.rotation.eulerAngles.x;
if(x>180)x-=360;
print(-x);

I will try this and post the resut.
Maybe i will need more help.

I don`t know how to put this to work.

I try some ways and this is the last one:

	var NewEuler:Vector3 = transform.rotation.eulerAngles;

	if(NewEuler.x > 15)
	{
		
		if(NewEuler.x > 180)
		{
			NewEuler.x-=360;
		}
		
		NewEuler.x = Mathf.Abs(NewEuler.x);

		NewEuler.x = 15;
	}

        transform.rotation.eulerAngles = NewEuler;

But if this way the code bug and the units crash on x rotation.

and if i try other way, the units don`t go up the hills:

	var NewEuler:Vector3 = transform.rotation.eulerAngles;

        NewEyler.x = 0;

        transform.rotation.eulerAngles = NewEuler;

Some one have a solution to this problem?

I find a Way to fix that problem.

You need to set the Box Collider of the unit to Trigger and than in my Vehicle Class:

function Update()
{
        //Get a Position near the Ground
	transform.position = getTerrainPosition(transform.position,DebugUnidade);

	//Move the unit up because on Unity the point 0 is in the middle of the Model, and i don't find a way to get the Bouding Box Width and Heigth
	transform.position.y += 2.56;

       //All the code Come Here
}

And Here i do the magic to get the position near the ground:

function getTerrainPosition(Posicao:Vector3,DebugNow:boolean)
{

	var newPosition = Posicao;
	var Procura:boolean = true;
	
	var TerrainLayerNew = 1 << 8;
	
	var hit : RaycastHit;
	
	if (Physics.Raycast (newPosition, -Vector3.up, hit,100,TerrainLayerNew)) 
	{
		if(DebugNow)
		{
			print("Pt2 = "+hit.collider.name);
		}

		newPosition = hit.point;
	}
	else
	{
		if (Physics.Raycast (newPosition, Vector3.up, hit,100,TerrainLayerNew)) 
		{
			if(DebugNow)
			{
				print("Pt3 = "+hit.collider.name+" - "+TerrainLayer.value+" - "+hit.collider.gameObject.layer);
			}
			
			newPosition = hit.point;
		}
	}
	
	return newPosition;
}

And in this funcion i do a RayCast up and down to find the terrain and return the position near the ground.

With this way i can move my units, without physics problem and without change alot my code.

Obs: I need to set the max distance to the Raycast because the unit ignore the Layer Filter if you set this to unlimited distance.

Obs 2: With this way i get a collision problem the all the units iguinore the colision between then, this mean more work.