Building a bot
From OpenSimulator
(New page: Bots (or Non-Player Characters (NPCs) represent instances where, instead of a user controlling an agent represented as an avatar in-world, a program controls the agent. This facility allow...) |
|||
Line 37: | Line 37: | ||
public static Vector3 pos = new Vector3(); | public static Vector3 pos = new Vector3(); | ||
public static int turn_count = 0; | public static int turn_count = 0; | ||
− | + | // How far, in meters, the target AV can go before we start moving | |
− | + | private static float followDistance = 3; | |
− | public static | + | // A boolean switch to enable or disable following |
+ | public static bool followon = false; | ||
+ | // This is the name of the agent to follow | ||
+ | public static string followName = "FirstName LastName"; | ||
public static void Main() | public static void Main() | ||
{ | { | ||
Line 56: | Line 59: | ||
client.Appearance.SetPreviousAppearance(false); | client.Appearance.SetPreviousAppearance(false); | ||
} | } | ||
− | public static void Objects_OnObjectUpdated(Simulator simulator, ObjectUpdate update, ulong regionHandle, ushort timeDilation) | + | public static void Objects_OnObjectUpdated(Simulator simulator, ObjectUpdate update, |
+ | ulong regionHandle, ushort timeDilation) | ||
{ | { | ||
if (followon == true) //Check to make sure we need to be following | if (followon == true) //Check to make sure we need to be following | ||
{ | { | ||
− | + | //Exit this event if it's not an avatar update | |
+ | if (!update.Avatar) { return; } | ||
Avatar av; | Avatar av; | ||
client.Network.CurrentSim.ObjectsAvatars.TryGetValue(update.LocalID, out av); | client.Network.CurrentSim.ObjectsAvatars.TryGetValue(update.LocalID, out av); | ||
Line 78: | Line 83: | ||
if (pos.Z > 1) | if (pos.Z > 1) | ||
{ | { | ||
− | client.Self.AutoPilotLocal(Convert.ToInt32(pos.X), Convert.ToInt32(pos.Y), pos.Z); | + | client.Self.AutoPilotLocal(Convert.ToInt32(pos.X), |
+ | Convert.ToInt32(pos.Y), pos.Z); | ||
} | } | ||
else | else | ||
Line 99: | Line 105: | ||
System.Threading.Thread.Sleep(3000); | System.Threading.Thread.Sleep(3000); | ||
followon = true; | followon = true; | ||
− | client.Objects.OnObjectUpdated += new ObjectManager.ObjectUpdatedCallback(Objects_OnObjectUpdated); | + | client.Objects.OnObjectUpdated += new |
+ | ObjectManager.ObjectUpdatedCallback(Objects_OnObjectUpdated); | ||
} | } | ||
} | } | ||
} | } |
Revision as of 21:13, 17 December 2008
Bots (or Non-Player Characters (NPCs) represent instances where, instead of a user controlling an agent represented as an avatar in-world, a program controls the agent. This facility allows one to program humanoid figures for a variety of tasks. There are two ways that bots can be coded: on a client or on the server where opensim is running. This tutorial covers only the former case: running code on the client, which coincidentally may be the same computer where the server is located.
The following example is called "MyPetBot" and by building this source, and running the resulting bin\MyPetBot executable that results in the bot logging into the world, and then proceeding to follow whatever avatar is specified inside the code.
A short video is shown here
// Need to add the following References if using VC# 2008: // OpenMetaverse, OpenMetaverseTypes, System // These can be found in your opensim\bin folder using System; using System.IO; using System.Collections.Generic; using System.Text; using OpenMetaverse; namespace MyPetBot {
class MyPetBot { public static GridClient client = new GridClient(); // Enter the name of the agent that you wish to treat // as a bot. For example" Test User" // Also enter the login password for this agent private static string first_name = "Test"; private static string last_name = "User"; private static string password = "test"; // Specify where the bot is to be logged in public static Vector3 startLoc = new Vector3(128, 128, 22); public static Vector3 pos = new Vector3(); public static int turn_count = 0; // How far, in meters, the target AV can go before we start moving private static float followDistance = 3; // A boolean switch to enable or disable following public static bool followon = false; // This is the name of the agent to follow public static string followName = "FirstName LastName"; public static void Main() { // Enter the region name where the bot will log in string startLocation = NetworkManager.StartLocation("Your Region", (int) startLoc.X,(int) startLoc.Y,(int) startLoc.Z); client.Network.OnConnected += new NetworkManager.ConnectedCallback(Network_OnConnected); LoginParams loginParams = new LoginParams(); loginParams.FirstName = first_name; loginParams.LastName = last_name; loginParams.Password = password; // Enter the URI for your region (either a dot-decimal IP or domain name loginParams.URI = "http://yourserverIP:9000"; client.Network.Login(loginParams); Console.WriteLine("Bot Login Message: " + client.Network.LoginMessage); client.Appearance.SetPreviousAppearance(false); } public static void Objects_OnObjectUpdated(Simulator simulator, ObjectUpdate update, ulong regionHandle, ushort timeDilation) { if (followon == true) //Check to make sure we need to be following { //Exit this event if it's not an avatar update if (!update.Avatar) { return; } Avatar av; client.Network.CurrentSim.ObjectsAvatars.TryGetValue(update.LocalID, out av); if (av == null) return; if (av.Name == followName) { pos = av.Position; if (Vector3.Distance(pos, client.Self.SimPosition) > followDistance) { int followRegionX = (int)(regionHandle >> 32); int followRegionY = (int)(regionHandle & 0xFFFFFFFF); int followRegionZ = (int)(regionHandle); ulong x = (ulong)(pos.X + followRegionX); ulong y = (ulong)(pos.Y + followRegionY); turn_count++; if (turn_count%10 == 1) client.Self.Movement.TurnToward(pos); if (pos.Z > 1) { client.Self.AutoPilotLocal(Convert.ToInt32(pos.X), Convert.ToInt32(pos.Y), pos.Z); } else { client.Self.AutoPilotCancel(); } } else { turn_count = 0; client.Self.Movement.TurnToward(pos); } } } } static void Network_OnConnected(object sender) { Console.WriteLine("The bot is connected"); client.Self.Movement.AlwaysRun = false; System.Threading.Thread.Sleep(3000); followon = true; client.Objects.OnObjectUpdated += new ObjectManager.ObjectUpdatedCallback(Objects_OnObjectUpdated); } }
}