Heya
This is the patrol function from the fps tut.
function Patrol ()
{
var curWayPoint = AutoWayPoint.FindClosest(transform.position);
while (true)
{
var waypointPosition = curWayPoint.transform.position;
// Are we close to a waypoint? -> pick the next one!
if (Vector3.Distance(waypointPosition, transform.position) < pickNextWaypointDistance)
curWayPoint = PickNextWaypoint (curWayPoint);
// Attack the player and wait until
// - player is killed
// - player is out of sight
if (CanSeeTarget ())
yield StartCoroutine("AttackPlayer");
// Move towards our target
MoveTowards(waypointPosition);
yield;
}
}
I think these instructions are streamlined for use with a character controller, right? And a character controller is subject to gravity, correct?
Well this almost works for my submarine, except that it drags itself along the sea floor. What Im after is a way for my enemy to “float” toward the waypoint like a submarine. Would someone skilled recommend I scrap this general approach or is there some little command like Gravity=0; that I can add?
Let me know if I should post the entire script. I removed a bit that said:@script RequireComponent (CharacterController) and it compiles ok.
Thank you
AaronC
You probably want to move the sub yourself without using the character controller. It should be pretty simple to rotate your sub towards the next waypoint and move it forward, then set a new waypoint when it reaches the current target.
Thanks Yoggy but this is in an area where I dont really know where to start…I have been trying to learn from the Ai and Car Ai scripts …
So in the update i would as you say be wanting to rotate the object and move it forward. I was planning on using forces rather than transform manipulation for the player, but Im not sure which would be better for the AI. Probably forces also.
So
var Power: 1.0;
var AiSub: GameObject;
var MyWaypoint: GameObject;
function Update(){
Stalk();
}
function Stalk(){
//rotate towards waypoint?
AiSub, transform.Rotation= MyWaypoint, transform.Rotation;
rigidbody.AddForce (Vector3.
forward * power)
}
I guess I could have two waypoints, and a script similar to this on my AiSub twice, then have a collider or trigger on the waypoints that enables 1 instance of this script and disables the other, so when the sub hits the waypoint, it suddenly starts going to the other waypoint as the active scripts have switched over…What do you think?
AC
There are some syntax errors in your code, but you probably wrote it for an example anyhow.
You can use the LookAt() function to face the waypoint, but it will snap instantly and therefore doesn’t look very nice.
What you want to do is get a direction vector from your position to the waypoint position, and slowly turn to face it.
In vector math you get the direction vector by subtracting the target position vector from your position vector:
var myDirection = target.transform.position - transform.position;
Then you need to lerp to that new direction like this:
var targetRotation = Quaternion.LookRotation(myDirection.normalized);
var str = Mathf.Min(rotationSpeed * Time.deltaTime, 1);
transform.rotation = Quaternion.Lerp (transform.rotation, targetRotation, str);
That code may have bugs, but you get the idea. Then you move towards it how you like. (The physics engine won’t like this method, but I don’t like using the physics engine to simulate AI units for that reason.)
Thats cool Jeremy. Man, theres a lot in a simple thing huh?
This has enabled me to have an enemy sub that seeks out the player and rams you…Havent managed to get the enemy firing yet, and Im forgetting about waypoints, but this is a good start. Cheers.
The whole:var myDirection = target.transform.position - transform.position;thing makes perfect sense mathmatically but I’m still getting my head around it in 3d space…
I am interested to understand this a little better:
var str = Mathf.Min
str is a varibile we invented, right? How about the other bit?
-Only if you have time to answer my annoying questions
Thanks a million
AC
With var str I am create a vaiable named str. Then I am assigning it the returned value of the Mathf.Min function (so what Mathf.Min figures out, it puts in our str variable).
Mathf.Min simply returns the smallest of the two numbers or variables you supply.
So this line:
var str = Mathf.Min(myVar, 1);
Figures out which value is smaller (myVar or 1) and it puts the smaller one into our str variable. This is useful for making sure variables don’t go out of range (which is what we are using it for).
Really, that str thing is not essential but it makes things cleaner. The Lerp functions clamp the input between 0 and 1 before they do anything with it.
I thought Id post this incase its useful out there. Its an basic AI script for a submarine. You need to attach a rocketlauncher script(from fps tut) to a child GO of your"Sub".
var Speed = 3.0;
var rotationSpeed = 5.0;
var shootRange = 15.0;
var attackRange = 30.0;
var shootAngle = 4.0;
var dontComeCloserRange = 5.0;
var delayShootTime = 0.35;
var target : Transform;
private var lastShot = -10.0;
function Update(){
if (target == null GameObject.FindWithTag("Player")) {
target = GameObject.FindWithTag("Player").transform;
}
var targetDirection = target.transform.position - transform.position;
var forward = transform.TransformDirection(Vector3.forward);
var angle = Vector3.Angle(targetDirection, forward);
var distance = Vector3.Distance(transform.position, target.position);
var targetRotation = Quaternion.LookRotation(targetDirection.normalized);
var str = Mathf.Min(rotationSpeed * Time.deltaTime, 1);
transform.rotation = Quaternion.Lerp (transform.rotation, targetRotation, str);
if (distance < shootRange angle < shootAngle)
StartCoroutine("Shoot");
}
function Shoot ()
{
// Fire gun
BroadcastMessage("Fire");
// Wait for the rest of the animation to finish
yield WaitForSeconds(delayShootTime);
}
function RotateTowards (position : Vector3)
{
var direction = position - transform.position;
direction.y = 0;
if (direction.magnitude < 0.1)
return;
// Rotate towards the target
transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
}
function MoveTowards (position : Vector3)
{
transform.Translate (0, 0, Speed * Time.deltaTime);
}