2017年11月19日 星期日

Unity程式設計初體驗(七)-操縱人物模型的程式設計

在前一章我們介紹Unity程式初體驗(六)-Unity的動畫系統的文章,瞭解到Unity動畫系統中有四個主要部份,分別是:動畫夾(Animation clips)、動畫控制器(Animator Controller)、操縱人物模型(Rigged Character Model)、動畫組件(Animator Component)。今天我們來試試看如何操縱人物模型。



我們設計的程式原始如下:
using UnityEngine;
using System.Collections;

public class PlayGUI : MonoBehaviour
{
    public Transform[] transforms;

    public GUIContent[] GUIContents;

    private Animator[] animator;

    private string currentState = "";

    private int state = 0;
    private int timecnt = 0;

    // Use this for initialization
    void Start()
    {
        animator = new Animator[transforms.Length];
        for (int i = 0; i < transforms.Length; i++)
        {
            animator[i] = transforms[i].GetComponent();
        }
    }

    void OnGUI()
    {
        GUILayout.BeginVertical("box");
        for (int i = 0; i < GUIContents.Length; i++)
        {

            if (GUILayout.Button(GUIContents[i]))
            {
                currentState = GUIContents[i].text;
            }

            AnimatorStateInfo stateInfo = animator[0].GetCurrentAnimatorStateInfo(0);

            if (!stateInfo.IsName("Base Layer.idle0"))
            {
                for (int j = 0; j < animator.Length; j++)
                {
                    //animator[j].SetBool("idle0ToIdle0", false);
                    animator[j].SetBool("idle0ToIdle1", false);
                    animator[j].SetBool("idle0ToWalk", false);
                    animator[j].SetBool("idle0ToRun", false);
                    animator[j].SetBool("idle0ToWound", false);
                    //animator[j].SetBool("idle0ToSkill1", false);
                    animator[j].SetBool("idle0ToSkill0", false);
                    animator[j].SetBool("idle0ToAttack1", false);
                    animator[j].SetBool("idle0ToAttack0", false);
                    animator[j].SetBool("idle0ToDeath", false);
                }
            }
            else
            {
                for (int j = 0; j < animator.Length; j++)
                {
                    animator[j].SetBool("walkToIdle0", false);
                    animator[j].SetBool("runToIdle0", false);
                    animator[j].SetBool("deathToIdle0", false);
                }
            }

            if (currentState != "")
            {
                if (stateInfo.IsName("Base Layer.walk") && currentState != "walk")
                {
                    for (int j = 0; j < animator.Length; j++)
                    {
                        animator[j].SetBool("walkToIdle0", true);
                    }
                }

                if (stateInfo.IsName("Base Layer.run") && currentState != "run")
                {
                    for (int j = 0; j < animator.Length; j++)
                    {
                        animator[j].SetBool("runToIdle0", true);
                    }
                }

                if (stateInfo.IsName("Base Layer.death") && currentState != "death")
                {
                    for (int j = 0; j < animator.Length; j++)
                    {
                        animator[j].SetBool("deathToIdle0", true);
                    }
                }

                switch (currentState)
                {
                    /*
        case "idle0":
for (int j = 0; j < animator.Length; j++) {
animator[j].SetBool("idle0ToIdle0", true);
}
break;
*/
                    case "idle1":
                        for (int j = 0; j < animator.Length; j++)
                        {
                            animator[j].SetBool("idle0ToIdle1", true);
                        }
                        /*
                        break;
                    case "idle0":

                        break;
                    case "walk":
                        for (int j = 0; j < animator.Length; j++) {
                            animator[j].SetBool("idle0ToWalk", true);
                        }
                        */
                        break;
                    case "run":
                        for (int j = 0; j < animator.Length; j++)
                        {
                            animator[j].SetBool("idle0ToRun", true);
                        }
                        break;
                    case "attack0":
                        for (int j = 0; j < animator.Length; j++)
                        {
                            animator[j].SetBool("idle0ToAttack0", true);
                        }
                        break;
                    case "attack1":
                        for (int j = 0; j < animator.Length; j++)
                        {
                            animator[j].SetBool("idle0ToAttack1", true);
                        }
                        break;
                    case "skill0":
                        for (int j = 0; j < animator.Length; j++)
                        {
                            animator[j].SetBool("idle0ToSkill0", true);
                        }
                        break;
                        /*
                    case "skill1":
                        for (int j = 0; j < animator.Length; j++) {
                            animator[j].SetBool("idle0ToSkill1", true);
                        }
                     
                        break;*/
                    case "wound":
                        for (int j = 0; j < animator.Length; j++)
                        {
                            animator[j].SetBool("idle0ToWound", true);
                        }
                        break;
                    case "death":
                        for (int j = 0; j < animator.Length; j++)
                        {
                            animator[j].SetBool("idle0ToDeath", true);
                        }
                        break;

                    default:
                        break;
                }
                currentState = "";
            }
        }
        GUILayout.EndVertical();
    }

    void Update()
    {
        timecnt = timecnt + 1;
        if (timecnt > 50) {
            timecnt = 0;
        switch (state)
            {
                case 0:
                    for (int j = 0; j < animator.Length; j++)
                    {
                        animator[j].SetBool("idle0ToAttack0", true);
                    }
                    Debug.Log("state 0");
                    state = 1;
                    break;

                case 1:
                    for (int j = 0; j < animator.Length; j++)
                    {
                        animator[j].SetBool("Attack0Toidle0", true);
                    }
                    Debug.Log("state 1");
                    state = 2;
                    break;
                case 2:
                    for (int j = 0; j < animator.Length; j++)
                    {
                        animator[j].SetBool("idle0ToAttack1", true);
                    }
                    Debug.Log("state 2");
                    state = 3;
                    break;
                case 3:
                    for (int j = 0; j < animator.Length; j++)
                    {
                        animator[j].SetBool("idle0ToRun", true);
                    }
                    Debug.Log("state 3");
                    state = 0;
                    break;
                default:

                    break;
            }
        }
     
    }
}

上面程式黃底文字是我們增加的程式,其中有兩個變數,一個是state來控制動畫運作的狀態值,另一個timecnt是用來延遲動畫切換的狀態值,讓動畫可以按照我們想要的動作來運作。為了要讓我很清楚地瞭解程式的運作,我們在程式中增加Debug.Log的程式碼。

4 則留言:

  1. 回覆
    1. 今天上課已經有說明,若是不懂請再提出。

      刪除
  2. 程式碼要放在哪一個資料夾中
    程式碼檔建好後要怎麼去拖曳此檔,並做運用
    這篇文章並無清楚的說明上述的做法

    回覆刪除
    回覆
    1. 程式碼可以建一個Scripts來存放,也可以不用。直接用滑鼠用拖移方式,移至物件的上方即可。

      刪除