Hi all,
Just need a little help understanding how I should be doing this.
Currently, I have a prototype where I have a set of waypoints in my script for an AI object to move along.
At some point when a player object enters a detection radius trigger, it will stop and for the moment - jump up in the air (using the attached rigidbody.)
The enemy object(monster) has its own collider so it can collide with objects in the scene, but it also has a parent game object
=>parent (script attached to here, sphere collider trigger here detects player, so any jumping is applied to this rigidbody)
===> monster (child, pretty much the model)
using UnityEngine;
using System.Collections;
public class monster : MonoBehaviour {
public Vector3[] waypoints;
public float time;
public float wait_time;
private float time_till_attack;
public bool smooth = false;
private float node_radius = 0.5f;
private float _t = 0;
private Vector3 start, finish;
private int index = 0;
private float wait_timer = 0;
private bool player_detected = false;
private float attack_timer = 0;
// Use this for initialization
void Start ()
{
SetTargetPosition();
}
void Update()
{
// if no player detected, visit the waypoints
if (!player_detected)
{
if (waypoints.Length > 1)
{
if (_t >= 1.0f)
{
// this is just a pause before moving to next waypoint
if (wait_timer < wait_time)
wait_timer += Time.deltaTime;
else
{
SetTargetPosition();
wait_timer = 0;
}
}
float time_ratio = smooth ? Mathf.SmoothStep(0.0f, 1.0f, _t) : _t;
transform.position = Vector3.Lerp(start,finish, time_ratio);
_t += Time.deltaTime/time;
}
}
else
{
// can this be done as a coroutine?
// I had all sorts of trouble trying to have a simple pause before jump
if (attack_timer < time_till_attack)
attack_timer += Time.deltaTime;
else
{
// after pausing, jump at the player
// repeat this until the player is out of detection zone
// to continue back on waypoint path
}
}
}
void SetTargetPosition()
{
if (index > waypoints.Length - 1) index = 0;
start = waypoints[index];
index++;
if (index > waypoints.Length - 1) index = 0;
finish = waypoints[index];
_t = 0;
}
void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
player_detected = true;
}
void OnTriggerExit(Collider other)
{
if (other.tag == "Player")
player_detected = false;
}
public void OnDrawGizmos()
{
if(waypoints == null)
return;
for(int i=0;i< waypoints.Length;i++) {
Vector3 pos = waypoints[i];
Gizmos.color = Color.yellow;
Gizmos.DrawSphere(pos, node_radius);
if(i>0) {
Vector3 prev = waypoints[i-1];
Gizmos.DrawLine(prev,pos);
}
}
}
}
Again - this is a prototype script! I'll fine tune it once I have the basics down:
1 ai walks along waypoints (done)
2 ai detects player (done)
3 ai stops waypoint movement when player detected (done)
4 ai pauses for a set time (see the comment in code, I could not get the coroutine to work)
5 ai jumps in the air to attempt to knock player (a flying kind of object)
6 repeat from 4 until player leaves detection radius.
ideally the monster will 'jump' in the direction of the player. The jump will always be the same amount on the current level.
* with a jump animation, I could just detect when the animation finishes at step 5, but assume I dont have that luxury
Does anyone have any good ideas on how I can do this. It will help me going forward in producing other types on enemy scripts. Also any comments on improving the code (*ahem* coroutines) would be welcomed.
Cheers
↧