首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >单位接地状态对角色来说是闪烁的。.isGrounded正在使用,但仍在闪烁

单位接地状态对角色来说是闪烁的。.isGrounded正在使用,但仍在闪烁
EN

Stack Overflow用户
提问于 2018-11-25 06:50:44
回答 3查看 2.4K关注 0票数 0

我的角色控制器的固定状态在似乎每一帧都会不断地闪烁。据我所知,它应该检查球员是否通过player.isGrounded停飞,但其他东西正在将其移回。

代码语言:javascript
运行
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerCharacterController: MonoBehaviour {

    static Animator anim;

    public bool walking;

    public GameObject playerModel, Hero;
    //Transforms
    public Transform playerCam, character, centerPoint;

    private Vector3 moveDirection;

    //character controller declaration
    CharacterController player;

    //Mouse Rotation
    private float rotX, rotY;
    //Mouse Y Position
    public float mouseYPosition = 1f; 
    //Mouse Sensitivity
    public float Sensitivity = 10f;
    //Mouse Zoom
    private float zoom;
    public float zoomSpeed = 2;
    //Clamping Zoom
    public float zoomMin = -2f;
    public float zoomMax = -10f;
    public float rotationSpeed = 5f;
    //Move Front Back left & Right
    private float moveFB, moveLR;   
    //Movement Speed
    public float Speed = 2f;
    //Velocity of Gravity
    public float verticalVelocity;
    //Jump Distance
    public float jumpDist = 5f;
    //Multiple Jumps
    int jumpTimes;
    //To use with Dialogue Manager
    public DialogueManager DiagM;

    public AudioClip jumpSound;
    public AudioClip HurtSound;
    public AudioClip PunchSound;

    AudioSource audioSource;

    //knockback

    public float knockBackForce;
    public float knockBackTime;
    private float knockBackCounter;


    // Use this for initialization
    void Start ()   
    {
        //character controller
        player = GameObject.Find("Player").GetComponent<CharacterController> ();

        StartCoroutine(MyCoroutine(character));

        anim = GetComponent<Animator>();

        //mouse zoom
        zoom = -3;  
        centerPoint.transform.position = playerCam.transform.position;
        centerPoint.transform.parent = null;
        audioSource = GetComponent<AudioSource>();
    }

    IEnumerator MyCoroutine (Transform character)
    {
        if (player.isGrounded == true)

        {
        anim.SetBool("isFalling",false);
        //anim.SetBool("isIdling", true);
        yield return new WaitForSeconds(0);
        }

    }
    // Update is called once per frame

    void Update ()
    {        
        //Mouse Zoom Input
        zoom += Input.GetAxis ("Mouse ScrollWheel") * zoomSpeed;

        if (zoom > zoomMin)
            zoom = zoomMin;
        if (zoom < zoomMax)
            zoom = zoomMax;

        //Mouse Camera Input
        playerCam.transform.localPosition = new Vector3 (0, 0, zoom);

        //Mouse Rotation

        rotX += Input.GetAxis ("Mouse X") * Sensitivity;
        rotY -= Input.GetAxis ("Mouse Y") * Sensitivity;      

        //Clamp Camera
        rotY = Mathf.Clamp (rotY, -60f, 60f);
        playerCam.LookAt (centerPoint);
        centerPoint.localRotation = Quaternion.Euler (rotY, rotX, 0);

        //Movement Speed
        if (knockBackCounter <= 0)
        {   
            moveDirection = (transform.forward * Input.GetAxis("Vertical")) + (transform.right * Input.GetAxis("Horizontal"));
            moveDirection = moveDirection * Speed;
            moveDirection.y = verticalVelocity;

            player.Move(moveDirection * Time.deltaTime);



            //Movement Rotation

            centerPoint.position = new Vector3 (character.position.x, character.position.y + mouseYPosition, character.position.z);

            //knockback disable
            //Movement Input

            if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)

            {
                transform.rotation = Quaternion.Euler(0f, centerPoint.rotation.eulerAngles.y, 0f);
                Quaternion turnAngle = Quaternion.LookRotation(new Vector3(moveDirection.x, 0f, moveDirection.z));
                playerModel.transform.rotation = Quaternion.Slerp(playerModel.transform.rotation, turnAngle, Time.deltaTime * rotationSpeed);

                if (player.isGrounded == true)
                {
                    anim.SetBool("isWalking", true);
                    anim.Play("Running");
                }
            }
            else 
            {
                StartCoroutine(MyCoroutine(character));
            }

            if (Input.GetButtonDown("LHand"))
            {
                audioSource.PlayOneShot(PunchSound, 1F);
                anim.Play("RPunch");
            }

            if (player.isGrounded == true)
            {
                jumpTimes = 0;
                //verticalVelocity = -Physics.gravity.y * Time.deltaTime;
                verticalVelocity = 0;
            }
            else
            {
                verticalVelocity += Physics.gravity.y * Time.deltaTime;
                anim.SetBool("isWalking", false);
                anim.SetBool("isFalling", true);
            }


            if (jumpTimes < 1)
            {
                if (Input.GetButtonDown("Jump"))
                {
                    verticalVelocity += jumpDist;
                    anim.Play("Jump");
                    audioSource.PlayOneShot(jumpSound, 1F);
                    jumpTimes += 1;
                }
            }
        }
        else
        {
            knockBackCounter -= Time.deltaTime;
        }
    }

    public void Knockback(Vector3 direction)
    {
        knockBackCounter = knockBackTime;
        anim.Play("Jump");
        audioSource.PlayOneShot(HurtSound, 50F);
        moveDirection = direction * knockBackForce;
        moveDirection.y = knockBackForce;
    }
}

它看起来与verticalVelocity行有关,但到目前为止,我只尝试设置verticalVelocity =0,直到我真正移动了角色。我可以改变什么来停止闪烁?

EN

回答 3

Stack Overflow用户

发布于 2019-07-24 03:57:11

可能已经解决了,但原因是,如果使用的是character Controller,则应始终将重力应用于角色。

当角色与对象碰撞时,它实际上进入了对象内部的一小部分,然后Unity将角色推回远离对象,直到它不再接触对象。在这一点上,你的重力再次开始作用,并重新初始化这个循环。

你需要100%的时间应用重力来创造足够的力量来“平衡”这场与地板的战斗。可以是一个更小的“重力”,比如1。不需要成为你的重力变量。

此外,最重要的是,我想添加一个"Coyote time",并创建我的on IsGrounded()方法,如下所示:

代码语言:javascript
运行
复制
    public bool IsGrounded()
{
    return CoyoteTime < CoyoteTimeMax;
}

public void CoyoteControl()
{
    if (CharController.isGrounded)
    {
        CoyoteTime = 0;
    }
    else
    {
        CoyoteTime += Time.deltaTime;
    }
}

然后我在Update()上调用CoyoteControl(),并且我可以在需要的时候调用IsGrounded()。在检查器上,我通常将CoyoteTimeMax设置为0.1,这样会使下落更加平滑。

票数 2
EN

Stack Overflow用户

发布于 2018-11-26 15:06:39

根据你的评论。您不应该通过检查动画参数来确定您的播放器是否已停飞。最好的方法是使用RayCast()。所以你要做的是:

  1. 创建名为Ground的图层,并将场景中的所有平台添加到该图层。
  2. 创建布尔变量

i.e

代码语言:javascript
运行
复制
bool isGrounded;

  1. 创建一个函数来检查角色是否已接地

类似于:

代码语言:javascript
运行
复制
bool checkGrounded(){

    return Physics.Raycast(transform.position, Vector3.down, 2f, 1 << LayerMask.NameToLayer("Ground")));

} 

在此answer中,您可以阅读有关光线广播中的参数的信息

  1. 最终在更新中检查播放器是否已停飞

类似于:

代码语言:javascript
运行
复制
void Update(){
    isGrounded = checkGrounded();
}
票数 1
EN

Stack Overflow用户

发布于 2022-01-30 22:48:22

我发现,如果您多次检查,isGrounded检查可能会在更新()函数的过程中发生变化。在函数开始时将其赋给一个变量可能会解决闪烁问题。

代码语言:javascript
运行
复制
void Update()
{
    bool isGrounded = characterController.isGrounded;
    ...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53463043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档