您的位置:首页 > 移动开发 > Unity3D

Unity 动画模板代码注解

2016-04-18 18:02 429 查看
/********************************************
* The developed codes is only for this class.
* Any business useages need the permission of the author
*
* Copyright (c) 2016.04  sysu.edu.cn
* Copyright (c) 2016.04  Mr. Pan
*
* *******************************************/

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class StateTrigger { //这是状态机开关
private float t;
private bool fired;

public StateTrigger(float trigger_time) { //构造的时候传入一个时间,一旦动画进行到这个时间,就开启开关
this.t = trigger_time;
this.fired = false;
}

public bool triggerIt(float time) { //这个方法传入一个time
//Debug.Log (time);
if ((time > this.t) & !fired) { // 如果这个时间大于 trigger time ,并且 本身未执行
fired = true; // 已执行
return true; // 可以执行
} else if ((time <= this.t) & fired) { // 如果还没到那个trigger时间,那么不管fired是否,都将fired设置为false
fired = false;
return false; // 并且不能执行
} else {
return false; // 剩下的情况是fired,就是已经执行了,那么就算超过trigger时间也不用执行了
}
}

}

public class duck_anim : MonoBehaviour {

// Some animation controller obejcts
private Animator anim; // 声明一个动画,而非数据
private AnimationClip[] clips; // 动画剪辑,这是用来存储所有可以使得角色动画的 动画 (注意)数据
private readonly Dictionary<string, AnimationClip> clips_dict = new Dictionary<string, AnimationClip>(); // 只读的字典,用于通过名字搜索 动画剪辑
// const of Parameters and states
protected const string PARA_NAME_TRIGGER_SUF = "_trigger"; //在最后的setinteger 和 setTrigger
protected const string PARA_NAME_ATTACK = "attack";
protected const int ATTACK1 = 0x01; // 这类常数,用来保证一个状态只有一个路径活动,0x02,0x03等作为选择路径参数的值
protected const int ATTACK2 = 0x02; // 不过是怎么控制的呢? 是用在setInteger的时候的,作为 value of the parameter的

protected readonly int SID_ATTACK1 = Animator.StringToHash("Base Layer.Attack1"); // 生成对应的ID
protected readonly int SID_ATTACK2 = Animator.StringToHash("Base Layer.Attack2");
protected readonly int SID_IDLE = Animator.StringToHash("Base Layer.Idle");

// Use this for initialization
void Start () {
//setting clips
anim = GetComponent<Animator> ();
// 下如同字面所说,是一个 运行动画控制器,是动画在运行时刻的代表,可以用来在runtime(进行时)改变动画控制器
RuntimeAnimatorController rac = GetComponent<Animator> ().runtimeAnimatorController;
clips = rac.animationClips; //这是runtimeAnimatorController的欸以参数,包括所有controller要用到的 动画剪辑clips
foreach (AnimationClip clip in clips) {
clips_dict.Add (clip.name, clip);
}

// other setting, such as clip event

}

// Update is called once per frame
private AnimatorStateInfo pre_state; // 代表了当前或者之后的状态的信息
void Update () {
AnimatorStateInfo asi = anim.GetCurrentAnimatorStateInfo (0); //获取当前动画器的状态信息,参数是该层的索引,表示是第0层
//这段代码,主要为了在不动的时候来,循环Idle状态
if (asi.fullPathHash == pre_state.fullPathHash) { // 完整路径哈希,这个hash是有animator.strngToHash来生成的,对应动画编辑器中层中的动画
//print currentState update here
UpdateState (asi);
} else {
ExitState (pre_state);
EnterState (asi);
pre_state = asi;
}

//demo only
if (Input.GetKeyDown (KeyCode.R)) {
do_attack2 ();
} else if (Input.GetKeyDown (KeyCode.A)) {
do_attack1 ();
}
}

void EnterState(AnimatorStateInfo asi) {
if (asi.fullPathHash == SID_IDLE) {
//
print ("Enter Idle");
}
}

void ExitState(AnimatorStateInfo asi) {
if (asi.fullPathHash == SID_IDLE) {
//
print ("Exit Idle");
}
}

private StateTrigger st_idle_50 = new StateTrigger (0.5f);
private StateTrigger st_attck2_90 = new StateTrigger (0.9f);
void UpdateState(AnimatorStateInfo asi) {
if (asi.fullPathHash == SID_IDLE) {
// 如果此时是 idle 状态
if (st_idle_50.triggerIt(asi.normalizedTime)) { // 归一化时间,百分之几的
print ("Update 50%, place you event call code after it!");
}
}

if (asi.fullPathHash == SID_ATTACK2) {
//Debug.Log ("sadadasd");
if (st_attck2_90.triggerIt(asi.normalizedTime)) {
print ("Update 90%, place you event call code after it!");
attackBeginHandler ("attack2");
}
}

}

// load clip events and curve here

// Define your events handle here
protected void attackBeginHandler (string attack_name) {
print ("ahahah!");
}

// define outer command here
// the interface to client program
public void do_attack1() {
anim.SetInteger (PARA_NAME_ATTACK, ATTACK1); // 设置参数的名字 和 值
anim.SetTrigger (PARA_NAME_ATTACK + PARA_NAME_TRIGGER_SUF); // 设置一个要激活的触发器参数
}

public void do_attack2() {
anim.SetInteger (PARA_NAME_ATTACK, ATTACK2);
anim.SetTrigger (PARA_NAME_ATTACK + PARA_NAME_TRIGGER_SUF);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: