C# Unity3D Mecanim角色转弯前停止

C# Unity3D Mecanim角色转弯前停止,c#,unity3d,logic,game-physics,C#,Unity3d,Logic,Game Physics,所以在过去的几天里,我一直在使用Mecaim开发Unity3D中的角色控制器。它不是基于我自己的代码,而是基于我在网上找到的一个教程,当然,该教程是为Unity 4编写的,所以我在这里和那里遇到了一些小问题,但到目前为止我还没有解决任何问题 所以最基本的问题是,我的角色似乎(毫无理由地)停止了所有的冲力,当我试图做一个艰难的180度转弯时,他慢慢地转过身来,之后他继续像正常人一样奔跑,但我不明白为什么他会突然停止转弯 这是我的角色逻辑脚本: using UnityEngine; using Sy

所以在过去的几天里,我一直在使用Mecaim开发Unity3D中的角色控制器。它不是基于我自己的代码,而是基于我在网上找到的一个教程,当然,该教程是为Unity 4编写的,所以我在这里和那里遇到了一些小问题,但到目前为止我还没有解决任何问题

所以最基本的问题是,我的角色似乎(毫无理由地)停止了所有的冲力,当我试图做一个艰难的180度转弯时,他慢慢地转过身来,之后他继续像正常人一样奔跑,但我不明白为什么他会突然停止转弯

这是我的角色逻辑脚本:

using UnityEngine;
using System.Collections;

public class characterLogic : MonoBehaviour {

[SerializeField]
private Animator animator;
[SerializeField]
private FollowCamera gamecam;
[SerializeField]
private float directionSpeed = 1.5f;
[SerializeField]
private float directionDampTime = 0.25f;
[SerializeField]
private float rotationDegreePerSecond = 120f;
[SerializeField]
private float speedDampTime = 0.05f;

private float speed = 0.0f;
private float direction = 0.0f;
private float charAngle = 0f;
private float horizontal = 0.0f;
private float vertical = 0.0f;
private AnimatorStateInfo stateInfo;
private AnimatorTransitionInfo transInfo;

private int m_LocomotionId = 0;
private int m_LocomotionPivotLId = 0;
private int m_LocomotionPivotRId = 0;
private int m_LocomotionPivotLTransId = 0;  
private int m_LocomotionPivotRTransId = 0;  

public Animator Animator
{
    get
    {
        return this.animator;
    }
}

public float Speed
{
    get
    {
        return this.speed;
    }
}

public float LocomotionThreshold { get { return 0.2f; } }


// Use this for initialization
void Start () {


    animator = GetComponent<Animator>();

    if(animator.layerCount >= 2)
    {
        animator.SetLayerWeight(1, 1);
    }   

    m_LocomotionId = Animator.StringToHash("Base Layer.Locomotion");
    m_LocomotionPivotLId = Animator.StringToHash("Base Layer.LocomotionPivotL");
    m_LocomotionPivotRId = Animator.StringToHash("Base Layer.LocomotionPivotR");
    m_LocomotionPivotLTransId = Animator.StringToHash("Base Layer.Locomotion -> Base Layer.LocomotionPivotL");
    m_LocomotionPivotRTransId = Animator.StringToHash("Base Layer.Locomotion -> Base Layer.LocomotionPivotR");

}

public void keysToWorldSpace (Transform root, Transform camera, ref float directionOut, ref float speedOut, ref float angleOut, bool isPivoting){

    Vector3 rootDirection = root.forward;

    Vector3 keyDirection = new Vector3 (horizontal, 0, vertical);

    speedOut = keyDirection.sqrMagnitude;

    //get camera rotation
    Vector3 cameraDirection = camera.forward;
    cameraDirection.y = 0.0f;
    Quaternion referentialShift = Quaternion.FromToRotation (Vector3.forward, cameraDirection);

    //convert key input to world space coordinates
    Vector3 moveDirection = referentialShift * keyDirection;
    Vector3 axisSign = Vector3.Cross (moveDirection, rootDirection);

    Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), moveDirection, Color.green);
    Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), axisSign, Color.red);
    Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), rootDirection, Color.magenta);
    Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), keyDirection, Color.blue);

    float angleRootToMove = Vector3.Angle(rootDirection, moveDirection) * (axisSign.y >= 0 ? -1f : 1f);
    if (!isPivoting)
    {
        angleOut = angleRootToMove;
    }

    angleRootToMove /= 180f;

    directionOut = angleRootToMove * directionSpeed;

}

// Update is called once per frame
void Update () {

    if (animator) {

        stateInfo = animator.GetCurrentAnimatorStateInfo(0);
        transInfo = animator.GetAnimatorTransitionInfo(0);

        horizontal = Input.GetAxis("Horizontal");
        vertical = Input.GetAxis("Vertical");

        charAngle = 0f;
        direction = 0f;

        keysToWorldSpace (this.transform, gamecam.transform, ref direction, ref speed, ref charAngle, isInPivot());

        animator.SetFloat ("Speed", speed);
        animator.SetFloat ("Direction", direction, directionDampTime, Time.deltaTime);

        if(speed > LocomotionThreshold){

            if(!isInPivot()){

                Animator.SetFloat("Angle", charAngle);

            }

        }
        if(speed < LocomotionThreshold && Mathf.Abs(horizontal) < 0.05f){

            animator.SetFloat("Direction", 0f);
            animator.SetFloat("Speed", speed, speedDampTime, Time.deltaTime);

        }

        Debug.Log(Speed);
        Debug.Log(charAngle);

    }

}

void FixedUpdate() {

    if (IsInLocomotion () && ((direction >= 0 && horizontal >= 0) || (direction < 0 && horizontal < 0))) {

        Vector3 rotationAmount = Vector3.Lerp(Vector3.zero, new Vector3(0f, rotationDegreePerSecond * (horizontal < 0f ? -1f : 1f), 0f), Mathf.Abs(horizontal));
        Quaternion deltaRotation = Quaternion.Euler(rotationAmount * Time.deltaTime);
        this.transform.rotation = (this.transform.rotation * deltaRotation);

    }

}

public bool isInPivot(){

    return stateInfo.fullPathHash == m_LocomotionPivotLId || 
            stateInfo.fullPathHash == m_LocomotionPivotRId || 
            transInfo.nameHash == m_LocomotionPivotLTransId || 
            transInfo.nameHash == m_LocomotionPivotRTransId;

}

public bool IsInLocomotion(){

    return stateInfo.fullPathHash == m_LocomotionId;

}
使用UnityEngine;
使用系统集合;
公共类特征逻辑:单行为{
[序列化字段]
私人动画师;
[序列化字段]
私人随动摄像机;
[序列化字段]
专用浮动方向速度=1.5f;
[序列化字段]
专用浮动方向阻尼时间=0.25f;
[序列化字段]
专用浮点数旋转度秒=120f;
[序列化字段]
私人浮动时间=0.05f;
私人浮动速度=0.0f;
专用浮动方向=0.0f;
专用浮点字符=0f;
私人浮动水平=0.0f;
私人浮动垂直=0.0f;
私有动画师stateInfo stateInfo;
私有动画传输信息传输信息;
私有int m_移动ID=0;
私有int m_移动PivotLid=0;
私有int m_移动PivotRid=0;
私有int m_移动pivotltransid=0;
private int m_movementpivortransid=0;
公共动画师
{
得到
{
返回这个.animator;
}
}
公共浮动速度
{
得到
{
返回此项。速度;
}
}
公共浮点移动reshold{get{return 0.2f;}}
//用于初始化
无效开始(){

animator=GetComponent)转到Unity 5,但在那里没有遇到相同的问题,我不完全确定导致我出现此问题的原因是什么,但如果你们中有人知道或发现了,请告诉我。

我自己已经发现了这个问题

以下是新代码,以防有人对未来感兴趣:

using UnityEngine;
using System.Collections;

public class characterLogic : MonoBehaviour {

[SerializeField]
private Animator animator;
[SerializeField]
private FollowCamera gamecam;
[SerializeField]
private float directionSpeed = 1.5f;
[SerializeField]
private float directionDampTime = 0.25f;
[SerializeField]
private float rotationDegreePerSecond = 120f;
[SerializeField]
private float speedDampTime = 0.05f;
[SerializeField]
private float fovDampTime = 3f;

private float horizontal = 0.0f;
private float vertical = 0.0f;
private float speed = 0.0f;
private float direction = 0.0f;
private float charAngle = 0f;
private const float SPRINT_SPEED = 2.0f;
private const float SPRINT_FOV = 75.0f;
private const float NORMAL_FOV = 60.0f;
private const float WALK_SPEED = 0.1f;
private AnimatorStateInfo stateInfo;
private AnimatorTransitionInfo transInfo;

private int m_LocomotionId = 0;
private int m_LocomotionPivotLId = 0;
private int m_LocomotionPivotRId = 0;
private int m_LocomotionPivotLTransId = 0;  
private int m_LocomotionPivotRTransId = 0;  

public Animator Animator
{
    get
    {
        return this.animator;
    }
}

public float Speed
{
    get
    {
        return this.speed;
    }
}

public float LocomotionThreshold { get { return 0.2f; } }


// Use this for initialization
void Start () {


    animator = GetComponent<Animator>();

    if(animator.layerCount >= 2)
    {
        animator.SetLayerWeight(1, 1);
    }   

    m_LocomotionId = Animator.StringToHash("Base Layer.Locomotion");
    m_LocomotionPivotLId = Animator.StringToHash("Base Layer.LocomotionPivotL");
    m_LocomotionPivotRId = Animator.StringToHash("Base Layer.LocomotionPivotR");
    m_LocomotionPivotLTransId = Animator.StringToHash("Base Layer.Locomotion -> Base Layer.LocomotionPivotL");
    m_LocomotionPivotRTransId = Animator.StringToHash("Base Layer.Locomotion -> Base Layer.LocomotionPivotR");

}

public void keysToWorldSpace (Transform root, Transform camera, ref float directionOut, ref float speedOut, ref float angleOut, bool isPivoting){

    Vector3 rootDirection = root.forward;

    Vector3 keyDirection = new Vector3 (horizontal, 0, vertical);

    speedOut = keyDirection.sqrMagnitude;

    //get camera rotation
    Vector3 cameraDirection = camera.forward;
    cameraDirection.y = 0.0f;
    Quaternion referentialShift = Quaternion.FromToRotation(Vector3.forward, Vector3.Normalize(cameraDirection));

    //convert key input to world space coordinates
    Vector3 moveDirection = referentialShift * keyDirection;
    Vector3 axisSign = Vector3.Cross (moveDirection, rootDirection);

    Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), moveDirection, Color.green);
    Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), axisSign, Color.red);
    Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), rootDirection, Color.magenta);
    Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), keyDirection, Color.blue);

    float angleRootToMove = Vector3.Angle(rootDirection, moveDirection) * (axisSign.y >= 0 ? -1f : 1f);
    if (!isPivoting)
    {
        angleOut = angleRootToMove;
    }

    angleRootToMove /= 180f;

    directionOut = angleRootToMove * directionSpeed;

}

// Update is called once per frame
void Update () {

    if (animator) {

        stateInfo = animator.GetCurrentAnimatorStateInfo(0);
        transInfo = animator.GetAnimatorTransitionInfo(0);

        horizontal = Input.GetAxis("Horizontal");
        vertical = Input.GetAxis("Vertical");

        charAngle = 0f;
        direction = 0f;
        float charSpeed = 0f;

        keysToWorldSpace (this.transform, gamecam.transform, ref direction, ref charSpeed, ref charAngle, isInPivot());

        if (Input.GetButton("Sprint"))
        {
            speed = Mathf.Lerp(speed, SPRINT_SPEED, Time.deltaTime);
            gamecam.GetComponent<Camera>().fieldOfView = Mathf.Lerp(gamecam.GetComponent<Camera>().fieldOfView, SPRINT_FOV, fovDampTime * Time.deltaTime);
        }
        else
        {
            speed = charSpeed;
            gamecam.GetComponent<Camera>().fieldOfView = Mathf.Lerp(gamecam.GetComponent<Camera>().fieldOfView, NORMAL_FOV, fovDampTime * Time.deltaTime);      
        }

        if (Input.GetButton("Walk"))
        {
            speed = Mathf.Lerp(speed, WALK_SPEED, Time.deltaTime);
        }
        else
        {
            speed = charSpeed;      
        }

        animator.SetFloat("Speed", speed, speedDampTime, Time.deltaTime);
        animator.SetFloat("Direction", direction, directionDampTime, Time.deltaTime);

        if(speed > LocomotionThreshold){

            if(!isInPivot()){

                Animator.SetFloat("Angle", charAngle);

            }

        }
        if(speed < LocomotionThreshold && Mathf.Abs(horizontal) < 0.05f){

            animator.SetFloat("Direction", 0f);
            animator.SetFloat("Speed", speed, speedDampTime, Time.deltaTime);

        }

        Debug.Log(Speed);
        Debug.Log(charAngle);

    }

}

void FixedUpdate() {

    if (IsInLocomotion () && ((direction >= 0 && horizontal >= 0) || (direction < 0 && horizontal < 0))) {

        Vector3 rotationAmount = Vector3.Lerp(Vector3.zero, new Vector3(0f, rotationDegreePerSecond * (horizontal < 0f ? -1f : 1f), 0f), Mathf.Abs(horizontal));
        Quaternion deltaRotation = Quaternion.Euler(rotationAmount * Time.deltaTime);
        this.transform.rotation = (this.transform.rotation * deltaRotation);

    }

}

public bool isInPivot(){

    return stateInfo.fullPathHash == m_LocomotionPivotLId || 
            stateInfo.fullPathHash == m_LocomotionPivotRId || 
            transInfo.nameHash == m_LocomotionPivotLTransId || 
            transInfo.nameHash == m_LocomotionPivotRTransId;

}

public bool IsInLocomotion(){

    return stateInfo.fullPathHash == m_LocomotionId;

}
使用UnityEngine;
使用系统集合;
公共类特征逻辑:单行为{
[序列化字段]
私人动画师;
[序列化字段]
私人随动摄像机;
[序列化字段]
专用浮动方向速度=1.5f;
[序列化字段]
专用浮动方向阻尼时间=0.25f;
[序列化字段]
专用浮点数旋转度秒=120f;
[序列化字段]
私人浮动时间=0.05f;
[序列化字段]
专用浮动fovDampTime=3f;
私人浮动水平=0.0f;
私人浮动垂直=0.0f;
私人浮动速度=0.0f;
专用浮动方向=0.0f;
专用浮点字符=0f;
私人恒浮冲刺速度=2.0f;
私有常量浮点冲刺=75.0f;
私人常数浮动正常视场=60.0f;
私人建筑浮标行走速度=0.1f;
私有动画师stateInfo stateInfo;
私有动画传输信息传输信息;
私有int m_移动ID=0;
私有int m_移动PivotLid=0;
私有int m_移动PivotRid=0;
私有int m_移动pivotltransid=0;
private int m_movementpivortransid=0;
公共动画师
{
得到
{
返回这个.animator;
}
}
公共浮动速度
{
得到
{
返回此项。速度;
}
}
公共浮点移动reshold{get{return 0.2f;}}
//用于初始化
无效开始(){
animator=GetComponent();
如果(animator.layerCount>=2)
{
动画师:设置图层权重(1,1);
}   
m_motionId=Animator.StringToHash(“基本层.移动”);
m_motionPivotLid=Animator.StringToHash(“基本层.motionPivotL”);
m_movementpivotrid=Animator.StringToHash(“基本层.movementpivotr”);
m_movementpivotltransid=Animator.StringToHash(“Base Layer.movement->Base Layer.movementpivotl”);
m_movementpivortransid=Animator.StringToHash(“Base Layer.movement->Base Layer.movementpivotr”);
}
公共空间(变换根、变换摄影机、ref float directionOut、ref float speedOut、ref float angleOut、bool isPivoting){
Vector3 rootDirection=root.forward;
Vector3键方向=新的Vector3(水平、0、垂直);
speedOut=keyDirection.sqrMagnitude;
//让摄像机旋转
Vector3 CamerarDirection=camera.forward;
cameraDirection.y=0.0f;
四元数引用移位=四元数.FromToRotation(Vector3.forward,Vector3.Normalize(CameradDirection));
//将关键点输入转换为世界空间坐标
Vector3 moveDirection=参考移位*键方向;
Vector3 axisSign=Vector3.Cross(移动方向,根方向);
Debug.DrawRay(新矢量3(root.position.x,root.position.y+2f,root.position.z),moveDirection,Color.green);
Debug.DrawRay(新矢量3(root.position.x,root.position.y+2f,root.position.z),axisSign,Color.red);
Debug.DrawRay(新矢量3(root.position.x,root.position.y+2f,root.position.z),rootDirection,Color.品红色);
Debug.DrawRay(新矢量3(root.position.x,root.position.y+2f,root.position.z),keyDirection,Color.blue);
浮动角度roottomove=Vector3.角度(rootDirection,moveDirection)*(axisSign.y>=0?-1f:1f);
如果(!isPivoting)
{
angleOut=angleRootToMove;
}
角roottomove/=180f;
directionOut=angleRootToMove*方向速度;
}
//每帧调用一次更新
无效更新(){
如果(动画师){
stateInfo=animator.GetCurrentAnimatorStateInfo(0);
transInfo=animator.GetAnimatorTransitionInfo(0);
水平=输入.GetAxis(“水平”);
垂直=输入。GetAxis(“垂直”);
charAngle=0f;
方向=0f;
浮动速度=0f;
keystorldspace(this.transform、gamecam.transform、ref-direction、ref-charSpeed、ref-charAngle、isInPivot());
if(Input.GetButton(“Sprint”))
{
速度=Mathf.Lerp(速度