Wheel Track to Nearest

I have thought up a solution to creating vehicle traffic/ai that will be helpful for a project I am working on. The system uses separate lanes of nodes that will run along the road. Each will have a letter value (such as AA, AB, etc.) for the lane, and a number value (1-5) for the node itself. This will translate into the name of the node’s property.

The vehicles will track to node (for example) G1, until they reach it, in which case they will track to node G2. If I want them to change lanes here, then they will track to node D3. And once they hit D5, they will revert back to tracking to the nearest D1.

I probably could have saved time in saying just this: the wheel tracking thing has always evaded my grasp. How do I make a vehicle wrapper-based vehicle point its wheels at not only a target, but base that target on proximity and property?

I think you would have to get the distance from the object to each node, sort them in a list by increasing distance, and then get the first object from that list (the 0 position). That would get you the name of the closest node. But do you even need to get the nearest node? Why not just have a specified path D1, D2…D5, back to D1, with options to change lanes to the G path at each node.

I’m not entirely clear on what you’re saying. Just a guess, but do you mean why not just track straight to node D1 without tracking to nearest node with property D1?
If so, the idea for me is to create a repeating path of nodes. If I only had nodes D/G 1-5, then I would only be capable of having 5 points. However, by using properties, I could have D1-5, set one, D1-5, set two, etc. so that I would not need to have a script or logic setup for each node in the scene. That way, I could have 5, 10, 25, maybe even 50 nodes without having to mention them each in script or logic.
If that’s not what you meant, then please clarify.

By the way, is there any place I can get a track to nearest property script, preferably for 2.5x? I found Monster’s old S2A .blend, but I am making this for exportation, and I want to use as few modules as possible. Also, a little direction (no pun intended) on the steering, if at all possible.

Sort example within radar…


tmpSortDistance = []
myHitList = mySen["ChkRadar"].hitObjectList
        
for tmpHit in myHitList:
    tmpSortDistance.append((myOwn.getDistanceTo(tmpHit), id(tmpHit)))
    
tmpSortDistance.sort()

mziskandar-thanks, that’s part of it. However, I’m not much of a coder. I probably should have mentioned that earlier. Is this a whole script for finding the closest, or just part of one? If so, how do I adapt it to what I need? And will it work in 2.58?

Still coming up dry on the steering tracking, I can’t seem to find anything helpful. But I know it’s been done.

EDIT: I’m using Monster’s Vehicle Wrapper, by the way.

Okay, I managed to Frankenstein mziskandar’s code and some random bits of useful Python to form a what would be a good basis for making this script. If it actually worked.

Upon runtime, I get an error reading ‘myHitList = radar[“Radar”].hitObjectList
TypeError: ‘KX_RadarSensor’ object is not subscriptable’

Here is the code:


from bge import logic as GameLogic
c = GameLogic.getCurrentController()
own = c.owner
 
radar = c.sensors["Radar"]
 
tmpSortDistance = []
myHitList = radar["Radar"].hitObjectList
for tmpHit in myHitList:
    tmpSortDistance.append((owner.getDistanceTo(tmpHit), id(tmpHit)))
tmpSortDistance.sort()

EDIT: Nevermind, I found an old Track to Nearest script, and ported it into 2.58. Therefore, I have basically everything except for the steering system.

Now, before I add the steering code, I would like to grant the script the ability to automatically detect what sensors are present, without having to specify a sensor by name, but just a sensor by type. I would also like to give the script the ability to detect what property it should search for based on what property is in the property field of the object’s near sensor.

Here is the code so far, devoid of the above functionality (2.58).


from bge import logic as GameLogic
def GetClosest(target, prop):
    obj_list = [obj for obj in GameLogic.getCurrentScene().objects if obj.get(prop)]
    closest = obj_list[0] # Default closest
    distance = target.getDistanceTo(closest)
 
    for object in obj_list[1:]:
        new_distance = target.getDistanceTo(object)
        if new_distance < distance:
            closest = object
            distance = new_distance
    return(closest)
 
controller = GameLogic.getCurrentController()
obj = controller.owner
near = controller.sensors['Near']
prop = 'Trackable'
closest = GetClosest(obj, prop)
tracker = controller.actuators['Tracker']
tracker.object = closest
controller.activate(tracker)

Now, I tryed typing ‘near = controller.sensors(NearSensor.type)’, as was suggested by the near sensor, when hovered over, as well as the line ‘prop = near.property’/‘prop = NearSensor.property’, which also didn’t work. Adding parenthesis and brackets did little as well.
Short and sweet, how do I make these objects callable, or can I?

I tried to do some reading, searching, and learning, but am still coming up short.

Here is the current code:


from bge import logic as GameLogic
 
def GetClosest(target, prop):
    obj_list = [obj for obj in GameLogic.getCurrentScene().objects if obj.get(prop)]
    closest = obj_list[0] # Default closest
    distance = target.getDistanceTo(closest)
 
    for object in obj_list[1:]:
        new_distance = target.getDistanceTo(object)
        if new_distance < distance:
            closest = object
            distance = new_distance
    return(closest)
 
controller = GameLogic.getCurrentController()
obj = controller.owner
near = controller.sensors.NearSensor[]
prop = 'Trackable'
closest = GetClosest(obj, prop)
tracker = controller.actuators['Tracker']
tracker.object = closest
controller.activate(tracker)

I still come up with the error ‘invalid syntax’, with the square brackets at the end of the line ‘near = controller.sensors.NearSensor[]’ indicated.

You’re probably getting the error because the name of the near sensor and other sensors would generally go inside the brackets like you did with the actuator name.

Ace Dragon-I am aware of that. But that’s not the idea. The idea is to get the sensor’s name based on its type, if possible, and use that name for the functions. That way, I don’t need to have 3+ versions of the script (for the 3+ near sensors with names script-specified) running on each ai vehicle.

Okay, I have an idea as to how to make the steering portion of the script.

There is a float property on the object that regards steering. It goes from -1 (full right) to 0 (no turn) to 1 (full left). After the nearest script-specified property is found, the object will attempt to get the angle from the vehicle’s -y (the front plane of the car) to the object. The script will then assign the steering property a value of between -179 and 179, reflective of the angle (I don’t know about right behind it, I haven’t thought that part over.

Since 179/180 is such a large number in relation to the default property value of -1 to 1, the vehicle will either be doing a full right turn or full left turn unless it is within 1 degree of the exact direction. To fix this, the angle value could be divided to reduce the sharpness of the steering, e.g. 180 divided by 3 = the car will have to be 3 degrees off before hard turning in either direction.

However, as in many cases, I do not know how to do this. I have the script for detecting the closest of x-property, it’s just finding the angle and transforming that into the steering angle.

Alright, if no one has any idea as to what I’m saying, or any ideas on this topic at all, can anyone at least point me in the direction of someone that can do this sort of thing or may have successfully done this before?