2017-09-02 10:49:48 Markdon 阅读数 3925

有时候一个Legacy或者Mecanim动画不能很好的控制人物移动,这时候我们就可以通过混合树来控制了。
首先把我们的人物模型拖进场景
首先把默认状态选择,这里在我们看看人物能不能移动
这里写图片描述
这里写图片描述
然后我们进行操作;点击Windows里的Animator选项这里写图片描述
混合树创建步骤:1.右击出现creat state -> from blend Tree
这里写图片描述

这里写图片描述
配置混合树
这里写图片描述
这里写图片描述
using UnityEngine;
using System.Collections;

public class AnimatorTest : MonoBehaviour {

private Animator anim;
private float horizontal;
private float vertical;
//旋转的速度
public float rotateSpeed;
//向前跑的速度
public float speed;

// Use this for initialization
void Start () {
    anim = GetComponent<Animator>();
}

// Update is called once per frame
void Update () {
    //
    horizontal = Input.GetAxis("Horizontal");
    vertical = Input.GetAxis("Vertical");
    //W键或者上方向键按下的时候
    if (Input.GetKey(KeyCode.W)|| Input.GetKey(KeyCode.UpArrow))
    {
        //如果只按下W键或者上方向键按下的时候
        anim.SetBool("Run",true);
        transform.Translate(Vector3.forward * Time.deltaTime * speed);
        //如果按下W键或者上方向键按下的时候同事按下AD或者左右方向键的时候执行左跑或者右跑的动作
        if (vertical != 0)
        {
            anim.SetFloat("RunValue", horizontal);
            transform.Translate(Vector3.forward * Time.deltaTime * speed * vertical);

            transform.Rotate(Vector3.up * Time.deltaTime * rotateSpeed * horizontal);
        }
    }
    //W键或者上方向键抬起的时候执行idle动画
    if (Input.GetKeyUp(KeyCode.W) || Input.GetKeyUp(KeyCode.UpArrow))
    {
      anim.SetBool("Run",false);
    }
}

}
这里写图片描述

2015-02-10 14:22:13 book_longssl 阅读数 2836

 

     动画混合

  状态机之中的状态不仅可以是单个剪辑,也可以是一个混合树。构建和编辑复杂的状态机和混合树,以便完全控制的角色如何运动。Unity编辑器提供强大的工具,用于分割、创建循环和从导入的动画文件中提取轨迹。然后可以把这些动画短片用作一个多层混合树的叶子,或者作为分层状态机中的一种状态。混合树让您只使用几个动画剪辑就能创建各种各样的运动。在混合树编辑器中,您可以定义混合参数并在3D视图中预览混合动画。混合树和动画剪辑一样,可以用作分层状态机中的状态。

  动画工具用于创建多层分层状态机。控制器可以定义任意数量的层。每一层可以使用自己的状态机,也可以与主层共享状态机。层可被覆盖或添加,使用身体遮罩可以定义身体受影响的部分。最后,您可以使用分层状态机把复杂的控制器分解成更小的可重复使用的模块。

  


 

  Mecanim的混合树


动画重定向

  将创建的sa_ctl控制器拖到到模型的controller变量中。这样模型就可以播放动作了,也可以将这个控制器拖到给其他模型文件实现动画重定向。



  Tips;


     注意:此Animator组件中的Apply Root Motion选项如果我们勾选了的话,当播放动画时是通过动画运动的幅度来改变角色的Transform的,如果我们不勾选,我们就可以用脚本设定此角色的Tranform。

  如果在Animator中我们勾选了Apply Root Motion,我们不必修改角色的Transform,依靠角色的动作本身的设计就能改变角色的Transform。但是如果我们没有勾选它,那我们就只能依靠程序来动态的改变其Transform,就像老式的动画系统一样。



2017-08-31 21:41:34 yy763496668 阅读数 3133

我们需要实现可以向左向前向右跑

混合树创建步骤:1.右击出现creat state -> from blend Tree
这里写图片描述

这里写图片描述
配置混合树
这里写图片描述
这里写图片描述

参考代码如下:

using UnityEngine;
using System.Collections;

public class AnimatorTest : MonoBehaviour {

    private Animator anim;
    private float horizontal;
    private float vertical;
    //旋转的速度
    public float rotateSpeed;
    //向前跑的速度
    public float speed;

    // Use this for initialization
    void Start () {
        anim = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update () {
        //
        horizontal = Input.GetAxis("Horizontal");
        vertical = Input.GetAxis("Vertical");
        //W键或者上方向键按下的时候
        if (Input.GetKey(KeyCode.W)|| Input.GetKey(KeyCode.UpArrow))
        {
            //如果只按下W键或者上方向键按下的时候
            anim.SetBool("Run",true);
            transform.Translate(Vector3.forward * Time.deltaTime * speed);
            //如果按下W键或者上方向键按下的时候同事按下AD或者左右方向键的时候执行左跑或者右跑的动作
            if (vertical != 0)
            {
                anim.SetFloat("RunValue", horizontal);
                transform.Translate(Vector3.forward * Time.deltaTime * speed * vertical);
                Vector3 direction = Vector3.forward * vertical + Vector3.right * horizontal;
                transform.Rotate(Vector3.up * Time.deltaTime * rotateSpeed * horizontal);
            }
        }
        //W键或者上方向键抬起的时候执行idle动画
        if (Input.GetKeyUp(KeyCode.W) || Input.GetKeyUp(KeyCode.UpArrow))
        {
            anim.SetBool("Run",false);
        }
    }
}

效果如下:
这里写图片描述

2014-04-10 18:41:41 u011714480 阅读数 3261
混合树 (Blend Tree)
游戏动画中的一个常见任务是在两个或更多类似运动之间混合。最好的已知示例可能是依据人物速度混合行走和奔驰动画。另一个示例是人物在奔驰过程中转弯时向左或向右歪斜。



重要的是区分变换 (Transition) 与混合树 (Blend Tree)。尽管两者都用于创立滑润动画,可是它们用于不一样类型的状况。


变换 (Transition) 用于在给守时刻量内从一个动画状况 (Animation State) 滑润变换为另一个状况。变换指定为动画状况机 (Animation State Machine) 的一部分。假如变换敏捷,则一般可从一个运动极好地变换为彻底不一样的运动。
混合树 (Blend Tree) 用于答应经过按不一样程度组合一切动画的各个部分来滑润混合多个动画。各个运动参加构成结尾作用的量运用混合参数进行操控,该参数仅仅与动画器操控器 (Animator Controller) 相关的数值动画参数之一。要使混合运动有意义,混合的运动有必要具有类似性质和时刻。混合树 (Blend Tree) 是动画器操控器 (Animator Controller) 中的特殊状况类型。
类似运动示例可所以各种行走和奔驰动画。要使混合作业良好,片段中的移动有必要在一样的规范化时刻点发作。例如,行走和奔驰动画能够对齐,以便脚与地上触摸的时刻在一样的规范化时刻点发作(例如,左脚在 0.0 踏地,而右脚在 0.5 踏地)。由于运用规范化时刻,所以片段是不是具有不一样长度无关紧要。


要开始运用新混合树 (Blend Tree),需求:


右键单击动动画器操控器窗口 (Animator Controller Window)上的空白空间
从呈现的上下文菜单中挑选 创立状况 (Create State) > 重新混合树 (From New Blend Tree)。
双击混合树 (Blend Tree) 以进入混合树图 (Blend Tree Graph)。
动画器操控器窗口 (Animator Controller Window) 如今显现整个混合树 (Blend Tree) 的图形,而检视器 (Inspector) 显现当时挑选的节点及其直接子级。




动画器窗口 (Animator Window) 显现整个 混合树 (Blend Tree) 的图形。左边是仅包括根混合节点 (Blend Node) 的混合树 (Blend Tree)。右侧是包括根混合节点 (Blend Node) 以及以三个动画片段 (Animation Clip) 作为子节点的混合树 (Blend Tree)。


这会为参数值改变时的动画组合方法供给图形可视化(在拖动滑块时,源自树根的箭头会改动其底纹以显现首要动画片段)。


能够在混合树 (Blend Tree) 图中挑选任何节点以在检视器 (Inspector) 中检视它。假如所选节点是动画片段 (Animation Clip),则会显现该动画片段 (Animation Clip) 的检视器 (Inspector)。假如动画是从模型导入,则设置是只读的。假如节点是混合节点 (Blend Node),则会显现混合节点 (Blend Node) 的检视器 (Inspector)。



任何运动之前在 检视器 (Inspector) 中显现的混合节点 (Blend Node) 已增加。


混合类型”(Blend Type) 下拉菜单用于挑选能够依据一个或两个参数混合的不一样混合类型之一。能够在以下页面上了解有关不一样混合类型和其他混合树 (Blend Tree) 选项的更多信息。本文章由游戏蛮牛unity3d教程手册整理推荐
unity3d游戏测评 http://www.unitymanual.com/forum-virtualreality-1.html
2019-07-28 21:05:37 qmAlin 阅读数 105

相机控制(Cameramanager)

using UnityEngine;
namespace dgl {

    public class CameraManager : MonoBehaviour {
        public bool lockon = false;
        public float followSpeed = 9;
        public float mouseSpeed = 2;
        public float controllerSpeed = 7;
        public Transform target;
        [HideInInspector]
        public Transform pivot;
        [HideInInspector]
        public Transform camTrans;

        float turnSmoothing = .1f;
        public float minAngle = -35;
        public float maxAngle = 35;

        float smoothX;
        float smoothY;
        float smoothXVelocity;
        float smoothYVelocity;
        public float lookAngle;
        public float tilAngle;

        public static CameraManager singleton;
        public void Init (Transform t) {
            target = t;
            camTrans = Camera.main.transform;
            pivot = camTrans.parent;
        }
        public void Tick (float d) {
            float h = Input.GetAxis ("Mouse X");
            float v = Input.GetAxis ("Mouse Y");

            float c_h = Input.GetAxis ("RightAxis X");
            float c_v = Input.GetAxis ("RightAxis Y");

            float targetSpeed = mouseSpeed;

            if (c_h != 0 || c_v != 0) {
                h = c_h;
                v = c_v;
                targetSpeed = controllerSpeed;
            }
            FollowTarget (d);
            HandleRotations (d, v, h, targetSpeed);
        }

        void FollowTarget (float d) {
            float speed = d * followSpeed;
            Vector3 targetPosition = Vector3.Lerp (transform.position, target.position, speed);
            transform.position = targetPosition;
        }
        void HandleRotations (float d, float v, float h, float targetSpeed) {
            if (turnSmoothing > 0) {
                smoothX = Mathf.SmoothDamp (smoothX, h, ref smoothXVelocity, turnSmoothing);
                smoothY = Mathf.SmoothDamp (smoothY, v, ref smoothYVelocity, turnSmoothing);
            } else {
                smoothX = h;
                smoothY = v;
            }
            if ( lockon)
            {
                
            }
            lookAngle+=smoothX*targetSpeed;
            transform .rotation=Quaternion.Euler(0,lookAngle,0);

            tilAngle -=smoothY*targetSpeed;
            tilAngle=Mathf.Clamp(tilAngle,minAngle,maxAngle);
            pivot.localRotation=Quaternion.Euler(tilAngle,0,0);
        }
        /// <summary>
        /// Awake is called when the script instance is being loaded.
        /// </summary>
        void Awake () {
            singleton = this;
        }
    }
}

 

状态控制(StateManager)

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

public class StateManager : MonoBehaviour {
    [Header ("Init")]
    public GameObject activeModel;
    [Header ("Input")]
    public float vertical;
    public float horiziontal;
    public float moveAmount;
    public Vector3 moveDir;
    [Header ("Stats")]
    public float moveSpeed = 2;
    public float runSpeed = 3.5f;
    public float rotateSpeed = 5;
    public float toGround = .5f;
    [Header ("States")]
    public bool run;
    public bool onGround;
    public bool lockOn;
    [HideInInspector]
    public Animator animator;
    [HideInInspector]
    public Rigidbody rigid;
    [HideInInspector]
    public float delta;
    [HideInInspector]
    public LayerMask ignoreLayers;
    // Start is called before the first frame update
    void Start () {
        Init ();
    }
    // Update is called once per frame
    void Update () {

    }
    public void Init () {
        SetupAnimator ();
        rigid = GetComponent<Rigidbody> ();
        rigid.angularDrag = 999;
        rigid.drag = 4;
        rigid.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ;
        gameObject.layer = 8;
        ignoreLayers = ~(1 << 9);

        animator.SetBool ("onGround", true);
    }
    void SetupAnimator () {
        if (activeModel == null) {
            animator = GetComponent<Animator> ();
            if (animator == null) {
                Debug.Log ("nO MODEL");
            } else {
                activeModel = animator.gameObject;
            }

        }
        if (animator == null)
            animator = activeModel.GetComponent<Animator> ();
    }
    public void Tick (float d) {
        delta = d;
        onGround = OnGround ();
        animator.SetBool ("onGround", onGround);
    }
    void HandleMovementAnimations () {
        animator.SetBool ("run", run);
        animator.SetFloat ("vertical", moveAmount, .4f, delta);
    }
    public bool OnGround () {
        bool r = false;
        Vector3 origin = transform.position + (Vector3.up * toGround);
        Vector3 dir = -Vector3.up;
        float dis = toGround + .3f;
        RaycastHit hit;
        if (Physics.Raycast (origin, dir, out hit, dis, ignoreLayers)) {
            r = true;
            Vector3 targetPosition = hit.point;
            transform.position = targetPosition;
        }
        return r;
    }
    public void FixedTick (float d) {
        delta = d;

        rigid.drag = (moveAmount > 0 || onGround == false) ? 0 : 4;

        float targetSpeed = moveSpeed;

        if (run) {
            targetSpeed = runSpeed;
        }

        if (onGround) {
            rigid.velocity = moveDir * (targetSpeed * moveAmount);
        }

        if (run) {
            lockOn = false;
        }

        if (!lockOn) {
            Vector3 targetDir = moveDir;
            targetDir.y = 0;
            if (targetDir == Vector3.zero) {
                targetDir = transform.forward;
            }

            Quaternion tr = Quaternion.LookRotation (targetDir);
            Quaternion targetRotation = Quaternion.Slerp (transform.rotation, tr, delta * moveAmount * rotateSpeed);
            transform.rotation = targetRotation;
        }

        HandleMovementAnimations ();
    }

}

 

输入封装(InputHandler)

using System.Collections;
using System.Collections.Generic;
using dgl;
using UnityEngine;
public class InputHandler : MonoBehaviour {
    float vertical = 0;
    float horiziontal = 0;
    bool runInput;
    StateManager states;
    CameraManager cameraManager;

    float delta;
    // Start is called before the first frame update
    void Start () {
        states = GetComponent<StateManager> ();
        states.Init ();
        cameraManager = CameraManager.singleton;
        cameraManager.Init (this.transform);
    }

    // Update is called once per frame
    void Update () {
        delta = Time.deltaTime;
        states.Tick (delta);
    }
    private void FixedUpdate () {
        delta = Time.fixedDeltaTime;
        GetInput ();
        UpdateState ();
        states.FixedTick (delta);
        cameraManager.Tick (delta);
    }
    void GetInput () {
        vertical = Input.GetAxis ("Vertical");
        horiziontal = Input.GetAxis ("Horizontal");
        runInput = Input.GetButton ("RunInput");
    }
    void UpdateState () {
        states.vertical = vertical;
        states.horiziontal = horiziontal;

        Vector3 v = states.vertical * cameraManager.transform.forward;
        Vector3 h = states.horiziontal * cameraManager.transform.right;

        states.moveDir = (v + h).normalized;
        float m = Mathf.Abs (horiziontal) + Mathf.Abs (vertical);
        states.moveAmount = Mathf.Clamp01 (m);

        if (runInput) {

            states.run = (states.moveAmount > 0);
            if (states.moveAmount > 0)
                states.run = true;

        } else {
            states.run = false;
        }
    }

}

//TODO视角锁定 二维混合树动画  

Unity3d 动画系统介绍

阅读数 20259

没有更多推荐了,返回首页