- Home /
obstacles avoidance in C#
I am creating an AI script that is used to move my character towards an target.The complete code is given below.Some body tell me why the code is not working. I want to do in the following way
First calculate the distance depending on speed this distance use as the length of the ray cast and radius of the overlap sphere. Get all the objects in an an array and store their trasforms in other array then covert them in to local transform and check their local z if it is positive then its can be collide I also sort the list depending on their distance if you any other way to implement me let me know
Regards Zahid
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class COLLOSION : MonoBehaviour
{
public GameObject targetLookAt;
Vector3 pos;
float mindistance = 0.0f;
float ray_len = 0.0f;
List<Transform> withinrange;
GameObject[] targets;
float maxspeed = 20;
RaycastHit hit;
SphereCollider nps;
Vector3 stree;
CharacterController move;
void Start()
{
mindistance = 20;
pos = this.transform.position;
withinrange =new List<Transform>();
nps = transform.GetComponent<SphereCollider>();
stree =Vector3.zero;
move = transform.GetComponent("CharacterController") as CharacterController;
targetLookAt = GameObject.Find("targetLookAt");
}
void Update()
{
pos=transform.position;
var vel = (targetLookAt.transform.position - pos).normalized * maxspeed*Time.deltaTime;
ray_len = getlenth();
Collider []gameobjects=Physics.OverlapSphere(pos,ray_len);
foreach(Collider c in gameobjects)
{
addtolist(c.transform);
}
SortedList();
//foreach (Transform T in withinrange)
//{
// T.tag = "inRane";
//}
var left = new Vector3(-pos.x, pos.y, pos.z);
//coverts all transfroms into local
foreach (Transform t in withinrange)
{
var vs = transform.InverseTransformDirection(t.position);
Debug.Log(Vector3.Distance(pos, t.transform.position));
if (vs.z >= 0)
{
if(Physics.Raycast(pos,transform.forward,out hit,ray_len))
{
Debug.Log(hit.distance);
Debug.DrawLine(pos, hit.point, Color.red);
if (hit.transform != transform)
{
Debug.DrawLine(pos, hit.point, Color.red);
var coll = t.GetComponent<SphereCollider>();
coll.radius += nps.radius;
var co = 1 + (ray_len + hit.distance) / ray_len;
stree.x = (coll.radius - vs.x) * co;
co = 0.2f;
stree.z = (coll.radius - vs.z) * co;
stree = transform.TransformDirection(stree);
var ew = new Vector3(stree.x, 0, stree.z);
move.Move(ew + vel*maxspeed);
}
}
}
else if (Physics.Raycast(left, transform.forward, out hit, ray_len))
{
if (hit.transform != transform)
{
var coll = t.GetComponent<SphereCollider>();
coll.radius += nps.radius;
var co = 1 + (ray_len + hit.distance) / ray_len;
stree.x = (coll.radius - vs.x) * co;
co = 0.2f;
stree.z = (coll.radius - vs.z) * co;
stree = transform.TransformDirection(stree);
var ew = new Vector3(stree.x, 0, stree.z);
move.Move(ew + vel);
}
}
}
}
public float getlenth()
{
return mindistance +maxspeed;
}
void SortedList()
{
withinrange.Sort(delegate(Transform t1, Transform t2)
{
return Vector3.Distance(pos, t1.position)
.CompareTo(Vector3.Distance(pos, t2.position));
});
}
void addtolist(Transform c)
{
withinrange.Add(c);
}
}
Answer by whydoidoit · Jan 26, 2013 at 01:28 PM
I kinda get what you are trying to do - but why are you ray casting the same rays for each transform in the overlap sphere?
I'd have thought the process should be:
Get all of the colliders that are in range
foreach(var collider in Physics.OverlapSphere(pos, ray_len))
{
//Check each one here
}
Then the check is whether it is infront of you using a dot product
var direction = collider.transform.position - pos;
if(Vector3.Dot(direction.normalized, transform.forward) > 0) // Or a bigger value if you want to limit the angle to something more like a cone > 0.5 would give you 45 degrees each side of forward
{
//Do something when it is in front of you
}
Then add it to the list, but give the list more info, because your current version is doing a lot of square roots
public struct PotentialTarget
{
public Collider collider;
public float distance;
public Vector3 position;
public Vector3 direction;
}
List<PotentialTarget> targets = new List<PotentialTarget>();
//...
targets.Clear();
foreach(var collider in Physics.OverlapSphere(pos, ray_len))
{
//Check each one here
var targetPos = collider.transform.position;
var direction = targetPos - pos;
if(Vector3.Dot(direction.normalized, transform.forward) > 0) // Or a bigger value if you want to limit the angle to something more like a cone > 0.5 would give you 45 degrees each side of forward
{
targets.Add( new PotentialTarget { collider = collider, direction = direction, distance = direction.magnitude, position = targetPos });
}
}
targets.Sort((x,y)=>x.distance < y.distance ? -1 : (x.distance > y.distance ? 1 : 0));
Then you need to do something with these targets - I'm not sure what you are after there, but you can raycast the individual colliders (high speed)
foreach(var target in targets)
{
//Do something about the target
}
Your answer
Follow this Question
Related Questions
Obstacle Avoidance 0 Answers
What is the best way to avoid AI collision with my script? 0 Answers
Follow AI which avoides obstacles 1 Answer
Problem with AI dodging obstacles 1 Answer
obstacles avoidance in C# 1 Answer