Sooooo I’ve been trolling through the forums for quite some time and tried numerous suggestions people have offered for issues I would consider similar to mine, only nothing will work for me…
Basically, the “KillerPlant” you see before you has 2 animations, being “idle” and “attack”.
I’ve managed to get the plant to rotate and spit it’s little spore things at the player which is what it should be doing, but I can’t for the life of me get the idle and attack animations to play at all(and this is stupidly basic).
When the plant Spits, I want the “attack” animation to blend in and for it to idle at any other time.
Here is my code (yes i did say it was basic
) Obviously there is another script on the spore launcher game object too… Just after suggestions on how to fix this/why it didn’t work in the first place?? Cheers.
//AI PLANT
var spittingRange = 30.0;
var spittingAngleDistance = 10.0;
var target : Transform;
function Start ()
{
//Set animations to loop
animation.wrapMode = WrapMode.Loop;
animation.CrossFade("idle");
animation["attack"].wrapMode = WrapMode.Once;
if (target == null GameObject.FindWithTag("Player"))
{
target = GameObject.FindWithTag("Player").transform;
}
}
function Update ()
{
if (target == null)
{
return;
}
if (!CanSeeTarget ())
{
return;
}
// Rotate towards target
var targetPoint = target.position;
var targetRotation = Quaternion.LookRotation (targetPoint - transform.position, Vector3.up);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 2.0);
// If we are almost rotated towards target - fire one clip of ammo
var forward = transform.TransformDirection(Vector3.forward);
var targetDir = target.position - transform.position;
if (Vector3.Angle(forward, targetDir) < spittingAngleDistance)
{
//SendMessage("Fire");
BroadcastMessage("Spit");
SendMessage("playAttack");
}
}
function playAttack()
{
animation.CrossFade("attack");
}
function CanSeeTarget () : boolean
{
if (Vector3.Distance(transform.position, target.position) > spittingRange)
return false;
var hit : RaycastHit;
if (Physics.Linecast (transform.position, target.position, hit))
return hit.transform == target;
return false;
}
Mmm, edited your post, I have. (The image was too big for the page and added very little; also, I’ve put some code tags on your script to make it more readable.)
First things to try… put a Debug.Log after the CanSeeTarget “if” statement to check if the code after that point gets executed. If so, try another Debug.Log just after the SendMessage(“playAttack”) (still inside the curly brace, I mean). You need to establish whether the animation code is being called at all.
Sooo apologies here, I broke the link to the animations somehow when rotating the plant around to make it look down the X-axis instead of the Z-axis, but I had no way of knowing that. I re-added the model as part of some mad plan and wouldn’t you know it, it worked…
Now I’m finding that when trying to adapt your FPS AI script for a melee character, I’m having an issue whereby my character keeps rotating on the spot at the same time as it walks towards you… all the animations are playing, only it looks like it’s trying to do something it shouldn’t which confuses me since this is practically the FPS animation scrip, just without the Waypoints code and some different animations as they are melee-type characters. I’m currently studying and I’ve had my tutors look over the code without any joy in terms of a solution.
Would be forever greatful if someone can shed some light here.
var speed = 3.0;
var rotationSpeed = 5.0;
var swingRange = 5.0;
var attackRange = 30.0;
//var swingAngle = 30.0;
var dontComeCloserRange = 4.0;
var delaySwingTime = 0.5;
//var pickNextWaypointDistance = 2.0;
var target : Transform;
private var lastSwing = -10.0;
// Make sure there is always a character controller
@script RequireComponent (CharacterController)
function Start ()
{
// Auto setup player as target through tags
if (target == null GameObject.FindWithTag("Player"))
target = GameObject.FindWithTag("Player").transform;
Patrol();
}
function Patrol ()
{
while (true)
{
if (CanSeeTarget ())
{
yield StartCoroutine("AttackPlayer");
}
yield;
}
}
function CanSeeTarget () : boolean
{
if (Vector3.Distance(transform.position, target.position) > attackRange)
return false;
var hit : RaycastHit;
if (Physics.Linecast (transform.position, target.position, hit))
return hit.transform == target;
return false;
}
function Melee ()
{
// Start swinging ("attack") animation
//animation.CrossFade("attack, 0.3");
Debug.Log("running melee");
animation.Play("attack");
// Wait until half the animation has played
yield WaitForSeconds(delaySwingTime); //make this the time it takes to backswing.
// Wait for the rest of the animation to finish
yield WaitForSeconds(animation["attack"].length - delaySwingTime);
}
function AttackPlayer ()
{
var lastVisiblePlayerPosition = target.position;
while (true)
{
if (CanSeeTarget ())
{
// Target is dead - stop hunting
if (target == null)
return;
// Target is too far away - give up
var distance = Vector3.Distance(transform.position, target.position);
if (distance > attackRange * 3)
return;
lastVisiblePlayerPosition = target.position;
if (distance > dontComeCloserRange)
{
MoveTowards (lastVisiblePlayerPosition);
}
else
{
RotateTowards(lastVisiblePlayerPosition);
}
var forward = transform.TransformDirection(Vector3.forward);
var targetDirection = lastVisiblePlayerPosition - transform.position;
targetDirection.y = 0;
var angle = Vector3.Angle(targetDirection, forward);
// Starting if close and player is in sight
//if (distance <= swingRange angle <= swingAngle)
if (distance <= swingRange)
yield StartCoroutine("Melee");
yield;
}
else
{
yield StartCoroutine("SearchPlayer", lastVisiblePlayerPosition);
// Player not visible anymore - stop attacking
if (!CanSeeTarget ())
return;
}
}
}
function SearchPlayer (position : Vector3)
{
// Run towards the player but after 3 seconds timeout and go back to Patroling
var timeout = 3.0;
while (timeout > 0.0)
{
MoveTowards(position);
// We found the player
if (CanSeeTarget ())
return;
timeout -= Time.deltaTime;
yield;
}
}
function RotateTowards (position : Vector3)
{
// SendMessage("SetSpeed", 0.0); //don't know what this does???
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)
{
var direction = position - transform.position;
direction.y = 0;
if (direction.magnitude < 0.5)
{
// SendMessage("SetSpeed", 0.0);
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);
// Modify speed so we slow down when we are not facing the target
var forward = transform.TransformDirection(Vector3.forward);
var speedModifier = Vector3.Dot(forward, direction.normalized);
speedModifier = Mathf.Clamp01(speedModifier);
// Move the character
direction = forward * speed * speedModifier;
GetComponent (CharacterController).SimpleMove(direction);
//SendMessage("SetSpeed", speed * speedModifier, SendMessageOptions.DontRequireReceiver);
}
Problem Solved… Once again, a matter of re-making the prefab from scratch. I can’t find any reason for this, but at least I know my script was working. Can close this off if you like.