Animation Switch...
Hello everyone, I'm new to Unity, and this is my first forum post. Recently, I tried to learn a bit more about the animation system (Mecanim), so that I could add some life into a little game I'm doing. So far, I've managed to import animations from another software, and call on an running animation when the enemy is moving. However, I want the enemy to switch between animations at a given point(ex: When it gets close to the player, it pounces on him), but unfortunately, I haven't got a clue as to how to do it properly...
I was thinking of creating an "Action_Field" (basically a box with a collider and a rigidbody) that would follow the player and change the enemy's animation when it comes in contact with it. (OnCollisionEnter)
Unfortunately, that didn't work, and I've been busy trying to find a solution these past few days, but I'm afraid I might not be able to find it on my own... I'd be grateful if someone could help me figure this out, or even simply give me a nudge in the right direction.
Here's the code in its written form, along with a few helpful snapshots:
Action Field Script
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class ActionField_Script : MonoBehaviour {
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
}
void OnCollisionEnter (Collision hit)
{
if (hit.gameObject.tag == "Enemy")
{
var enemy = hit.collider.GetComponent <EnemyAI> ();
enemy.animSwitch = true;
if (enemy.animSwitch)![alt text][1]
{
enemy.animate.SetBool ("run", false);
enemy.animate.SetBool ("leap", true);
}
}
}
}
Enemy_AI
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class EnemyAI : MonoBehaviour { Transform target; //private Vector3 originalPosition; //private Vector3 currentPosition; //private Vector3 enemyPosition; public Animator animate; private GameObject enemy; public bool animSwitch;
Transform enemyTransform;
public float speed;
public float rotationSpeed;
public float detectionRange;
// Use this for initialization
void Start ()
{
animSwitch = false;
enemyTransform = this.GetComponent <Transform> ();
animate = GetComponent<Animator> ();
enemy = GameObject.FindWithTag ("Enemy");
//originalPosition = enemy.transform.position;
//currentPosition = originalPosition * Time.deltaTime;
//enemyPosition = originalPosition;
}
// Update is called once per frame
void Update ()
{
if (GameObject.FindWithTag ("Player") != null)
{
target = GameObject.FindWithTag ("Player").transform;
Vector3 targetHeading = target.position - transform.position;
Vector3 targetDirection = targetHeading.normalized;
transform.rotation = Quaternion.LookRotation (targetDirection);
transform.eulerAngles = new Vector3 (0, transform.eulerAngles.y, 0);
enemyTransform.position += enemyTransform.forward * speed * Time.deltaTime;
}
else if (GameObject.FindWithTag ("Player") == null)
{
target = GameObject.FindWithTag ("Character").transform;
Vector3 newTargetHeading = target.position - transform.position;
Vector3 newTargetDirection = newTargetHeading.normalized;
transform.rotation = Quaternion.LookRotation (newTargetDirection);
transform.eulerAngles = new Vector3 (0, transform.eulerAngles.y, 0);
enemyTransform.position += enemyTransform.forward * speed * Time.deltaTime;
animate.SetBool ("run", true);
}
}
}
[1]: /storage/temp/89782-unity-help.png
Answer by IsaiahKelly · Mar 13, 2017 at 11:37 PM
Use OnTriggerEnter() and SetTrigger()
I would replace the "leap" animator bool with an animator trigger and use a collider trigger attached to the player as a way to trigger the leap state on the enemy when they enter it.
void OnTriggerEnter(Collider other)
{
var enemy = other.GetComponent<EnemyAI>();
if (enemy)
{
enemy.target = gameObject; // Set this object (Player object) as enemy target?
enemy.animate.SetTrigger("leap");
}
}
For this to work you need to attach a SphereCollider to the player and set "Is Trigger" to true. Then handle all enemy animation related stuff in the enemy's Animator itself. Animation switching is handle in the Animator itself using states.
Answer by MrXProductions · Mar 14, 2017 at 03:35 PM
I have tried everything you said, and more. Unfortunately, it did not work. Perhaps there are still many functions I don't understand or use properly, but so far, in every little project I have come up with, "Trigger" causes objects to lose their physical properties. They go through walls, fall through the ground, players and enemies alike go straight through one another. As I said, maybe I just don't get it...
I've tried adding and removing trigger/bool values on each and every animation transitions in the editor, changed some functions in both scripts mentione above, and even added new ones, but everything I tried ultimately failed.
If I were to copy the contents of the "EnemyAI" Update into an IEnumerator instead, I might be able to stop the enemy's movements for a time using a "waitforseconds", but would I be able to cause the leap animation to happen while the enemy is motionless? I'm at a loss as to what to do...
First off, change this answer into a comment by clicking on the gear icon in the top right corner and selecting "Convert to Comment". If you want to respond to an answer in the future please click on "Add comment" underneath the answer itself. Creating an answer to your own question is only useful when you've actually solved your own problem.
Yes, you don't understand how triggers are supposed to work. The behavior you described is exactly as intended. Triggers don't interact with anything, they simply fire events when other things enter them. See the video on Colliders as Triggers for more info.
However, you can have multiple colliders on the same object. This means you can have a trigger collider and a normal collider on the same object! This is what I meant by "attached trigger collider". Don't change the collider on the player already. Just add an additional collider to the player and set that to "Is trigger".
This additional trigger collider can be directly on the player or in a child object under the player for better origination. This will allow you to let the player still collide with other objects and detect trigger events at the same time. Just make sure the trigger is bigger than the player's collider, so things can actually enter the trigger and fire events.
That should solve your trigger issue, but from your code samples it seems you don't understand how best to use the Animator too, but that's an entirely different topic that's far too big to get into here. So I would highly recommend studying up on some of the Learn tutorials covering Animation.
Unity Answers is also best for short specific answers to relatively simple questions. So if you need more than that it might be better to create a post in the forums for general help and advice with your projects. Hope this helps you and best of luck!