- Home /
How can I get a character to patrol and follow terrain?
I've seen many forum posts and answers related to parts of this question, but I can't seem to get it to work together properly. I have a character that I want to patrol waypoints and follow the terrain while doing so. I have patrolling waypoints working, but really only if the Y value of each waypoint is the same. My thought is to have the AI patrol the waypoints based only on the x-z plane and ignore the y value, and use raycasting during update to keep it on and aligned with the terrain. Not sure what to do really.
Here's what I have so far:
using UnityEngine;
using System.Collections;
public class PatrolWaypoints : MonoBehaviour {
public Transform[] waypoints; // The amount of Waypoint you want
public float patrolSpeed = 3; // The walking speed between Waypoints
public bool loop = true; // Do you want to keep repeating the Waypoints
public Transform player; // Referance to the Player
public float dampingLook = 6.0f; // How slowly to turn
public float pauseDuration = 0; // How long to pause at a Waypoint
private float curTime;
private int currentWaypoint = 0;
private CharacterController controller;
void Awake() {
}
void Start() {
controller = GetComponent<CharacterController>();
}
void Update() {
RaycastHit hit;
if (Physics.Raycast(transform.position, -transform.up, out hit)){
transform.position = new Vector3(transform.position.x, hit.point.y, transform.position.z);
transform.up = hit.normal;
}
if (currentWaypoint < waypoints.Length) {
Patrol();
} else {
if (loop) {
currentWaypoint = 0;
}
}
}
void Patrol() {
Vector3 target = waypoints[currentWaypoint].position;
//target.y = transform.position.y; // Keep waypoint at character's height
Vector3 moveDirection = target - transform.position;
if(moveDirection.magnitude < 0.5) { // If this number is 1 the character will jerk the last bit to the waypoint and not be over it
// any lower and the character will get stuck for a second over the waypoint on the iPhone
if (curTime == 0) {
curTime = Time.time; // Pause over the Waypoint
}
if ((Time.time - curTime) >= pauseDuration){
currentWaypoint++;
curTime = 0;
}
} else {
//transform.LookAt(target); // Use this instead of below to look at target without damping the rotation
// Look at and dampen the rotation
Quaternion rotation = Quaternion.LookRotation(target - transform.position);
transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * dampingLook);
controller.Move(moveDirection.normalized * patrolSpeed * Time.deltaTime);
}
}
}
Answer by hellaeon · Jul 25, 2013 at 10:48 PM
Hi mate, have a look at the character controller, see if it helps.
Though, it seems you don't mention a collider on your initial post - seems silly to ask but....do you have one? I would have thought a collider on your object and the terrain collider would take care of it....
I don't have a collider on it, when I try to place one, Unity tells me that it already has a character controller, and if i place a collider, it will replace the controller.
or you can add onto the collider. Dual collider component or multiple are still legal to use.
One collider could be the range to pick up items and another collider would be the range allow trigger some event. As range could differ, you would have multiple colliders, but really not needed. Doing this is just taxing and can be done with vector math But it does depending on what info you need from such a collision. If you want to just know something is there, do something math is fine, if you need to know object detail, try a collider.
I am just trying to make it move along with the terrain, so I think the character controller is enough, correct?
Your answer
Follow this Question
Related Questions
AI Field of vision 1 Answer
AI script works, when we add a blocked function it stops working HELP 0 Answers
Need Help making Pong AI beatable 1 Answer
Collider Vision AI question. Solved! 0 Answers
AI raycasting problem 0 Answers