I'm currently using a raycast obstacle avoidance solution that I cobbled together, and it works okay, but has a few problems.
Chief among them is that when my AI object is avoiding, it is very jittery. I know exactly why its jittery, because I'm adding the hit.normal (multiplied by a modifier) of the raycast to my target direction for my eventual slerp, so the frames that the AI is avoiding the target direction is instantly changed, resulting in a jitter.
I know I need to probably Vector3.Lerp my avoidance direction (the original target direction plus the offset from the raycast hit.normal) and my original target direction, I just have no idea where to put it!
Here's my whole script in its current incarnation:
var rayLength : float = 10.0;
private var rayArray : Vector3[];
function Start(){
rayArray = new Vector3[3];
}
function MoveTowardsAndAvoid(target : Transform, speed : float, rotSpeed : float){
var targetPos : Vector3 = target.position;
targetPos.y = transform.position.y; //set y to zero so we only rotate on one plane
var targetDir : Vector3 = targetPos - transform.position;
rayArray[0] = transform.TransformDirection(-0.20,0,0.5); //ray pointed slightly left
rayArray[2] = transform.TransformDirection(0.20,0,0.5); //ray pointed slightly right
rayArray[1] = transform.forward; //ray 1 is pointed straight ahead
//loop through the rays
for (i=0; i<3; i++) {
var hit : RaycastHit;
// if you hit something with the ray......
if (Physics.Raycast (transform.position, rayArray*, hit, rayLength)) {*
*Debug.DrawLine(transform.position, hit.point, Color.magenta);*
_targetDir += 50*hit.normal;_
*}*
*}*
*// rotation and movement code*
*var targetRotation = Quaternion.LookRotation(targetDir);*
_transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotSpeed*Time.deltaTime);_
_transform.Translate(Vector3.forward*Time.deltaTime*speed);_
*}*
*```*
*<p>Any ideas?</p>*
Did you end up solving this Derek? I'm having the a very similar problem using a single raycast to rotate a gameobject based on the hit.normal and Quaternion.LookRotation(dir). It gets quite jittery only during the obstacle avoidance, otherwise it's very smooth. I have posted a question about it here: <a href="http://answers.unity3d.com/questions/225442/how-to-apply-dampening-to-hit-normal-based-rotatio.html">How to apply dampening to hit normal based rotation?</a> Would really appreciate some help about this from someone, or even an alternative approach.
var rayLength : float = 10.0;
var lerpSpeed : float = 1.0;
var theTarget : GameObject;
var mult : float = 1.0;
var speed : float = 1.0;
var rotSpeed : float = .15;
private var rayArray : Vector3[];
private var lerpedTargetDir : Vector3;
function Start(){
rayArray = new Vector3[3];
}
function Update(){
MoveTowardsAndAvoid(theTarget.transform);
}
function MoveTowardsAndAvoid(target : Transform){
var targetPos : Vector3 = target.position;
targetPos.y = transform.position.y; //set y to zero so we only rotate on one plane
var targetDir : Vector3 = targetPos - transform.position;
rayArray[0] = transform.TransformDirection(-0.20,0,0.5); //ray pointed slightly left
rayArray[2] = transform.TransformDirection(0.20,0,0.5); //ray pointed slightly right
rayArray[1] = transform.forward; //ray 1 is pointed straight ahead
moveIt = false;
//loop through the rays
for (i=0; i<3; i++) {
var hit : RaycastHit;
// if you hit something with the ray......
if (Physics.Raycast (transform.position, rayArray*, hit, rayLength)) {*
*Debug.DrawLine(transform.position, hit.point, Color.magenta);*
_targetDir += mult * hit.normal;_
*} else {*
*moveIt = true;*
*}*
*}*
*// rotation and movement code*
_lerpedTargetDir = Vector3.Lerp(lerpedTargetDir,targetDir,Time.deltaTime * lerpSpeed);_
*var targetRotation = Quaternion.LookRotation(lerpedTargetDir);*
_transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotSpeed*Time.deltaTime);_
_if(moveIt){ transform.Translate(Vector3.forward*Time.deltaTime*speed); }_
*}*
*```*
Nah, I tried something basically just like this (and just tried yours just to be safe). It bounces slowly bounces back and fourth slowly now, like a more pronounced jitter.
One thing you might try is to respond only to one of the raycasts, rather than (potentially) to all three. For example, you could respond to the closest one, or to the one for which the normal is most aligned towards the agent.
I'd also recommend consulting the literature on steering behaviors (or reviewing it, if you've already covered that material). These behaviors are all pretty well defined, and you can find example implementations in libraries such as OpenSteer, UnitySteer etc. By looking at how it's done elsewhere (or just reading the description in the 'canonical' paper on the subject) and comparing it to what you're doing, you should be able to figure out what's causing the problem.
Sorry to be a little vague, but to offer a specific suggestion I'd probably have to dig into the code myself. In the meantime though, perhaps the above suggestions will be of some help.
The documentation for UnitySteer seems deliberately obtuse or borderline nonexistent, but I would love to use it if I could. It doesn't seem too easy to implement into your own AI scripts without being forced to use their vehicle scripts and code around it.
What if you put the 'move' stuff in Update() and the 'find' stuff in LateUpdate()?
What do you mean? If the move/rotate stuff was in Update() and I need to modify the targetDir of my rotation slerp when I hit an obstacle, how would I modify the rotation after it already happened?
Did you end up solving this Derek? I'm having the a very similar problem using a single raycast to rotate a gameobject based on the hit.normal and Quaternion.LookRotation(dir). It gets quite jittery only during the obstacle avoidance, otherwise it's very smooth. I have posted a question about it here: <a href="http://answers.unity3d.com/questions/225442/how-to-apply-dampening-to-hit-normal-based-rotatio.html">How to apply dampening to hit normal based rotation?</a> Would really appreciate some help about this from someone, or even an alternative approach.
– Hamesh81