OK, the way that you are doing it picks a random direction, then asks every frame if it can move towards the unit, if it cannot it rotates a random amount. This is where your jitteryness is coming from.
Lets rewrite what I did to conform to what you have.
Lets start off easy. using the Min and Max distances from my script we rewrite the update to read like this:
function Update () {
var distance = Vector3.Distance(transform.position, target.position);
if(distance > maxDistance) return;
var rotation = transform.rotation;
transform.LookAt(target);
transform.rotation = Quaternion.Slerp(
rotation,
transform.rotation,
rotationSpeed * Time.deltaTime);
if(distance < minDistance) return;
Debug.DrawLine(transform.position, target.position, Color.yellow);
}
What this means is that if we are too far away, don’t do anything. If we are too close, only make sure that we are rotating towards the target, but don’t do anything else.
Now, the whole store a rotation, set a look and whatever else, does pretty much the same thing as what you had before, it is just written simpler.
Now, lets use the function I wrote before (with some rewrites to make it a bit more readable:
function GetHitDistance(position : Vector3, vector : Vector3, distance : float){
var r = distance;
var pos = transform.TransformPoint(position);
//Debug.DrawLine(pos, pos + transform.forward * 5, Color.red);
var vec = transform.TransformDirection(vector);
var ray = new Ray(pos, vec);
var c = Color.green;
var hits : RaycastHit[];
hits = Physics.RaycastAll(ray, distance);
for(var hit : RaycastHit in hits){
if(
hit.transform.root != transform.root
hit.transform.root != target
!hit.collider.isTrigger){
r = hit.distance;
c = Color.yellow;
break;
}
}
Debug.DrawLine(ray.origin, ray.GetPoint(r), c);
return r;
}
Basically this function checks a physics hit from a transformed point and direction over a distance. First, we are going to “shoot from the hip” so to speak. We will create two rays from the hip of the box so that we are actually checking to see if the entire box can move through the area, and not just the center of the box.
So lets change this up a bit and use that function to make it move:
function Update () {
// get and check distances
var distance = Vector3.Distance(transform.position, target.position);
if(distance > maxDistance) return;
if(distance < minDistance) return;
// store rotation
var rotation = transform.rotation;
// get ray tests
var r1 = GetHitDistance(Vector3( 0.5,0,0), Vector3.forward, 2);
var r2 = GetHitDistance(Vector3(-0.5,0,0), Vector3.forward, 2);
// if we are good for both rays move it.
if(r1 == 2 r2 == 2){
transform.position += transform.forward * moveSpeed * Time.deltaTime;
// do the rotation
transform.LookAt(target);
transform.rotation = Quaternion.Slerp(
rotation,
transform.rotation,
2.0 * Time.deltaTime);
// check the rotation and see if we should have rotated
r1 = GetHitDistance(new Vector3( 0.5,0,0), Vector3.forward, 2);
r2 = GetHitDistance(new Vector3(-0.5,0,0), Vector3.forward, 2);
if(r1 < 2 || r2 < 2) transform.rotation = rotation;
}
This now says, hey, if nothing is in front of you, move towards the target.
Now, lets complicate things a bit. If there is something in the way, lets do two raycasts at the hips pointing outward and find the one that is longer. This means that there is more space on that side. So we add this code to the end of it:
// if we are not good then lets stop and rotate
else {
// check the rays from the hips
r1 = GetHitDistance(new Vector3(-0.5,0,0), new Vector3(-0.5,0,2), 2);
r2 = GetHitDistance(new Vector3( 0.5,0,0), new Vector3( 0.5,0,2), 2);
// find the longest ray
var direction = 1;
if(r1 > r2) direction = -1;
// apply rotation
transform.Rotate(0, direction * rotationSpeed * Time.deltaTime, 0);
}
This one extends the if(r1 == 2 r2 ==2) statement and will only come into play if either hit is less than 2.
It checks two new rays from the hips and outward slightly pointing forward This checks to see if anything is to the left or right of the object. So whichever distance is higher, evidently has more space. Choose that direction and start rotating in it.
The last thing, if you are using Capsules instead of boxes is to stabilize the model in space. You can get jitteryness from the physics engine if you are constantly trying to balance between a mathematical movement and physics one. This code prevents that.
function LateUpdate(){
// stabilizer code
var euler = transform.localEulerAngles;
euler.x = 0;
euler.z = 0;
transform.localEulerAngles = euler;
rigidbody.angularVelocity = Vector3.zero;
}
That is as simple as I can make it… lol