So I made this c# code from JS from the old fps tutorial. There r no errors but still my AI script seems not to be working(robot doesn’t move or anything). Didn’t find anything similar on the internet and now I have to ask for some help because I’ve spent tons of time trying to figure out what’s wrong.
I know there is too much code but I don’t know which part doesn’t work:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(CharacterController))]// Make sure there is always a character controller
public class AI : MonoBehaviour
{
public float speed = 3.0f;
public float rotationSpeed = 5.0f;
public float shootRange = 15.0f;
public float attackRange = 30.0f;
public float shootAngle = 4.0f;
public float dontComeCloserRange = 5.0f;
public float delayShootTime = 0.35f;
public float pickNextWaypointDistance = 2.0f;
public Transform target;
private float lastShot = -10.0f;
void Start()
{
// Auto setup player as target through tags
if (target == null && GameObject.FindWithTag("Player"))
target = GameObject.FindWithTag("Player").transform;
Patrol();
}
IEnumerator Patrol()
{
AutoWaypoint curWayPoint = AutoWaypoint.FindClosest(transform.position);
while (true)
{
Vector3 waypointPosition = curWayPoint.transform.position;
//If we're close to a waypoint, we'll go ahead and pick the next one.
if (Vector3.Distance(waypointPosition, transform.position) < pickNextWaypointDistance)
{
curWayPoint = PickNextWaypoint(curWayPoint);
}
//We'll attack the player if he is in sight.
if (CanSeeTarget())
{
yield return StartCoroutine("AttackPlayer");
}
// Move towards our target
MoveTowards(waypointPosition);
}
}
bool CanSeeTarget()
{
//If the target is out of range, we cannot see it.
if (Vector3.Distance(transform.position, target.position) > attackRange)
{
return false;
}
RaycastHit hit;
if (Physics.Linecast(transform.position, target.position, out hit))
{
return hit.transform == target;
}
return false;
}
IEnumerator Shoot()
{
// Start shoot animation
animation.CrossFade("shoot", 0.3f);
// Wait until half the animation has played
yield return new WaitForSeconds(delayShootTime);
// Fire gun
BroadcastMessage("Fire");
// Wait for the rest of the animation to finish
yield return new WaitForSeconds(animation["shoot"].length - delayShootTime);
}
IEnumerator AttackPlayer()
{
//We'll set up the position the player was last visible.
Vector3 lastVisiblePlayerPosition = target.position;
while (true)
{
if (CanSeeTarget())
{
//If our target is dead, we need to quit hunting.
if (target == null)
{
yield return null;
}
//If the target is too far away, we need to give up the hunt.
float distance = Vector3.Distance(transform.position, target.position);
if (distance > shootRange * 3.0f)
{
yield return null;
}
lastVisiblePlayerPosition = target.position;
//If we aren't in the "Don't come closer range" yet, we'll move toward the last known
//position.
if (distance > dontComeCloserRange)
{
MoveTowards(lastVisiblePlayerPosition);
}
else
{
RotateTowards(lastVisiblePlayerPosition);
}
Vector3 forward = transform.TransformDirection(Vector3.forward);
Vector3 targetDirection = lastVisiblePlayerPosition - transform.position;
targetDirection.y = 0;
float angle = Vector3.Angle(targetDirection, forward);
//We'll start shooting at the player if he's in sight and within range.
if (distance < shootRange && angle < shootAngle)
{
yield return StartCoroutine("Shoot");
}
}
else
{
yield return StartCoroutine("SearchPlayer", lastVisiblePlayerPosition);
//If at any point the player leaves visibility, we should stop attacking.
if (!CanSeeTarget())
{
yield return null;
}
}
}
}
IEnumerator SearchPlayer(Vector3 position)
{
// Run towards the player but after 3 seconds timeout and go back to Patroling
float timeout = 3.0f;
while (timeout > 0.0f)
{
MoveTowards(position);
// We found the player
if (CanSeeTarget())
{
yield return null;
}
timeout -= Time.deltaTime;
}
}
IEnumerator RotateTowards(Vector3 position)
{
SendMessage("SetSpeed", 0.0f);
Vector3 direction = position - transform.position;
direction.y = 0;
if (direction.magnitude < 0.1f)
{
yield return null;
}
//Otherwise we have a target that we can see. As such, we'll rotate
//towards our target.
Vector3 targetPoint = target.position;
Quaternion targetRotation = Quaternion.LookRotation(targetPoint - transform.position, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 2.0f);
}
IEnumerator MoveTowards(Vector3 position)
{
Vector3 direction = position - transform.position;
direction.y = 0;
if (direction.magnitude < 0.5f)
{
SendMessage("SetSpeed", 0.0);
yield return null;
}
//Otherwise we have a target that we can see. As such, we'll rotate
//towards our target.
Vector3 targetPoint = target.position;
Quaternion targetRotation = Quaternion.LookRotation(targetPoint - transform.position, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 2.0f);
// Modify speed so we slow down when we are not facing the target
Vector3 forward = transform.TransformDirection(Vector3.forward);
float speedModifier = Vector3.Dot(forward, direction.normalized);
speedModifier = Mathf.Clamp01(speedModifier);
// Move the character
direction = forward * speed * speedModifier;
CharacterController controller = GetComponent<CharacterController>();
controller.SimpleMove(direction * speed);
SendMessage("SetSpeed", speed * speedModifier, SendMessageOptions.DontRequireReceiver);
}
AutoWaypoint PickNextWaypoint(AutoWaypoint currentWaypoint)
{
//Let's find the waypoint where our character will have to turn the least.
//This is the direction the character is walking.
Vector3 forward = transform.TransformDirection(Vector3.forward);
//The closer our two vectors are, the larger the dot product shall be.
var best = currentWaypoint;
float bestDot = -10.0f;
foreach (AutoWaypoint cur in currentWaypoint.connected)
{
Vector3 direction = Vector3.Normalize(cur.transform.position - transform.position);
float dot = Vector3.Dot(direction, forward);
if (dot > bestDot && cur != currentWaypoint)
{
bestDot = dot;
best = cur;
}
}
return best;
}
}