Obstacle avoidance make my character trembles while it moves

Hi everyone,

Well, i’m learning the basics of Unity so i created a project where i have a biped character that moves using the arrow keys or using the mouse and clicking in the terrain (like a Diablo type of game). Everything was going fine but i recently added some code that makes the character avoid obstacles (http://www.burgzergarcade.com/tutorials/javascript/obstacle-avoidance-unity-3d) and it works pretty well but the character trembles, apparently while is detecting collisions with a raycast because if the path to the target is clear, it moves ok.

Here is my code, i’ll be trying to solve it by myself of course but if somebody wants to help, i’ll be thankful.

	void Update () {
		//Evalúa input de movimiento y determina la cantidad de movimiento para este frame
		horizontal = Input.GetAxis("Horizontal") * movementSpeed * Time.deltaTime;
		vertical = (Input.GetAxis("Vertical") * movementSpeed * Time.deltaTime) * -1;
		
		if((horizontal!=0.0f)||(vertical!=0.0f)){
			movingToTarget = false;
			targetPosition = Vector3.zero;
		}
		
		if(movingToTarget){
			distanceToTarget = Vector3.Distance(targetPosition, transform.position);
			if(distanceToTarget>=2.0f){
				
				animation.CrossFade("Run");				
				moveDirection = (targetPosition - transform.position).normalized;
				
				//Detecta obstáculos al frente
				if(Physics.Raycast(transform.position, transform.forward, out hit, 20.0f)){
					if(hit.transform != transform){
						moveDirection += hit.normal * 50.0f;
					}
				}
				leftBound = transform.position;
				leftBound.x -= 12.0f;
				rightBound = transform.position;
				rightBound.x += 12.0f;
				if(Physics.Raycast(leftBound, transform.forward, out hit, 20.0f)){
					if(hit.transform != transform){
						moveDirection += hit.normal * 50.0f;
					}
				}
				if(Physics.Raycast(rightBound, transform.forward, out hit, 20.0f)){
					if(hit.transform != transform){
						moveDirection += hit.normal * 50.0f;
					}
				}
				
				//Rota hacia el objetivo
				//targetPosition.y = transform.position.y; //Evita que rote hacia arriba
				rotation = Quaternion.LookRotation(moveDirection);
				aux = Mathf.Min(rotationSpeed * Time.deltaTime, 1); 
				transform.rotation = Quaternion.Lerp(transform.rotation, rotation, aux);
				
				//Avanza hacia el objetivo
				//transform.Translate(Vector3.forward * Time.deltaTime * movementSpeed);
				controller.Move(transform.forward * Time.deltaTime * movementSpeed);
				
			}else{
				animation.CrossFade("Idle", 0.2f);
				movingToTarget = false;
				targetPosition = Vector3.zero;
			}
			
		}else{
			//Rotación y animaciones
			moveDirection = new Vector3(vertical, 0, horizontal); 
			moveDirection = moveDirection.normalized;
			if(moveDirection!=Vector3.zero){
				animation.CrossFade("Run");
				rotation = Quaternion.LookRotation(moveDirection);
				aux = Mathf.Min(rotationSpeed * Time.deltaTime, 1); 
				transform.rotation = Quaternion.Lerp(transform.rotation, rotation, aux);
			}else{
				animation.CrossFade("Idle", 0.2f);
			}

			//Movimiento
			movement.x = vertical;
			movement.z = horizontal;
			movement.y = (gravity * Time.deltaTime) * -1;
			controller.Move(movement);
		}
	}

[/code]

It’s because your character is afraid of the object.

I think i know what is the problem, now: the raycast fails in some frames so the character tries to turn itself towards the target position (the place i made click) but in the next frame, the raycast works again so it turns again (away from the obstacle). This error repeats in the next frames and provokes the shaky rotation…

Now, the problem is that i can’t figure out how to solve it. I hope somebody has an idea because i would like to keep using a simple solution and avoid using some pathfinding add-on (they are cool but a little excesive for this tiny project, i think).

Just have it remember a ray hit and lower it over time.

====
if ray hit
float turnleft 1
every frame reduce turnleft by (1 * time.deltatime)

So it smooths out the turning. It should stop most of the shakeing if there is to much then instead of (1time) do (0.5time).